Rewrite Rules: Add opt-in support for random content redirects. - #13022
Rewrite Rules: Add opt-in support for random content redirects.#13022mlaetitia wants to merge 3 commits into
Conversation
Adds wp_random_content_redirect(), hooked on template_redirect, which redirects ?random requests to a randomly selected published post. Disabled by default; enable with the enable_random_content_redirect filter. Picks via COUNT plus a random OFFSET instead of ORDER BY RAND(). See https://core.trac.wordpress.org/ticket/64498 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Check for the random parameter before evaluating the enable filter so disabled sites pay no filter lookup per request. Validate post type viewability unconditionally, prime the post cache for get_permalink(), skip the second query when the random offset is zero, and drop test teardown that the test framework already guarantees. See https://core.trac.wordpress.org/ticket/64498 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
ellatrix
left a comment
There was a problem hiding this comment.
Just some nits, leaving some time for others to see this and can commit if you're ready.
| } | ||
|
|
||
| // Temporary redirect, so clients do not cache the randomly picked target. | ||
| wp_safe_redirect( $link, 302 ); |
There was a problem hiding this comment.
Should we also call nocache_headers?
There was a problem hiding this comment.
I suppose the intent here is to not cache the redirection (hence 302), while allowing clients to cache the resolved page (i.e. the randomly selected post). No?
There was a problem hiding this comment.
Wouldn't it cache based on the URL? I'm not a page cache expert, hence my comment being formatted as a question 🙂
There was a problem hiding this comment.
Thanks both for the comments. I ended up adding a nocache_headers as we actually want both as much as possible:
- the 302 makes the redirect non-permanent
- stop intermediary caches (CDNs, full-page caches) from pinning the redirect, which would make ?random return the same post for everyone
Thanks! Hadn't considered this properly
| if ( isset( $_GET['random_cat_id'] ) ) { | ||
| $cat_id = absint( wp_unslash( $_GET['random_cat_id'] ) ); | ||
|
|
||
| if ( $cat_id < 1 ) { |
There was a problem hiding this comment.
absint always returns positive? Should it be (int) instead maybe?
There was a problem hiding this comment.
Great catch! I changed this and also on the same note changed the test that checked the negative value as it was generally failing (as it should) but mostly for the wrong reasons.
changed both on the last commit
| return; | ||
| } | ||
|
|
||
| if ( isset( $_SERVER['REQUEST_METHOD'] ) && ! in_array( strtoupper( $_SERVER['REQUEST_METHOD'] ), array( 'GET', 'HEAD' ), true ) ) { |
There was a problem hiding this comment.
Not sure if by design, but if $_SERVER['REQUEST_METHOD'] isn't set, it will not return early.
There was a problem hiding this comment.
Generally it wouldn't (maybe some CLI scenarios?) , but I rewrote this to explicitly accept only GET or HEAD.
Note: I didn't include the new QUERY method since Core doesn't yet support it (so can't imagine a scenario where it would be sent)
Trac ticket: https://core.trac.wordpress.org/ticket/64498
This PR adds a minimal, opt-in implementation of random content redirects
What it does
Adds
wp_random_content_redirect()(inwp-includes/query.php, alongside its closest siblingwp_old_slug_redirect()), hooked ontemplate_redirect.When enabled, a request to
example.com/?randomissues a 302 redirect to a randomly selected published post.?random&random_post_type=pagerestricts the pick to a post type (viewable types only);?random&random_cat_id=<term ID>restricts it to a category. These parameter names match Matt's original Random Redirect plugin referenced in the ticket, so existing?randomlinks keep working.Disabled by default — per the ticket's request for an opt-in implementation with no user-facing settings or defaults, nothing happens unless a theme or plugin opts in:
A second filter,
random_content_redirect_url, allows short-circuiting or rewriting the redirect target (same pattern asold_slug_redirect_url).Implementation notes
WP_Querycalls) rather thanORDER BY RAND(), which randomizes and sorts every candidate row on each request and is uncached.$_GETontemplate_redirect, matching the original plugin's addressing. If pretty-URL support (e.g. a/random/rewrite endpoint) is desirable, the parameters should instead become registered query vars — happy to rework in that direction if preferred.Tests
tests/phpunit/tests/rewrite/randomContentRedirect.phpcovers: disabled-by-default behavior, no-op without therandomparameter, redirect to a published post, post type and category restriction, exclusion of password-protected/draft/private posts, invalid and non-viewable post types, nonexistent categories, empty result sets, and non-GET requests.Use of AI Tools
AI assistance: Yes
Tool(s): Claude Code
Model(s): Claude Fable 5
Used for: Initial implementation and test suite, ported from the Jetpack Random Redirect module under my direction; reviewed, tested, and edited by me.
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.