Sébastien Arnaud wrote:

<Directory "/mypath/mydir/">
    AddHandler mod_python .py .html
    PythonHandler mod_python.pubre
PythonOption "pubregex" "(?P<controller>[\w]+)?(\.(?P<extension>[\w]+))?(/(?P<action>[^/]+))?(\?$)?"
</Directory>

I know that not all grammars will work with the current version attached (due to some code being still dependent on the conservative url structure /path/file.ext), eventually though, I hope I can get this solved and allow any regex grammar to work.

Anyway, please share your comments and feedback to make sure I am headed in the right direction by keeping in mind that my first goal is to be able to publish using a defined regex url grammar a callable class within a module. I believe that once this first step is accomplished the real design of the web framework can begin.

Is regex essential to what you're trying to accomplish? I do something similar in a minimal handler I've written that simply makes a list of the URL parts:

 resource = req.path_info.strip('/').split('/')

Then I walk the list in order to determine the action that needs to be taken. A very primitive example would be:

if resource[0] == 'time':
    # use first item only, returns formatted local date & time
    # i.e. http://host/path/to/handler/time
    import time
    now = time.strftime('%Y-%m-%d %H:%M:%S')
    req.content_type = "text/plain"
    req.write(now)
elif resource[0] == 'color':
    # use second URL part as a key in a data structure
    # i.e. http://host/path/to/handler/color/Lance
    data = {'Lance': 'blue',
            'Robin': 'idunno',
            'Galahad': 'yellow'}
    req.content_type = "text/plain"
    try:
req.write("%s's favorite color is %s." % (resource[1], data[resource[1]]))
    except KeyError:
        req.write("%s's favorite color is unknown." % (resource[1],))
    except IndexError:
        req.write('Specify a name (/color/Someone).')

Then http://host/handler/time returns:

 2006-09-07 11:17:19

and http://host/handler/color/Lance returns:

 Lance's favorite color is blue.

My motivation was to support friendly dynamic URLs (http://host/handler/foo/bar/baz) in the simplest way possible. Since the action taken is handled in logic (instead of a strict mapping to either functions, modules, or objects), it's extremely flexible. The trick is in determining if an argument should be part of the abs_path or handled as a query (http://host/handler/foo?bar=baz).

Of course, there's nothing stopping you from using the remainder of the list as values for your app:

if resource[0] == 'order':
    # use remaining resources as multiple values for single argument
    # http://host/path/to/handler/order/item/item/item
    if len(resource) > 2:
        # there was a list of items
        order = '%s and %s' % (', '.join(resource[1:-1]), resource[-1])
    elif len(resource) == 2:
        # there was a single item
        order = resource[1]
    else:
        # no items in URL
        order = 'nothing'
    req.content_type = "text/plain"
    req.write('You have ordered %s.' % (order))

Then this URL:

 http://host/handler/order/spam/spam/spam/eggs/spam

would return:

 You have ordered spam, spam, spam, eggs and spam.

This isn't always appropriate, and one needs to be careful (too much rope, as they say). It's normally better to handle arbitrarily long lists of values with query arguments or POST variables.

Anyway, I don't mean to hijack your thread, Sébastien. I'm just wondering if you are trying to accomplish the same thing, or have a specific reason for using regex, which really can slow an application down. You could easily adapt this simpler approach to enforce a stricter mapping of your own convention.




Reply via email to