Quantcast

MJS_Controller_PathRouter - An enhanced RewriteRouter branch

classic Classic list List threaded Threaded
34 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Michael Sheakoski
Hello all,

I just wanted to spread the word about something I've been working on
and see what your opinions are on turning this into a proposal and
possibly getting included into the framework.  A couple weeks ago I sent
out an email to the list about a "Ruby on Rails" patch for the
RewriteRouter.  I received a lot of great feedback from members of the
list and was inspired to develop the idea further.  I tried to get some
of the work I did on this merged into the RewriteRouter but the author,
Martel, preferred to keep his existing code as a base to make changes
rather than accept a major rewrite of the Zend_Controller_Router_Route
class.  Because of this I decided to branch the RewriteRouter and
introduce some new improvements that Zend Framework users may find
extremely useful.

http://framework.zend.com/wiki/display/ZFUSER/MJS_Controller_PathRouter+-+An+enhanced+RewriteRouter

MJS_Controller_PathRouter improvements over Zend_Controller_RewriteRouter:
1. Cross platform.  Works on apache/IIS, with or without
mod_rewrite/ISAPI_Rewrite, PHP as cgi or SAPI
2. BasePath (RewriteBase) is set properly depending on whether or not
you are using a rewrite module
3. Does not force you to use the default routes hard coded into the class
4. more accurately parses the incoming request to give more reliable URL
matching

MJS_Controller_Router_PathRoute improvements over
Zend_Controller_Router_Route:
1. Matching engine is pure regex.  This allows you to have the same
fine-grained control over parsing your routes that you have in mod_rewrite
2. Support for controllers in subfolders
3. :variables can be defined anywhere and in any combination, not just
between /'s.
4. :variables can be next to eachother
5. Any number of wildcards can be defined in your route and can capture
entire strings of parameters.  You are not limited to only a single
wildcard at the end of the route capturing parameters in a
/p1/value1/p2/value2 format like Zend_Controller_Router_Route
6. The ability to override variables after they are matched.  This
allows you to insert text before or after values pulled from the URL.  
This feature is used to support controllers in subfolders by prefixing
the :controller with the subfolder after it is matched.
7. Less CPU/RAM usage.  No processing occurs until it is needed.
8. Syntax and behavior is 100% backwards compatible with
Zend_Controller_Router_Route

On average, performance is the same or better than RewriteRouter despite
all of these added features.

My design philosophy behind these classes was to be as easy to use as
possible for beginners and as powerful as needed for the experts.  Just
to put in perspective how easy it is to use and how compatible it is,
you can take your existing code written for Router / RewriteRouter and
change the class names to PathRouter / PathRoute and it will work out of
the box.

If you are in need of more compatible and industrial strength routing,
please give PathRouter a try.  For more information check out
http://framework.zend.com/wiki/display/ZFUSER/MJS_Controller_PathRouter+-+An+enhanced+RewriteRouter 
which goes in depth about the classes, provides documentation, usage,
examples, and benchmarks.

Thanks for your time,
Michael Sheakoski
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Nick Lo
Hi Michael,

> 8. Syntax and behavior is 100% backwards compatible with  
> Zend_Controller_Router_Route

Is there a need at this stage to be ensuring backwards compatibility,  
surely it should be about getting to the best solution? I understand  
why you have done it but it somehow gives me a foreboding sense of  
internal politics creeping in.

My personal considerations for the controller/router:

1. Is it flexible enough to handle anything from the simplest url to  
more complex ones?

e.g. By simplest I refer to the way Wordpress can manage urls like:

www.myblog.com/my-post-that-is-static

I may well be wrong but I cannot see a way to map the above url via a  
general controller to a row in a database, which means that I could  
not do a Wordpress to ZF conversion without resorting to using  
mod_rewrite (or creating multiple controller files). This always  
seemed to be a strange weakness in ZF so far considering how  
ubiquitous Wordpress is.

2. Can routes be stored together with and in a similar format to the  
other configuration info?

Especially if development is being done in a team environment.

  This comment, which I agree with, was left on my article:

"My reservation with your method of putting routes into the config  
file is that then you have to include the  
Zend_Controller_RewriteRouter file in your config file. I prefer to  
not to include code in my config file.
Even aside from my personal preferences, this method can’t be used  
with XML or INI config files."

http://www.ingredients.com.au/nick/2006/07/18/rewriterouter-and- 
zend_config-play-together/#comment-142

3. Does it cross the threshold by which time could be as well spent  
just using mod_rewrite.

This includes the time spent learning the ZF way versus mod_rewrite  
(which would have use across several projects rather than just ZF  
based ones).

Anyway, I need to give these proposed routers a test run.

Nick







Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Martel
Nick Lo wrote:

>> 8. Syntax and behavior is 100% backwards compatible with  
>> Zend_Controller_Router_Route
> Is there a need at this stage to be ensuring backwards compatibility,  
> surely it should be about getting to the best solution?

 From the first glance at the proposed router I don't see how it is backwards
