Entries For: May 2007
2007-05-28
Some thoughts about the purpose of this blog
I've been thinking lately at the purpose of this blog, what it wants to be, what is really a blog and what I should write here. The number of posts have gone down in the last half of year, partly due to increased work load and partly due to some restructuring that I have done.
In general, I'm unhappy about posting small tips and bits of information on the blog, that's why I have created a Tips & Tutorials section on this site. I have copied or moved a lot of the content from the blog to this section and I'm also adding new stuff. I'll write new entries in the blog if there's anything worth noticing that I add there. At the moment, my "masterpiece" is an index of the packages available on svn.zope.org, done as an exercise in learning about the available extensions but also to provide a needed resource.
I'm also planning on writing a complete series of Zope 3 beginner to advanced tutorials, for which I already have the code and module outlines and only need to put them together.
2007-05-25
Running Python based software in the GPU?
2007-05-24
Using lovely.tag in an edit form (or advanced usage for zope.formlib's EditForm)
lovely.tag is a nice package that has almost all the functionality one can desire from a tagging engine. Recently I needed to integrate it with some of my content types (but not exactly as a tagging widget, but as a global registry for a global vocabulary), so I've created a couple of new widgets (an AJAX based multi-autocomplete one, based on z3c.widget.autocomplete and an add/remove widget, based on Plone's 3rd party AddRemoveWidget). I'll describe here the technique used to integrate the tagging editing in an edit form by using adapters (although this technique is described also in the form.txt from zope.formlib)
The formlib EditForm class creates a dictionary of adapters that are used for each interface to look up the fields (as attributes to the adapter objects). This translates into the following code (IActivity is a content type item):
class IActivity(Interface):
title = TextLine(title=u"Title")
class IItemWithTags(Interface):
tags = List(title=u"Tags", value_type=TextLine(title="Tag"))
class Activity(Persistent):
implements(IActivity)
title = u""
class ActivityEditForm(EditForm):
form_fields = form.Fields(IActivity) + form.Fields(IItemWithTags)
form_fields['tags'].custom_widget = MultiAutoCompleteWidget #custom built widget
Because the IItemWithTags interface is not directly offered by IActivity, there needs to be an adapter that knows how to deal with an Activity in relation with tags.
class ActivityTagsEditor(object):
adapts(IActivityItem)
implements(IActivityTags)
uid = None #the principal id. It is set externally
def __init__(self, context):
self.context = context
intids = getUtility(IIntIds)
self.tag_engine = getUtility(ITaggingEngine)
self.oid = intids.getId(self.context) #the object id
def _setTags(self, value):
self.tag_engine.update(self.oid, self.uid, value)
def _getTags(self):
return self.tag_engine.getTags(items=[self.oid])
tags = property(_getTags, _setTags)
Because of the way the tagging engine works, the adapter needs to know a principal id for whom to set those tags. So we need to overwrite the setUpWidgets method of the form class to set this id on the adapter object (see the setUpEditWidget code to see how the self.adapters registry is filled in).
def setUpWidgets(self, ignore_request=False):
self.adapters = {}
self.widgets = setUpEditWidgets(
self.form_fields, self.prefix, self.context, self.request,
adapters=self.adapters, ignore_request=ignore_request
)
self.adapters[IActivityTags].uid = self.request.principal.id
Another way to set up the adapter (if you don't want to mess with setUpWidgets) is something like this in the submit handler, right before the applyChanges call:
self.adapters = {IItemsWithTags:getAdapter(self.context, IActivityWithTags)}
self.adapters[IItemsWithTags].uid = self.request.principal.id
form.applyChanges(self.context, self.form_fields, data, adapters=self.adapters)
Reading zope.formlib.form.applyChanges is very educational in order to understand how formlib applies changes to objects and how it builds the self.adapters mapping.
And finally, the adapter is simply registered with:
<zope:adapter factory=".adapters.ActivitityTagsEditor" />
2007-05-08
Software is lame
I may sound like a fanboy or something, but I'm starting to think that it's impossible to have a perfect piece of software, especially with larger systems. Two things that happened to me lately that made me think this:
- How lame is that Windows doesn't automount USB sticks when they're present at boot time? Why would I have to remove+reinsert the stick just so Windows will see the bloody thing? My Kubuntu, of course, handles perfectly everything in this department (at least in my case).
- How lame is that Prototype handles in a really stupid way forms that have multiple submit buttons and are submitted through Ajax? Not even Form.request() will do the proper thing, which is to only leave one of the submit inputs in the stream, the one that has been clicked on. The problem is with zope.formlib, which gets the action and the validation from the submit button that was pressed. More then one submit input in the request and things become uncontrollable.
To fix this I have added the following onsubmit handler to my Javascript code:
my_form.onsubmit = function(event){
button = document.activeElement || event.explicitOriginalTarget; // IE, Mozilla, Opera
this.getInputs('submit').each(function(el){
if (el.name != button.name) {
el.disable();
}
}
}This disables all the submit input controls before serializing the form and doing an ajax request with Form.request(), as disabled inputs are ignored by serialize().
UPDATE: I am told that Prototype 1.6 will support multiple submit buttons.
2007-05-03
Brettspielwelt - the free, online boardgame portal
I live in Europe, I'm a geek, so I must also be a boardgame freak. I love games, and especially German style boardgames, with their intricate rules. Unfortunately, there's not much time to play, and not a lot of people that I can play with. Following a link on boardgamesgeek.com I've stumbled on this website, an online portal of boardgames that you can play, something similar to IGS (the Internet Go Server), but that implements loads of boardgames to be played in multiplayer style. The people are friendly and are willing to teach you to play (even in English). The client defaults to the German language, but this can be easily changed by changing the 'Nation = de' line to 'Nation = en' in the props file from the client download folder.
Being a Java application, it goes a long way to adding a few more entertainment choices to the ones available for the Linux platform, in terms of games.
UPDATE: There's a ton more of sites with online boardgames at the boargamegeek wiki
Some of these sites:
http://www.flexgames.com/ (2 games)
http://www.yucata.de/Default.aspx (several, growing)
games.asobrain.com (few, but has Settlers and Carcassonne)
http://www.spielbyweb.com/ (forum based)
http://yourturnmyturn.com/ (many, most classic)
http://hilinski.net/games/online/ (Taj Mahal and Tycoon)