How to create rewrite rules with the Rewrite API in PHP in WordPress

Contents

Introduction

This article explains, in exhaustive detail, how to create and manage rewrite rules for WordPress using the Rewrite API in PHP. You will learn what rewrite rules are, how WordPress processes them, the core functions and hooks you need, step‑by‑step examples (complete plugin code), debugging techniques, best practices, performance and security considerations, and many practical patterns for real projects.

What are rewrite rules?

Rewrite rules are mappings from pretty (human‑readable) URLs to internal WordPress query variables that determine which content is shown. For example, a request to:

/movies/action/

can be translated into a query like:

index.php?post_type=moviegenre=action

Rewrite rules are regular expressions used by WordPress to intercept incoming requests and convert the matched URL components into the query variables WordPress understands.

How WordPress processes rewrites (high level)

  • When a request arrives, WordPress builds an array of rewrite rules (regex => query_string). These rules are typically stored in the rewrite_rules option and are generated during initialization.
  • WordPress iterates rules in order and checks the request path against each regex. The first match converts the captured groups into a query string that is then parsed into WordPress query variables.
  • Query vars are used by WP_Query, the template loader, and many core/theme/plugin systems to determine which template to load and which content to return.

Core functions and hooks you must know

  • add_rewrite_rule(regex, query, after = bottom) — Add a rewrite rule. regex is a regex pattern (without the leading slash), query is the internal query string (uses matches[n]), after controls placement (top or bottom).
  • add_rewrite_tag(tag, regex, query = ) — Declare a rewrite tag (a named capture you can use in permastructs). Third param optionally sets a query var prefix (like myvar=).
  • add_permastruct(name, struct, args = array()) — Register a permalink structure containing rewrite tags. Used for custom permastructs and custom post types internally.
  • add_rewrite_endpoint(name, places, query_var = null) — Add endpoint support (e.g., /preview/, /feed/ appended to existing permalinks).
  • flush_rewrite_rules(hard = true) — Regenerates and persists rewrite_rules. Only run on activation or admin actions — dont call on every page load.
  • query_vars filter — Use this filter to whitelist custom query variables that you want available via get_query_var(). Note: add_rewrite_tag can register query vars automatically when the third param is used.
  • rewrite_rules_array filter — Filter the full rules array if you must alter rules at the end of generation.
  • init hook — Common place to register rewrite rules and tags.
  • register_activation_hook / register_deactivation_hook — Use to flush rewrite rules on plugin activation/deactivation.

Regex basics and rule anatomy

A rewrite rule has two main parts: the regular expression and the query string. The regex must match the request path (no leading slash). Capturing groups are referenced in the query string as matches[n]. Example:

  • Regex: ^movies/([^/] )/? — matches /movies/action/ capturing action in matches[1]
  • Query: index.php?post_type=moviegenre=matches[1]

Notes:

  • Use ^ and anchors to prevent accidental captures.
  • Make trailing slash optional with /? when appropriate.
  • Keep the regex strict — use [^/] to capture one path segment and avoid greedy matches.
  • Place more specific rules near the top if you use top placement.

Step-by-step: Simple example — movies genre list

Below is a complete minimal plugin that adds a rewrite rule for a custom URL structure /movies/genre/slug/ and makes that slug available as a query var. It includes safe flushing on activation/deactivation and a template_redirect handler that demonstrates how to output or use the query var.

lt?php
/
Plugin Name: Movies Genre Rewrite Demo
Description: Adds /movies/genre/ltgenre-sluggt/ rewrite rule and demonstrates usage.
Version: 1.0
Author: Example
/

if ( ! defined( ABSPATH ) ) {
exit
}

function mg_add_rewrite_tag_and_rule() {
// Register a rewrite tag for %movie_genre% (optional but useful)
// Third parameter registers a query var prefix movie_genre= so WP adds it automatically.
add_rewrite_tag( %movie_genre%, ([^/] ), movie_genre= )

// Add rule: ^movies/genre/([^/] )/? -> index.php?post_type=moviemovie_genre=matches[1]
add_rewrite_rule(
^movies/genre/([^/] )/?



Acepto donaciones de BAT's mediante el navegador Brave :)



Leave a Reply

Your email address will not be published. Required fields are marked *