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

WordPress Trac noreply at wordpress.org
Tue Mar 22 06:52:20 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:
-----------------------------+-----------------------------
Changes (by rmccue):

 * owner:   => rmccue
 * status:  new => assigned


Comment:

 [attachment:rewrites.diff] is part 1 of this plan. It introduces a
 `WP_Rewrite_Rule` class, as well as a `WP_Rewrite_RuleInterface`
 interface. This moves some parts of the rewrite handling to the rule
 object, which allows substantial benefits.

 For example, let's use [https://roots.io/routing-wp-requests/ the example
 from Roots' post] under "A challenging example". This can now be rewritten
 as a simple class, and avoid the use of intermediary rewrite tags
 altogether:

 {{{
 <?php

 class Custom_Rule extends WP_Rewrite_Rule {
         public function get_query_vars( $matches ) {
                 // A map from the timespan string to actual hours array
                 $hours = [
                         'morning'   => range(6, 11),
                         'afternoon' => range(12, 17),
                         'evening'   => range(18, 23),
                         'night'     => range(0, 5)
                 ];

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

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

                 return [
                         'date_query' => [
                                 [
                                         'year'  => date('Y', $timestamp),
                                         'month' => date('m', $timestamp),
                                         'day'   => date('d', $timestamp)
                                 ],
                                 [
                                         'hour'    => $hours[$timespan],
                                         'compare' => 'IN'
                                 ],
                                 'relation' => 'AND'
                         ],
                 ];
         }
 }
 // Let's add rules on init
 add_action('init', function() {

         $custom_date_format = '([0-9]{4}-[a-z]{3}-[0-9]{2})';
         $timespan_format = '(morning|afternoon|evening|night)';

         // This adds the rule
         add_rewrite_rule(
                 "^{$custom_date_format}-{$timespan_format}/?",
                 new Custom_Rule(),
                 'top'
         );
 });
 }}}

 This is substantially simpler, and more powerful. You can do conditional
 query building in the callback easily if you want, or map to any arbitrary
 set of query vars.

 If you're not using a query at all, you can set `$rule->skip_main_query =
 true`, an alternative to patches proposed in #10886. In addition, you can
 subclass and override `should_skip_main_query()` to return false, allowing
 complex handling here too.

 == Performance ==

 The main concern here is with performance. I've profiled this with 1000
 extra rules and measured both timing and memory. The current patch takes
 69% longer (9ms vs 16ms) and uses 176% more memory (512KB vs 1415KB),
 '''however''' this is due to the current implementation, which converts
 string-based rules to objects for ease of internal handling. We can
 instead use just-in-time conversion after the pattern matching, which
 reduces this significantly; updated patch coming soon.

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


More information about the wp-trac mailing list