GithubHelp home page GithubHelp logo

rewrite-register's Introduction

Rewrite Register

Overview

This is an initial proof-of-concept for a new way to handle rewrite rules in WordPress.

Presently, rewrite rules are cached in an option. When rules change, this cache must be "flushed", which is to say, regenerated. This is an imperfect, error-prone, and relatively manual process -- there's no great way to tell WordPress that rules have been added, modified, or removed, and that they should be regenerated (but only once).

This plugin aims to resolve the pains of rewrite flushing by adding a way to register rewrite rules. On every request, the register is then checked for changes against the most recent version. If any changes are found, the rules regenerate. The register contains the name of the rule set, the version of those rules, and the relative order in which they should be added.

Rule ordering is another pain point of the current rewrite system. When adding rules via add_rewrite_rule(), the only options for ordering are "top" or "bottom", and both of which are relative to the time the code is executed. When adding rules via add_permastruct(), one has virtually no control over where these rules are added. The rule ordering in this plugin is operational, but only with regards to other rules added to the register. Unfortunately, rules cannot be added relative to core rules at this time.

Examples

By activating the plugin, most rewrite rules will automatically get registered and the rules will flush when they change. This includes any additions or subtractions of permastructs, changes to permastruct arguments, and any calls to add_rewrite_rule() which happen in the normal request chain (e.g. on init).

Any rewrites added throughout the WP_Rewrite::rewrite_rules() routine (which includes all of its filters like generate_rewrite_rules and rewrite_rules_array) are not automatically registered, and changes to them would not trigger a rewrite flush. These rules must be registered to have their changes automatically flush the rewrite rules.

To register a rule, you would call:

wp_register_rewrites( $name, $version = null, $after = 'bottom', $callback = null );

$name is a unique reference key (slug) which is used in the action fired when rules are generated, and it can be used in other rule registrations to indicate placement.

$version is a version identifier. This will most often be an integer, but it could also be a float (e.g. 1.2) or a string (e.g. 'rc3'). The version exists to tell WordPress that the rules under $name have changed.

$after is used to indicate the placement for your rewrite rules. This can be 'top', 'bottom', or the $name of any other registered rewrites.

$callback is an optional callback which will automatically be hooked to the action which fires when rules are generated.

Here's an example of how one might register a set of rules added via the generate_rewrite_rules filter:

add_action( 'register_rewrites', function() {
	wp_register_rewrites( 'my-custom-rules', '1.0' );
} );

First, we see that we're hooking into a new action, "register_rewrites", which is a reserved action where all rules are registered (thus, there's no ambiguity around which action to use). In our function tied to "register_rewrites", we're registering our set of rules with a unique name "my-custom-rules" and a version "1.0".

Everything else done through generate_rewrite_rules can remain the same. If these rules ever changed, the developer would want to change the version, and the updates would be loaded on the next page request.

Let's look at a more elaborate example of registering rules in hierarchy, and only adding the rules when the rewrite rules cache is being built.

add_action( 'register_rewrites', function() {
	wp_register_rewrites( 'demo-1', '1.1', 'demo-2' );
	wp_register_rewrites( 'demo-2', '1.2', 'demo-3' );
	wp_register_rewrites( 'demo-3', '1.0', 'top' );
} );

add_action( 'build_rewrite_rules_demo-1', function() {
	add_rewrite_rule( 'foo/?$', 'index.php?foo=1' );
} );
add_action( 'build_rewrite_rules_demo-2', function() {
	add_rewrite_rule( 'bar/?$', 'index.php?bar=all' );
	add_rewrite_rule( 'bar/(\d+)/?$', 'index.php?bar=$matches[1]' );
} );
add_action( 'build_rewrite_rules_demo-3', function() {
	add_rewrite_rule( 'bat/([^/]+)/?$', 'index.php?bat=$matches[1]' );
	add_rewrite_rule( 'bat/([^/]+)/(\d+)/?$', 'index.php?bat=$matches[1]&paged=$matches[2]' );
} );

In our function bound to "register_rewrites", we're registering three sets of rules, demo-1, demo-2, and demo-3. demo-1 is at version 1.1 and should come after demo-2. demo-2 is at version 1.2 and should come after demo-3. demo-3 is at version 1.0 and should appear in the "top" set of rules. Breaking this all down, we should see the rules in the "top" register in the order demo-3, demo-2, demo-1.

Below the "register_rewrites" action, we're hooking into three different actions for our three sets of rules. The actions are build_rewrite_rules_{$name} (e.g. "build_rewrite_rules_demo-1"). These actions only fire when the rules need to be regenerated; they do not fire on every request. Within the functions for each of these actions, we're simple adding the rules for that rule set.

If we changed the rule associated with demo-3, we would want to increase the version, say to '1.1'. This change tells WordPress that it needs to regenerate the rules, and it will do so on the next page request.

What's Next

This POC already relieves (in most situations) one of WordPress' major pain-points, which is that rewrite rules do not automatically regenerate when changes are made. It also lays out a framework for a significant improvement in the control of rule ordering (or more accurately, rule hierarchy). Changes would need to be made to core to fully realize the idea of rewrite registration.

rewrite-register's People

Contributors

mboynes avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.