Personal tools
You are here: Home Documentation Tutorials Grok Poller Tutorial Implementing the Name Chooser

Implementing the Name Chooser

We now have a simple name chooser adapter, but it doesn't really do anything useful, and it doesn't fix the problems we had with the URL's.
This tutorial shows how to implement a simple polling application using Grok.
Page 11 of 14.

So scratch the MockNameChooser code completely and let's rewrite it by basing it on the default name chooser implementation (in app.py):

from zope.app.container.contained import NameChooser
from zope.app.container.interfaces import INameChooser

class PollerNameChooser(grok.Adapter, NameChooser):
    grok.context(Poller)
    grok.provides(INameChooser)

    def chooseName(self, name, obj):
        # At first choose a name by using Zopes default NameChooser
        name = super(PollerNameChooser, self).chooseName(name, obj)

        # Lower case the result and replace spaces with underscores
        name = name.replace(u' ', u'_').lower()

        # Check the name for errors just to be careful
        self.checkName(name, obj)
        return name

Zope's name chooser does a couple of things for the names:

  • Checks for duplicates and adds a counter if found
  • Converts slashes to dashes to work with URLs
  • Converts to unicode
  • Strips '+' and '@' characters from the beginning, as those are special to Zope

to this behaviour, we added lower casing and space replacing to make the URLs a bit more neat. You could also register this adapter for all containers by defining the context to grok.Container class.

Now to use it in our add form, replace handle_add method with the following code:

@grok.action('Add poll')
def handle_add(self, **data):
    poll = Poll()
    self.applyData(poll, **data)
    name = INameChooser(self.context).chooseName(poll.question, poll)
    self.context[name] = poll
    return self.redirect(self.url(self.context))

to adhere to the DRY pattern, we should still modify this code a bit by extracting the name chooser pattern as a method on the container, which is the first time we touch the template container. Add the following method to the Poller class:

def add_poll(self, poll):
    name = INameChooser(self).chooseName(poll.question, poll)
    self[name] = poll
    return name

now we can use this method to add polls to this container without thinking about the naming, all that is left is to update handle_add() method to use this new method for adding the new polls to the container.