compatible. I doesn't bind var => value parameters from URL - it leaves them in
unparsed format according to the documentation (Cleveland/OH/44315). Yet it
should be simple to do if you want it added.

BUT, I agree with Nick. Why copy existing Router solution and add couple of
functionalities you don't have to use most of the time? Maybe try to come up
with something that approaches the problem at a completely different angle. So
it will be useful for these people that find the current solution lacking.

> e.g. By simplest I refer to the way Wordpress can manage urls like:
> www.myblog.com/my-post-that-is-static
>
> I may well be wrong but I cannot see a way to map the above url via a  
> general controller to a row in a database, which means that I could  
> not do a Wordpress to ZF conversion without resorting to using  
> mod_rewrite (or creating multiple controller files). This always  
> seemed to be a strange weakness in ZF so far considering how  
> ubiquitous Wordpress is.

Well, I don't see any problems here. Just define the route as ':name' and look
for params['name'] in the database, Nick. Or am I missing something obvious?

> 2. Can routes be stored together with and in a similar format to the  
> other configuration info?
> Especially if development is being done in a team environment.

You have to store the names, route maps, defaults and requirements for every
single route. I'm willing to add the possibility to use a Zend_Config object
with the RewriteRouter but I don't see how this can be conveniently stored in
an ini file. I'm generaly biased in the direction of XML as I have a lot of
experience working with those files.

Maybe someone would be kind enough to contribute the neutral config structure
for php, ini and XML config files? I mean to be possible to parse it with the
same code in the hypothetic RewriteRouter method.

> Nick

--
Michael Minicki aka Martel Valgoerad | [hidden email] | http://aie.pl/martel.asc
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
"Finance is the art of passing money from hand to hand until it finally
disappears." -- Robert W. Sarnoff
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Nick Lo
>>> 8. Syntax and behavior is 100% backwards compatible with  
>>> Zend_Controller_Router_Route
>> Is there a need at this stage to be ensuring backwards  
>> compatibility,  surely it should be about getting to the best  
>> solution?
>
> BUT, I agree with Nick. Why copy existing Router solution and add  
> couple of functionalities you don't have to use most of the time?  
> Maybe try to come up with something that approaches the problem at  
> a completely different angle. So it will be useful for these people  
> that find the current solution lacking.

Well if this provides additional functionality then there should be a  
merge of solutions rather than a branch. I do however have the sense  
that Michael has done it this way in order to sidestep directly  
treading on your toes Martel
which is what I meant by politics. At this point I think I'd expect  
some of the Zend hierarchy to step in and cast some judgement.

>> e.g. By simplest I refer to the way Wordpress can manage urls like:
>> www.myblog.com/my-post-that-is-static
>> I may well be wrong but I cannot see a way to map the above url  
>> via a  general controller to a row in a database, which means that  
>> I could  not do a Wordpress to ZF conversion without resorting to  
>> using  mod_rewrite (or creating multiple controller files). This  
>> always  seemed to be a strange weakness in ZF so far considering  
>> how  ubiquitous Wordpress is.
>
> Well, I don't see any problems here. Just define the route as  
> ':name' and look for params['name'] in the database, Nick. Or am I  
> missing something obvious?

No it may well be me missing the obvious ...it was a while ago that I  
even though about how to do this and likely before RewriteRouter was  
released. Presumably the only option is to have it default to  
indexAction in indexController? However by then you are already in  
the controller and would presumably have to redirect or have some  
control structure to deal with it within indexAction. I think I'd  
like to see it routed to say a StaticPostController or such like. I  
don't actually have need for it right now and I suspect it would have  
some issues with scale/naming conflicts but I did want to use it as  
an example nonetheless.

More detail for non Wordpress users: In Wordpress you can add a  
"Page" which is really just a post like any other but has a value  
"static". So as an example: a post is made via admin called "About  
Us" and is set as a "Page" ...it can then be automatically found via  
yourblog.com/about-us/. Clearly Wordpress must be querying its  
database whenever a unrecognised/non-system url is called but either  
way it is a good example of a simple url mapping in use across a lot  
of sites.

>
>> 2. Can routes be stored together with and in a similar format to  
>> the  other configuration info?
>> Especially if development is being done in a team environment.
>
> You have to store the names, route maps, defaults and requirements  
> for every single route. I'm willing to add the possibility to use a  
> Zend_Config object with the RewriteRouter but I don't see how this  
> can be conveniently stored in an ini file. I'm generaly biased in  
> the direction of XML as I have a lot of experience working with  
> those files.
>
> Maybe someone would be kind enough to contribute the neutral config  
> structure for php, ini and XML config files? I mean to be possible  
> to parse it with the same code in the hypothetic RewriteRouter method.

Well from looking at the various routes implementations I agree that  
ini may well be too optimistic.

