Return-Path: Delivered-To: apmail-httpd-python-dev-archive@www.apache.org Received: (qmail 88921 invoked from network); 7 Sep 2006 19:14:19 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 7 Sep 2006 19:14:19 -0000 Received: (qmail 37391 invoked by uid 500); 7 Sep 2006 19:14:19 -0000 Delivered-To: apmail-httpd-python-dev-archive@httpd.apache.org Received: (qmail 37364 invoked by uid 500); 7 Sep 2006 19:14:19 -0000 Mailing-List: contact python-dev-help@httpd.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Delivered-To: mailing list python-dev@httpd.apache.org Received: (qmail 37353 invoked by uid 99); 7 Sep 2006 19:14:19 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Sep 2006 12:14:19 -0700 X-ASF-Spam-Status: No, hits=0.5 required=10.0 tests=DNS_FROM_RFC_ABUSE,HTML_MESSAGE,SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (asf.osuosl.org: domain of nicolas.lehuen@gmail.com designates 64.233.162.197 as permitted sender) Received: from [64.233.162.197] (HELO nz-out-0102.google.com) (64.233.162.197) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 07 Sep 2006 12:14:18 -0700 Received: by nz-out-0102.google.com with SMTP id x7so161736nzc for ; Thu, 07 Sep 2006 12:13:57 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:sender:to:subject:cc:in-reply-to:mime-version:content-type:references:x-google-sender-auth; b=Ln8gx5yIBiFwV6J/R07sckYG9vGBgAt3TIYpqDUo5ZMgn2r6J9g3KOrQx0QpMAuNWT506ZCDfTauc0rgbFhJb/0msZKxlcM1tz6UaRnidvzkc+WiCRMScI8qDwLD9XzK0CjlJ5XwdFZ8HcJ0MdnT+5mTeKnKk5lWKFMzBcWCkWk= Received: by 10.64.193.9 with SMTP id q9mr737315qbf; Thu, 07 Sep 2006 12:13:56 -0700 (PDT) Received: by 10.65.155.11 with HTTP; Thu, 7 Sep 2006 12:13:56 -0700 (PDT) Message-ID: Date: Thu, 7 Sep 2006 21:13:56 +0200 From: "Nicolas Lehuen" Sender: nicolas.lehuen@gmail.com To: "Jorey Bump" Subject: Re: Regex based publisher proposal Cc: "=?ISO-8859-1?Q?S=E9bastien_Arnaud?=" , python-dev@httpd.apache.org In-Reply-To: MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_Part_133762_30894583.1157656436651" References: <586C10B1-16E2-4F08-A017-D2199E9CCCEC@emedialibrary.org> <4500389A.1090409@joreybump.com> X-Google-Sender-Auth: b7f6f075908ea4d9 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N ------=_Part_133762_30894583.1157656436651 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Note that Routes can be integrated to mod_python, and provides a very usefu= l feature (that can be find in Rails as well) : URL generation, which is the inverse of dispatching. Given parameter names, the URL generator build a full URL that can be inserted into an HTML page, for example. 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 : > > What S=E9bastien 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 buid= l > hierarchies of objects, have callable object anywhere in the hierarchy, > etc.). > > Also, the publisher supports skipping the extension part of the module, s= o > you CAN have /controller/action URIs that already behave quite like what > S=E9bastien suggests. > > Regards, > Nicolas > > 2006/9/7, Jorey Bump : > > > S=E9bastien Arnaud wrote: > > > > > > > > AddHandler mod_python .py .html > > > PythonHandler mod_python.pubre > > > PythonOption "pubregex" > > > > > "(?P[\w]+)?(\.(?P[\w]+))?(/(?P[^/]+))?(\= ?$)?" > > > > > > > > > > > > > > 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 =3D 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] =3D=3D 'time': > > # use first item only, returns formatted local date & time > > # i.e. http://host/path/to/handler/time > > import time > > now =3D time.strftime('%Y-%m-%d %H:%M:%S') > > req.content_type =3D "text/plain" > > req.write(now) > > elif resource[0] =3D=3D 'color': > > # use second URL part as a key in a data structure > > # i.e. http://host/path/to/handler/color/Lance > > data =3D {'Lance': 'blue', > > 'Robin': 'idunno', > > 'Galahad': 'yellow'} > > req.content_type =3D "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 o= r > > > > handled as a query (http://host/handler/foo?bar=3Dbaz). > > > > Of course, there's nothing stopping you from using the remainder of the > > list as values for your app: > > > > if resource[0] =3D=3D '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 =3D '%s and %s' % (', '.join(resource[1:-1]), resource[-= 1]) > > elif len(resource) =3D=3D 2: > > # there was a single item > > order =3D resource[1] > > else: > > # no items in URL > > order =3D 'nothing' > > req.content_type =3D "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=E9bastien. 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 stricte= r > > mapping of your own convention. > > > > > > > > > > > ------=_Part_133762_30894583.1157656436651 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Note that Routes can be integrated to mod_python, and provides a very usefu= l feature (that can be find in Rails as well) : URL generation, which is th= e inverse of dispatching. Given parameter names, the URL generator build a = full URL that can be inserted into an HTML page, for example.

I'm dreaming almost daily of a similar feature for the publisher (t= he best would simply to have a modpython.publisher.generate_url(req,any_cal= lable) method that would automagically build the full or relative url to th= e callable given in parameter (given a few requirements on the callable) an= d based on the current request (you remember that discussion we had about k= nowing what was the full URL that was used to reach any given handler ? tha= t was the idea behind my question).

Regards,
Nicolas

2006/9/= 7, Nicolas Lehuen <nicolas@lehuen.= com>:
http://routes.groovie.org/). This tends to prove that some people find = it useful.

The proposed implementation, however, is another story. There are t= he 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 mod= ule, so you CAN have /controller/action URIs that already behave quite like= what S=E9bastien suggests.

Regards,
Nicolas

2006/9/7, Jorey Bump <list@joreybu= mp.com>:
S=E9bastien Arnaud wrote:

> <Directory "/mypath/mydir/&qu= ot;>
>     AddHandler mod_python .py .html
= >     PythonHandler mod_python.pubre
> &n= bsp;   PythonOption "pubregex"
> "(?P<con= troller>[\w]+)?(\.(?P<extension>[\w]+))?(/(?P<action>[^/]+))= ?(\?$)?"
>
> </Directory>
>
> I know that not all gra= mmars 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 t= he
> real design of the web framework can begin.

Is regex esse= ntial to what you're trying to accomplish? I do something
similar in a minimal handler I've written that simply makes a list ofthe URL parts:

  resource =3D req.path_info.strip('/').s= plit('/')

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] =3D=3D = 'time':
     # use first item only, returns formatte= d local date & time
     # i.e. http://host/path/to/handler/time
     import time
     no= w =3D time.strftime('%Y-%m-%d %H:%M:%S')
     req.co= ntent_type =3D "text/plain"
     req.write= (now)
