[wp-trac] [WordPress Trac] #36292: Rewrites: Next Generation

WordPress Trac noreply at wordpress.org
Tue Mar 22 12:42:06 UTC 2016


#36292: Rewrites: Next Generation
-----------------------------+-----------------------------
 Reporter:  rmccue           |       Owner:  rmccue
     Type:  feature request  |      Status:  assigned
 Priority:  normal           |   Milestone:  Future Release
Component:  Rewrite Rules    |     Version:
 Severity:  normal           |  Resolution:
 Keywords:                   |     Focuses:
-----------------------------+-----------------------------

Comment (by giuseppe.mazzapica):

 I really like the effort on this.

 As the guy who wrote the article you mentioned and Cortex (the library
 mentioned in the article) as well as exploring the concept since 2 years
 (in 2014 I release the now abandoned "Clever Rules" https://github.com
 /Giuseppe-Mazzapica/CleverRules) I have some things to say...

 A class for each a rule is overwhelming imo.

 I think that would be easier and with less impact, to introduce a new
 function, maybe named something like `add_rewrite_callback`.

 The fictional code would be something like:


 {{{
 add_action( 'add_rewrite_rules', 'prefix_date_rewrite_rule' );

 function prefix_custom_rules(WP_HTTP_Request $request) {

     add_rewrite_callback(
 "^([0-9]{4}-[a-z]{3}-[0-9]{2})-(morning|afternoon|evening|night)/?",
         'prefix_date_rewrite_rule',
         'top'
     );
 }
 }}}

 As you can see, I passed the yet to come `WP_HTTP_Request` to a new hook
 `'add_rewrite_rules'` that, passing the HTTP request, easily allows to add
 rules only under some request conditions, for instance, HTTP method.

 The `prefix_date_rule` function could then be something like:

 {{{
 function prefix_date_rewrite_rule(array $matches, WP_HTTP_Request
 $request) {

     // A map from the timespan string to actual hours array
     $hours = array(
         'morning'   => range(6, 11),
         'afternoon' => range(12, 17),
         'evening'   => range(18, 23),
         'night'     => range(0, 5)
     );

     // Get the custom vars, if available
     $customdate = $matches[1];
     $timespan = $matches[2];

     // Get UNIX timestamp from the query var
     $timestamp = strtotime($customdate);

     return array(
         'date_query' => array(
              array(
                 'year'  => date('Y', $timestamp),
                 'month' => date('m', $timestamp),
                 'day'   => date('d', $timestamp)
              ),
              array(
                 'hour'    => $hours[$timespan],
                 'compare' => 'IN'
              ),
              'relation' => 'AND'
         ),
     );
 }
 }}}

 This is quite an edge case, most of the rules won't require all this code.

 Maybe, internally the function can be used to generate a route class, but
 to require a class for each custom rule is far from ideal as a public API.

 Regarding skipping the main query, if the callback would return anything
 that is not an array, then there's no variable to assign to the main
 query, so you can just skip the main query if the callback return anything
 but an array.

 Or maybe, would be possible to just `add_filter( 'skip_main_query',
 '__return_false' )` inside the callback.

 Also note that this approach easily allows for things like:


 {{{
 add_rewrite_callback(
    "^/some/path/here?",
    function($matches) {
        do_something_interesting();
        wp_safe_redirect( home_url() );
        exit();
    },
    'top'
 );
 }}}

 or even:

 {{{
 add_rewrite_callback(
    "^/some/path/here?",
    function($matches) {
        wp_send_json_success( array( 'cool' => true ) );
    },
    'top'
 );
 }}}

 If you combine this with the possibility to add rules being aware of
 specific conditions in the HTTP request (because `add_rewrite_rules` hook
 pass the request object and the rule callback receives the request object
 as argument), things becomes interesting.

 Consider that, since you can distinguish "old" string rules from this new
 callback rules, you are not forced to convert the old ones, saving time
 and memory.

 And the two systems could live side-by-side without any issue I think.

 As a final thought, my Cortex (https://github.com/Brain-WP/Cortex) uses
 the library FastRoute (by Nikita Popov, one of the PHP devs who
 contributed more to PHP7) that is faster and less resources consuming of
 the WP system because it use a very clever approach described in this blog
 article http://nikic.github.io/2014/02/18/Fast-request-routing-using-
 regular-expressions.html

 I think would be interesting explore the same concept for WordPress.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/36292#comment:4>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list