Nick



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Simon Mundy
> No it may well be me missing the obvious ...it was a while ago that  
> I even though about how to do this and likely before RewriteRouter  
> was released. Presumably the only option is to have it default to  
> indexAction in indexController? However by then you are already in  
> the controller and would presumably have to redirect or have some  
> control structure to deal with it within indexAction. I think I'd  
> like to see it routed to say a StaticPostController or such like. I  
> don't actually have need for it right now and I suspect it would  
> have some issues with scale/naming conflicts but I did want to use  
> it as an example nonetheless.
>
> More detail for non Wordpress users: In Wordpress you can add a  
> "Page" which is really just a post like any other but has a value  
> "static". So as an example: a post is made via admin called "About  
> Us" and is set as a "Page" ...it can then be automatically found  
> via yourblog.com/about-us/. Clearly Wordpress must be querying its  
> database whenever a unrecognised/non-system url is called but  
> either way it is a good example of a simple url mapping in use  
> across a lot of sites.

Hi Nick

You're not limited to using your IndexController:-

$router->addRoute('wordpress', ':article', array('article' =>  
'default', 'controller' => 'page', 'action' => 'view'));

This will map to:

class PageController
{
     function viewAction()
     {
         $article = $this->_getParam('article'); // defaults to  
'default';
         ...your code...
     }
}

--

Simon Mundy | Director | PEPTOLAB

