[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