I'm dreaming almost daily of a similar feature for the publisher (the best would simply to have a modpython.publisher.generate_url(req,any_callable) method that would automagically build the full or relative url to the callable given in parameter (given a few requirements on the callable) and based on the current request (you remember that discussion we had about knowing what was the full URL that was used to reach any given handler ? that was the idea behind my question).
Regards,
Nicolas
2006/9/7, Nicolas Lehuen <[EMAIL PROTECTED]>:
What Sébastien proposes is the kind of dispatching mechanism used in Django, and (without regular expressions) in Rails and Routes ( http://routes.groovie.org/). This tends to prove that some people find it useful.
The proposed implementation, however, is another story. There are the problems that Graham noticed, plus the fact that the current publishing system is richer than the simple controller + action couple (you can buidl hierarchies of objects, have callable object anywhere in the hierarchy, etc.).
Also, the publisher supports skipping the extension part of the module, so you CAN have /controller/action URIs that already behave quite like what Sébastien suggests.
Regards,
Nicolas2006/9/7, Jorey Bump <[EMAIL PROTECTED]>: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 = "" '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.