""" " "" """""" "" "" """"""" " "" """"" " """"" "  """""" "" "
202/258 Flinders Lane | Melbourne | Victoria | Australia | 3000
Voice +61 (0) 3 9654 4324 | Mobile 0438 046 061 | Fax +61 (0) 3 9654  
4124
http://www.peptolab.com


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Simon Mundy
In reply to this post by Martel
Hi Martel

>> 2. Can routes be stored together with and in a similar format to  
>> the  other configuration info?
>> Especially if development is being done in a team environment.
>
> You have to store the names, route maps, defaults and requirements  
> for every single route. I'm willing to add the possibility to use a  
> Zend_Config object with the RewriteRouter but I don't see how this  
> can be conveniently stored in an ini file. I'm generaly biased in  
> the direction of XML as I have a lot of experience working with  
> those files.
>
> Maybe someone would be kind enough to contribute the neutral config  
> structure for php, ini and XML config files? I mean to be possible  
> to parse it with the same code in the hypothetic RewriteRouter method.

Here's an idea for that:-

====================================

Config file (as .ini)

route.archive.route = news/:year/:month
route.archive.defaults.year = 2006
route.archive.defaults.month = 1
route.archive.reqs.year = \d+
route.archive.reqs.month = \d+

or as .xml

<route>
     <archive>
         <route>news/:year</route>
         <defaults>
             <year>2006</year>
             <month>1</month >
         </defaults>
         <reqs>
             <year>\d+</year>
             <month>\d+</month>
         </reqs>
     </archive>
</route>

====================================

A new method for Zend_Controller_RewriteRouter:-

     public function addConfig(Zend_Config $config, $section) {
         if (is_null($config->{$section})) {
          throw new exception("no router configuration in section  
'{$section}'");
         }
         foreach ($config->{$section} as $name => $info) {
             $this->addRoute($name, new Zend_Controller_Router_Route
($info->route,
                                                                     
$info->defaults->asArray(),
                                                                     
$info->reqs->asArray()));
         }
     }

====================================

And then your bootstrap file would simply contain:-

$config = new Zend_Config(new Zend_Config_Ini('/my/path/config.ini',  
'development'));
$router = new Zend_Controller_RewriteRouter();
$router->addConfig($config, 'route');

====================================

Even if this doesn't qualify as a feature request for RewriteRouter  
(one could argue it is not an essential method), it at least serves  
to show how flexible the existing components are! :)

Cheers

--

Simon Mundy | Director | PEPTOLAB

""" " "" """""" "" "" """"""" " "" """"" " """"" "  """""" "" "
202/258 Flinders Lane | Melbourne | Victoria | Australia | 3000
Voice +61 (0) 3 9654 4324 | Mobile 0438 046 061 | Fax +61 (0) 3 9654  
4124
http://www.peptolab.com


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Michael Sheakoski
In reply to this post by Nick Lo
Nick Lo wrote:
> Hi Michael,
>
>> 8. Syntax and behavior is 100% backwards compatible with
>> Zend_Controller_Router_Route
>
> Is there a need at this stage to be ensuring backwards compatibility,
> surely it should be about getting to the best solution? I understand
> why you have done it but it somehow gives me a foreboding sense of
> internal politics creeping in.

Well, originally lack of backwards compatibility was one of the reasons
my patches were not considered.  It wasn't too hard to do and by being
compatible it means that all of the good ideas Martel thought of are
included.

> My personal considerations for the controller/router:
>
> 1. Is it flexible enough to handle anything from the simplest url to
> more complex ones?
>
> e.g. By simplest I refer to the way Wordpress can manage urls like:
>
> www.myblog.com/my-post-that-is-static
>
> I may well be wrong but I cannot see a way to map the above url via a
> general controller to a row in a database, which means that I could
> not do a Wordpress to ZF conversion without resorting to using
> mod_rewrite (or creating multiple controller files). This always
> seemed to be a strange weakness in ZF so far considering how
> ubiquitous Wordpress is.

YES! This was my whole point in creating it.  You can handle URLs from
the simplest strings to the most complex regular expressions, just like
mod_rewrite for apache.  Your above example would be:
$router->addRouter('wordpress', new
MJS_Controller_Router_PathRoute(':post', array('controller' => 'posts',
'action' => 'view')));

> 2. Can routes be stored together with and in a similar format to the
> other configuration info?

This could easily be added to PathRouter / RewriteRouter.  It will
definitely load slower than defining your routes directly in php code
though.  I even experimented with storing cached versions of the routes
with all arrays and regular expressions generated and it was slower due
to the larger file size than just processing them on the fly.

> 3. Does it cross the threshold by which time could be as well spent
> just using mod_rewrite.
>
> This includes the time spent learning the ZF way versus mod_rewrite
> (which would have use across several projects rather than just ZF
> based ones).
>
> Anyway, I need to give these proposed routers a test run.
>
> Nick

The reason someone would use PathRouter / RewriteRouter is to have a
solution that works with or without mod_rewrite and on any web server.  
This would ensure that their application just works out of the box.  For
someone who wants the most speed possible they would most likely make
their own specialized routing method specific to their software and
hardware setup.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Michael Sheakoski
In reply to this post by Martel
Martel Valgoerad wrote:
> From the first glance at the proposed router I don't see how it is
> backwards compatible. I doesn't bind var => value parameters from URL
> - it leaves them in unparsed format according to the documentation
> (Cleveland/OH/44315). Yet it should be simple to do if you want it added.
You are correct, that particular route captures the parameters as a
string to be parsed by the business logic.  Not every set of params
SHOULD be a var/value combination.  If you put a /* at the end of the
route it would indeed capture everything at the end in a var/value
combination though, just like the current RewriteRouter.

> BUT, I agree with Nick. Why copy existing Router solution and add
> couple of functionalities you don't have to use most of the time?
> Maybe try to come up with something that approaches the problem at a
> completely different angle. So it will be useful for these people that
> find the current solution lacking.
You make it sound like this is just a couple lines of code changed.  
Router_PathRoute DOES approach the problem at a completely different
angle.  People that find the current solution lacking are already using
it.  I've gotten many emails and feedback for it.  The other classes are
mostly smaller patches for compatibility and convenience but
improvements nonetheless.  Rather than reinvent the wheel I have been
trying to work with you and your already great code.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Nick Lo
In reply to this post by Simon Mundy
  Agh, yes it is glaringly, shamefully obvious after having a good  
nights sleep! I think I just had that one left over from thinking  
about it before RewriteRouter was introduced and it has just stuck.

Anyway, it is still a good example of a simple url mapping that I was  
referring to (quietly backs out of room...!).

Thanks,

Nick


>> No it may well be me missing the obvious ...it was a while ago  
>> that I even though about how to do this and likely before  
>> RewriteRouter was released. Presumably the only option is to have  
>> it default to indexAction in indexController? However by then you  
>> are already in the controller and would presumably have to  
>> redirect or have some control structure to deal with it within  
>> indexAction. I think I'd like to see it routed to say a  
>> StaticPostController or such like. I don't actually have need for  
>> it right now and I suspect it would have some issues with scale/
>> naming conflicts but I did want to use it as an example nonetheless.
>
> Hi Nick
>
> You're not limited to using your IndexController:-
>
> $router->addRoute('wordpress', ':article', array('article' =>  
> 'default', 'controller' => 'page', 'action' => 'view'));
>
> This will map to:
>
> class PageController
> {
>     function viewAction()
>     {
>         $article = $this->_getParam('article'); // defaults to  
> 'default';
>         ...your code...
>     }
> }
>
> --
>
> Simon Mundy | Director | PEPTOLAB
>
> """ " "" """""" "" "" """"""" " "" """"" " """"" "  """""" "" "
> 202/258 Flinders Lane | Melbourne | Victoria | Australia | 3000
> Voice +61 (0) 3 9654 4324 | Mobile 0438 046 061 | Fax +61 (0) 3  
> 9654 4124
> http://www.peptolab.com
>
>
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Nick Lo
In reply to this post by Simon Mundy
Purely throwing out rough ideas here but how about something like...

routes.articles.route = articles/:category
routes.articles.defaults = articles/all
routes.articles.required = articles/[a-z_]+

<routes>
     <articles>
         <route>articles/:category</route>
         <defaults>articles/all </defaults>
         <required>articles/[a-z_]+</required>
     </articles>
</routes>

...which is equivalent to...

$config['routes']['articles'] =
new Zend_Controller_Router_Route('articles/:category',
array('category' => 'all',
        'controller' => 'articles',
        'action'      => 'index' ),
        array('category' => '[a-z_]+') );

...and uses the same / separator to delimit each parameter. To me  
that would be easier to explain, setup, visualise, etc.

and perhaps you could use the : in the defaults as in...

routes.articles.defaults = articles:news/:

...which is equivalent to...

array('category' => '',
        'controller' => 'articles',
        'action'      => 'news' )

...poor example that one but I hope the idea is clear.

Nick

> Here's an idea for that:-
>
> ====================================
>
> Config file (as .ini)
>
> route.archive.route = news/:year/:month
> route.archive.defaults.year = 2006
> route.archive.defaults.month = 1
> route.archive.reqs.year = \d+
> route.archive.reqs.month = \d+
>
> or as .xml
>
> <route>
>     <archive>
>         <route>news/:year</route>
>         <defaults>
>             <year>2006</year>
>             <month>1</month >
>         </defaults>
>         <reqs>
>             <year>\d+</year>
>             <month>\d+</month>
>         </reqs>
>     </archive>
> </route>
>
> ====================================
>
> A new method for Zend_Controller_RewriteRouter:-
>
>     public function addConfig(Zend_Config $config, $section) {
>         if (is_null($config->{$section})) {
>         throw new exception("no router configuration in section  
> '{$section}'");
>         }
>         foreach ($config->{$section} as $name => $info) {
>             $this->addRoute($name, new Zend_Controller_Router_Route
> ($info->route,
>                                                                      
> $info->defaults->asArray(),
>                                                                      
> $info->reqs->asArray()));
>         }
>     }
>
> ====================================
>
> And then your bootstrap file would simply contain:-
>
> $config = new Zend_Config(new Zend_Config_Ini('/my/path/
> config.ini', 'development'));
> $router = new Zend_Controller_RewriteRouter();
> $router->addConfig($config, 'route');
>
> ====================================
>
> Even if this doesn't qualify as a feature request for RewriteRouter  
> (one could argue it is not an essential method), it at least serves  
> to show how flexible the existing components are! :)
>
> Cheers
>
> --
>
> Simon Mundy | Director | PEPTOLAB
>
> """ " "" """""" "" "" """"""" " "" """"" " """"" "  """""" "" "
> 202/258 Flinders Lane | Melbourne | Victoria | Australia | 3000
> Voice +61 (0) 3 9654 4324 | Mobile 0438 046 061 | Fax +61 (0) 3  
> 9654 4124
> http://www.peptolab.com
>
>
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Martel
Nick Lo wrote:

> Purely throwing out rough ideas here but how about something like...
>
> routes.articles.route = articles/:category
> routes.articles.defaults = articles/all
> routes.articles.required = articles/[a-z_]+

It will require a lot of string parsing which I would like to avoid. Remember
it will be called on every single request so it should be as fast as possible.
Router is already parsing maps on every request and you wish to parse three
such strings instead of one (per route of course :).

I know you would like to make it very easy for a programmer to write such a
configuration but it wasn't so easy to comprehend what you have meant at the
first glance. Simon's solution looks clearer to me (not to mention faster of
course). But I agree there is a smaller volume of markup with your idea.

--
Michael Minicki aka Martel Valgoerad | [hidden email] | http://aie.pl/martel.asc
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
"Generosity is giving more than you can, and pride is taking less than you
need." -- Kahlil Gibran
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Martel
In reply to this post by Simon Mundy
Simon Mundy wrote:

> Even if this doesn't qualify as a feature request for RewriteRouter  
> (one could argue it is not an essential method), it at least serves  
> to show how flexible the existing components are! :)

Simon, brilliant work! I'm going to incorporate it into the code without any
changes, if that's ok with you.

> Simon Mundy | Director | PEPTOLAB

--
Michael Minicki aka Martel Valgoerad | [hidden email] | http://aie.pl/martel.asc
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
"I am not young enough to know everything." -- Oscar Wilde
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Nick Lo
In reply to this post by Martel
Hi Michael,

Yep no problem, as I said, just tossing ideas onto the table. I was  
aware it would require some string parsing though without digging  
into your code I had no real idea how intensive that was. I am  
surprised you did not find it easy to comprehend as it's a relatively  
straightforward mimicking of the url itself.

If you are going to use the ini and xml versions I presume an array  
version would follow the same pattern as suggested by Simon?:

$config['route']['archive']['route'] = 'news/:year/:month'
$config['route']['archive']['defaults']['year'] = 2006
$config['route']['archive']['defaults']['month'] = 1
$config['route']['archive']['reqs']['year'] = '\d+'
$config['route']['archive']['reqs']['month'] = '\d+'

Nick


> Nick Lo wrote:
>
>> Purely throwing out rough ideas here but how about something like...
>> routes.articles.route = articles/:category
>> routes.articles.defaults = articles/all
>> routes.articles.required = articles/[a-z_]+
>
> It will require a lot of string parsing which I would like to  
> avoid. Remember it will be called on every single request so it  
> should be as fast as possible.
> Router is already parsing maps on every request and you wish to  
> parse three such strings instead of one (per route of course :).
>
> I know you would like to make it very easy for a programmer to  
> write such a configuration but it wasn't so easy to comprehend what  
> you have meant at the first glance. Simon's solution looks clearer  
> to me (not to mention faster of course). But I agree there is a  
> smaller volume of markup with your idea.
>
> --
> Michael Minicki aka Martel Valgoerad | [hidden email] | http://
> aie.pl/martel.asc
> =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
> =-=-=-=-=-=
> "Generosity is giving more than you can, and pride is taking less  
> than you
> need." -- Kahlil Gibran
>
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Martel
Nick Lo wrote:

> Yep no problem, as I said, just tossing ideas onto the table. I was  
> aware it would require some string parsing though without digging  
> into your code I had no real idea how intensive that was.

I have briefly analyzed it in my head. I'll try to dig deeper when I will have
some free time but for now I will just use the Simon's code.

> I am surprised you did not find it easy to comprehend as it's a relatively  
> straightforward mimicking of the url itself.

That's because you have thrown examples before the explanation and I
automatically started to analyze the code while reading. I have caught the idea
while doing so but it just wasn't clearly evident from the very beginning.
That's all. All in all, it seems as a very nice idea :)

> If you are going to use the ini and xml versions I presume an array  
> version would follow the same pattern as suggested by Simon?:

Yes, I guess. I haven't yet used Zend_Config_Array myself but it looks like it
would work.

> Nick

--
Michael Minicki aka Martel Valgoerad | [hidden email] | http://aie.pl/martel.asc
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
"Finance is the art of passing money from hand to hand until it finally
disappears." -- Robert W. Sarnoff
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

John Wells-7
In reply to this post by Nick Lo
On 7/25/06, Nick Lo <[hidden email]> wrote:
> <routes>
>      <articles>
>          <route>articles/:category</route>
>          <defaults>articles/all </defaults>
>          <required>articles/[a-z_]+</required>
>      </articles>
> </routes>
>

I'm wet-behind-the-ears new to this list, so forgive me if I'm
speaking out of turn.  I'm also wet-behind-the-ears new to the ZF, but
I'm fairly enchanted with it, and the work I've done with it in the
past couple of nights is relevant to this topic, so I thought I'd
chime in.

What I've done is establish a pattern for describing routes in a
Zend_Config 'compatible' file, and then extended the
Zend_Controller_Front class to automate the process of receiving
Zend_Config objects with route info and passing them through to the
front controller's router property.

Using XML as an example, routing configuration would look like this
(includes a rewritebase setting, both ways of establishing default
routing, and then an example of a user/:username routing, as taken
from the ZF docs):

<config>
    <production>
        <router>
            <rewritebase>/projects/myapp</rewritebase>
            <routes>
                <default comment="Default routing.">
                    <url />
                    <controller>index</controller>
                    <action>index</action>
                </default>
                <compat comment="Default routing compatibility">
                    <url>:controller/:action</url>
                    <controller>index</controller>
                    <action>index</action>
                </compat>
                <user>
                    <url>user/:username</url>
                    <controller>user</controller>
                    <action>lookup</action>
                    <variables>
                        <username>
                            <default>someuser</default>
                            <validate>\w+</validate>
                        </username>
                    </variables>
                </user>
            </routes>
        </router>
    </production>
</config>


With that loaded up into a Zend_Config object, I then pass the nested
router Zend_Config object off to my extended class,
Phrappe_Controller_Front.  It of course implements the same interface
to the Zend_Controller_Front class, so an HTTP request can simply be
dispatched like so:

$config = new Zend_Config(Zend_Config_Xml::load('path/to/config.xml',
'production'));
Phrappe_Controller_Front::run($zendConfigRouter, $zendConfigDirectory);

Note: the $zendConfigDirectory passed as the second parameter to
Phrappe_Controller_Front is also a Zend_Config object, which gives
directory location/structure info for the application install.  I'm
still hashing this method out, but in my experience it has been
helpful to pull this information into config files as different shared
hosting allow different setup, so it's all in the name of flexibility
right?  Anyway the directory node in the config file would look very
simple, like this:

<config>
    <production>
        <directory>
            <controllers>path/to/controllers</controllers>
        </directory>
    </production>
</config>

Instead of pasting the entire code of my Phrappe_Controller_Front
class into this email, here's a link to download it.  The zip file
includes my class file, and 3 different config files to test with, one
for each style of config file allowed (xml/ini/array).

http://www.johndwells.com/downloads/phrappe_controller_front.zip

The source code is well-documented, so it should be straightforward as
to what it's doing.  I'm also trying to write up some thoughts about
it for my blog. Coming shortly.

I'm very curious about the implications of speed for this approach, as
Martel has mentioned.  Is the Zend_Config object particularly slow? Is
one type of Zend_Config option faster than the next?

Seems to me that application configurations are to an extent a
necessary evil.  Perhaps it can be up to the programmer which approach
to take: if speed is paramount, then include a php file with route
info hard-coded, but if there's some room for automation, then
something like this might be helpful.

Looking forward to feedback.

John W
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Martel
John Wells wrote:

> Seems to me that application configurations are to an extent a necessary
> evil.  Perhaps it can be up to the programmer which approach to take: if
> speed is paramount, then include a php file with route info hard-coded, but
> if there's some room for automation, then something like this might be
> helpful.

Let me start with the last paragraph.

I think that's what Zend Framework is designed in mind - a lot of loosely
coupled components which you can choose to use or not. That's why I'm not sure
if such a tight link between an original Front Controller and a Zend_Config is
desirable (I can't speak for Zend here). Since it in fact refers to setting
options for a third component - the Router.

Your idea to extend the Front Controller is the way it should be done in my
opinion. But you don't have to do so much work there. When I commit Simon's
changes you will be required to extend run method only:

static public function run(Zend_Config $cfg)
{
     $router = new Zend_Controller_RewriteRouter();
     $router->addConfig($config, 'routes');

     $ctrl = self::getInstance();
     $ctrl->setRouter($router);

     $ctrl->setControllerDirectory($cfg->directory);
     $ctrl->dispatch();
}

It's not so hard to do on user part, is it?

And now for the rest:

> Instead of pasting the entire code of my Phrappe_Controller_Front class into
> this email, here's a link to download it.  The zip file includes my class
> file, and 3 different config files to test with, one for each style of
> config file allowed (xml/ini/array).

You're checking if rewrite base is not null and not empty in setRouter. Empty
string is a correct base for an absolute root (like for root of virtual host)
so you may simply strike that out.

> I'm very curious about the implications of speed for this approach, as
> Martel has mentioned.  Is the Zend_Config object particularly slow? Is one
> type of Zend_Config option faster than the next?

It's not my code so it would probably be a good idea to ask the author of
Zend_Config himself. Rob? :)

> John W

--
Michael Minicki aka Martel Valgoerad | [hidden email] | http://aie.pl/martel.asc
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
"The purpose of life is to fight maturity." -- Dick Werthimer
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

John Wells-7
On 7/25/06, Martel Valgoerad <[hidden email]> wrote:
> Your idea to extend the Front Controller is the way it should be done in my
> opinion. But you don't have to do so much work there. When I commit Simon's
> changes you will be required to extend run method only:

I hadn't seen Simon's changes yet (ZF wiki is not responding so I
can't get to Archives), but it sounds like they are spot on.  Very
cool.

> It's not so hard to do on user part, is it?

Nope.  Loving the simplicity.

> You're checking if rewrite base is not null and not empty in setRouter. Empty
> string is a correct base for an absolute root (like for root of virtual host)
> so you may simply strike that out.

Thanks for the feedback, an all points.  Cheers!
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Jayson Minard (ZF)
In reply to this post by John Wells-7
Hey John,

I like the idea, but would like to see the mappings set from outside the
controller or router classes.  A RouteLoader (or something similar) as a
helper to setup the routes keeps the other classes nicely in the dark.

--j


On 7/25/06 2:27 AM, "John Wells" <[hidden email]> wrote:

> On 7/25/06, Nick Lo <[hidden email]> wrote:
>> <routes>
>>      <articles>
>>          <route>articles/:category</route>
>>          <defaults>articles/all </defaults>
>>          <required>articles/[a-z_]+</required>
>>      </articles>
>> </routes>
>>
>
> I'm wet-behind-the-ears new to this list, so forgive me if I'm
> speaking out of turn.  I'm also wet-behind-the-ears new to the ZF, but
> I'm fairly enchanted with it, and the work I've done with it in the
> past couple of nights is relevant to this topic, so I thought I'd
> chime in.
>
> What I've done is establish a pattern for describing routes in a
> Zend_Config 'compatible' file, and then extended the
> Zend_Controller_Front class to automate the process of receiving
> Zend_Config objects with route info and passing them through to the
> front controller's router property.
>
> Using XML as an example, routing configuration would look like this
> (includes a rewritebase setting, both ways of establishing default
> routing, and then an example of a user/:username routing, as taken
> from the ZF docs):
>
> <config>
>     <production>
>         <router>
>             <rewritebase>/projects/myapp</rewritebase>
>             <routes>
>                 <default comment="Default routing.">
>                     <url />
>                     <controller>index</controller>
>                     <action>index</action>
>                 </default>
>                 <compat comment="Default routing compatibility">
>                     <url>:controller/:action</url>
>                     <controller>index</controller>
>                     <action>index</action>
>                 </compat>
>                 <user>
>                     <url>user/:username</url>
>                     <controller>user</controller>
>                     <action>lookup</action>
>                     <variables>
>                         <username>
>                             <default>someuser</default>
>                             <validate>\w+</validate>
>                         </username>
>                     </variables>
>                 </user>
>             </routes>
>         </router>
>     </production>
> </config>
>
>
> With that loaded up into a Zend_Config object, I then pass the nested
> router Zend_Config object off to my extended class,
> Phrappe_Controller_Front.  It of course implements the same interface
> to the Zend_Controller_Front class, so an HTTP request can simply be
> dispatched like so:
>
> $config = new Zend_Config(Zend_Config_Xml::load('path/to/config.xml',
> 'production'));
> Phrappe_Controller_Front::run($zendConfigRouter, $zendConfigDirectory);
>
> Note: the $zendConfigDirectory passed as the second parameter to
> Phrappe_Controller_Front is also a Zend_Config object, which gives
> directory location/structure info for the application install.  I'm
> still hashing this method out, but in my experience it has been
> helpful to pull this information into config files as different shared
> hosting allow different setup, so it's all in the name of flexibility
> right?  Anyway the directory node in the config file would look very
> simple, like this:
>
> <config>
>     <production>
>         <directory>
>             <controllers>path/to/controllers</controllers>
>         </directory>
>     </production>
> </config>
>
> Instead of pasting the entire code of my Phrappe_Controller_Front
> class into this email, here's a link to download it.  The zip file
> includes my class file, and 3 different config files to test with, one
> for each style of config file allowed (xml/ini/array).
>
> http://www.johndwells.com/downloads/phrappe_controller_front.zip
>
> The source code is well-documented, so it should be straightforward as
> to what it's doing.  I'm also trying to write up some thoughts about
> it for my blog. Coming shortly.
>
> I'm very curious about the implications of speed for this approach, as
> Martel has mentioned.  Is the Zend_Config object particularly slow? Is
> one type of Zend_Config option faster than the next?
>
> Seems to me that application configurations are to an extent a
> necessary evil.  Perhaps it can be up to the programmer which approach
> to take: if speed is paramount, then include a php file with route
> info hard-coded, but if there's some room for automation, then
> something like this might be helpful.
>
> Looking forward to feedback.
>
> John W
>


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

Jayson Minard (ZF)
In reply to this post by Martel
At this point, backwards compatibility can be broken for better solutions.
We are not locking in API compatibility yet as it will inhibit useful
changes.  We should be careful and thoughtful, but still allow change.

As for copying the existing router and making it better, that's fine as well
if we are getting to a cleaner and more functional solution that is still
easy to use for the simple cases.  Other approaches to routing are good to
explore in proposals as well but I don't think that is what Michael was
wanting to do here.

So let's consider what he's put onto the table here.

--j




On 7/24/06 4:51 AM, "Martel Valgoerad" <[hidden email]> wrote:

> Nick Lo wrote:
>
>>> 8. Syntax and behavior is 100% backwards compatible with
>>> Zend_Controller_Router_Route
>> Is there a need at this stage to be ensuring backwards compatibility,
>> surely it should be about getting to the best solution?
>
>  From the first glance at the proposed router I don't see how it is backwards
> compatible. I doesn't bind var => value parameters from URL - it leaves them
> in
> unparsed format according to the documentation (Cleveland/OH/44315). Yet it
> should be simple to do if you want it added.
>
> BUT, I agree with Nick. Why copy existing Router solution and add couple of
> functionalities you don't have to use most of the time? Maybe try to come up
> with something that approaches the problem at a completely different angle. So
> it will be useful for these people that find the current solution lacking.
>
>> e.g. By simplest I refer to the way Wordpress can manage urls like:
>> www.myblog.com/my-post-that-is-static
>>
>> I may well be wrong but I cannot see a way to map the above url via a
>> general controller to a row in a database, which means that I could
>> not do a Wordpress to ZF conversion without resorting to using
>> mod_rewrite (or creating multiple controller files). This always
>> seemed to be a strange weakness in ZF so far considering how
>> ubiquitous Wordpress is.
>
> Well, I don't see any problems here. Just define the route as ':name' and look
> for params['name'] in the database, Nick. Or am I missing something obvious?
>
>> 2. Can routes be stored together with and in a similar format to the
>> other configuration info?
>> Especially if development is being done in a team environment.
>
> You have to store the names, route maps, defaults and requirements for every
> single route. I'm willing to add the possibility to use a Zend_Config object
> with the RewriteRouter but I don't see how this can be conveniently stored in
> an ini file. I'm generaly biased in the direction of XML as I have a lot of
> experience working with those files.
>
> Maybe someone would be kind enough to contribute the neutral config structure
> for php, ini and XML config files? I mean to be possible to parse it with the
> same code in the hypothetic RewriteRouter method.
>
>> Nick


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: MJS_Controller_PathRouter - An enhanced RewriteRouter branch

John Wells-7
In reply to this post by Jayson Minard (ZF)
On 7/25/06, Jayson Minard <[hidden email]> wrote:
> Hey John,
>
> I like the idea, but would like to see the mappings set from outside the
> controller or router classes.  A RouteLoader (or something similar) as a
> helper to setup the routes keeps the other classes nicely in the dark.
>
> --j
>

Hi J,

I like the idea of a "loader".  And yes, as I put it together the
first time,  I recognized the tight coupling I was falling into.

Question then: One approach would be like you said, create a Helper
class, something like:

Phrappe_Controller_Router_Helper_RouteLoader.

Alternatively, what about an abstract ConfigLoader, that RouterLoader
then extends?  Like:

Phrappe_ConfigLoader_Abstract
Phrappe_ConfigLoader_RewriteRouter

With this approach, a Phrappe_ConfigLoader_PathRouter could quickly be
created for MJS_Controller_PathRouter, as well as other config options
that might bubble up in the future (like DB connection options?).

Or is there another approach I don't see?

Cheers,
John W
12
Loading...