durusmail: quixote-users: Where in the URL is Component San Diego?
Where in the URL is Component San Diego?
2003-01-30
2003-01-30
2003-01-30
2003-01-30
2003-01-31
2003-01-31
2003-02-05
2003-02-06
Where in the URL is Component San Diego?
Nicola Larosa
2003-01-30
 > Can you give an example of circumstances where the index would be
 > useful?  I can't imagine one on my own.

Sorry for the length.

I am working on an app that has a user authentication part. I need the
following paths:

/config/
returns a page with all the configuration commands

/config/users
returns a page with the list of all the known users

/config/user/add
returns a form with empty fields for a new user

/config/user/[loginName]/modify
returns a form with current values for a known user

/config/user/validate
used as a form action, validates values for a added or modified user

/config/user/[loginName]/delete
deletes a known user

I have a ConfigUI object that iterates over the component, answers directly
in the first two cases, and creates and returns UserForm(Form) objects when
the second level component is "user".

Currently it is all implemented in its _q_getname method, by means of a
case-like switch shaped like this:

if self.nextCompLevel == 2:
      # level 2 URL component: /config/something
      if component not in self.knownURLClasses.keys():
          message = "Unknown level 2 URL component: %s" % component
          raise TraversalError, message
      else:
          # /config/user , store the component
          self.currObjKind = component
          # advance state to next level
          self.nextCompLevel = 3
          # get next component
          return self
elif self.nextCompLevel == 3:
      # level 3 URL component: /config/user/something
      # could be 'add', 'validate', or a login name
      if component == 'add':
          # /config/user/add, create a new form object
          # and lose the old one, if already there
          self.forms[self.currObjKind] = \
              self.knownURLClasses[self.currObjKind](self.app)
          # URL ended, reset state for next call
          self.nextCompLevel = 2
          # call the appropriate object 'add' method
          return self.forms[self.currObjKind].add(request)
      elif component == 'validate':
          # /config/user/validate, need an existing form object
          if not self.forms.get(self.currObjKind):
            message = "Validate without existing %s form, object %s" \
              % (self.currObjKind, self.currObjItem)
            raise TraversalError, message
          # check passed, URL ended, reset state for next call
          self.nextCompLevel = 2
          # call the appropriate object 'validate' method
          return self.forms[self.currObjKind].validate(request)
      else:
          # it's a login name, store it
          self.currObjItem = component
          # advance state to next level
          self.nextCompLevel = 4
          return self
elif self.nextCompLevel == 4:
      # level 4 URL component: /config/user/login/something
      if component in ('delete', 'modify'):
          # create a new form object and lose the
          # old one, if already there
          self.forms[self.currObjKind] = \
              self.knownURLClasses[self.currObjKind](self.app)
          # pass the recorded item to the form object
          self.forms[self.currObjKind].setState(self.currObjItem)
          # URL ended, reset state for next call
          self.nextCompLevel = 2
          # call the appropriate object method
          if component == 'delete':
              return self.forms[self.currObjKind].delete(request)
          else:
              return self.forms[self.currObjKind].modify(request)
      else:
          message = "Unknown form action, component: %s" % component
          raise TraversalError, message
else:
      message = "Unknown next component level: %s" % self.nextCompLevel
      raise TraversalError, message

The __init__ contains this:

      self.nextCompLevel = 2
      self.currObjKind = ''
      self.currObjItem = ''
      self.forms = {}

Having the index passed to the _q_getname would allow me not to keep track
of what the next component level should be, and choose a path of action
based on what it really is.

P.S.: of course most "else"s are superfluous, but I keep them for clarity.
And obviously the "validate" method refuses "add" and "validate" as login
names. Not the cleanest way, I know. :^) But the alternative is to have
something like

/config/user/dummy/add

or, worse, query strings. :^)


--
"Python is the Beatles of programming languages."
   Aaron K. Johnson on comp.lang.python

Nicola Larosa - nico@tekNico.net



reply