elif resource[0] =3D=3D 'color':
     # use= second URL part as a key in a data structure
     # i.e. http://host/path/to/handler/color/Lance
  &nb= sp;  data =3D {'Lance': 'blue',
      = ;       'Robin': 'idunno',
            = ; 'Galahad': 'yellow'}
    =20 req.content_type =3D "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." % (reso= urce[1],))
     except IndexError:
    =      req.write('Specify a name (/color/Someone).')
<= br>Then http://host/handler/time returns:

  2006-09-07 11:17:19

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

  Lance's fav= orite color is blue.

My motivation was to support friendly dynamic U= RLs
( 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 obj= ects), it's extremely flexible. The
trick is in determining if an argume= nt should be part of the abs_path or
handled as a query (http:= //host/handler/foo?bar=3Dbaz).

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

if resource[0] =3D=3D '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
  &= nbsp;      order =3D '%s and %s' % (', '.join(reso= urce[1:-1]), resource[-1])
     elif len(resource) = =3D=3D 2:
         # there was a= single item
         order =3D resource[1]
&= nbsp;    else:
       =   # no items in URL
        = ; order =3D 'nothing'
     req.content_type =3D &quo= t;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.

Th= is 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 do= n't mean to hijack your thread, S=E9bastien. I'm just
wondering if you a= re trying to accomplish the same thing, or have a
specific reason for using regex, which really can slow an applicationdown. You could easily adapt this simpler approach to enforce a stricter<= br>mapping of your own convention.






------=_Part_133762_30894583.1157656436651--