This problem can be solved with the WordPress Rewrite API
The simplest way
I assume that you’ve created a page called year
and the request is most probably matched to this rule (.+?)(/[0-9]+)?/?$
, with the query rewritten to pagename=year
.
However, you will notice from the regular expression that an additional /
can be matched to with numbers following it.
Requesting /year/1999
will transform the query to pagename=year&page=%2F1999
. Thus page
is what will contain 1999
. And you can get to it using get_query_var('page');
and feed it to your custom query by using use the simple get_posts()
and feed it the extra meta_key
and meta_value
to retrieve your posts like so:
$args['meta_key'] = 'year';
$args['meta_value'] = get_query_var('page');
// ... other arguments
$posts_array = get_posts( $args );
But isn’t this wrong?
If using this unexpected result and behavior of taking page and feeding it in as year this feels wrong, you can go about achieving the same result in a different way by adding your own rewrite rule.
By adding a rule that will match ^year/([^/]\d+)/?'
and rewrite to pagename=year&custom_year=$matches[1]
you will be able to access custom_year
via $wp
global object.
// this has to be done only once!
add_rewrite_rule('^year/([^/]\d+)/?',
'index.php?pagename=year&custom_year=$matches[1],
'top');
flush_rewrite_rules();
The code above should be wrapped to be hooked into the init
action. The query itself can be accessed retrieved from the $wp->matched_query
property and has to be parsed:
global $wp; // may be required to bring into scope
$q_args = array();
parse_str($wp->matched_query, $q_args);
$custom_year = $q_args['custom_year'];
$args['meta_key'] = 'year';
$args['meta_value'] = get_query_var('custom_year');
// ... other arguments
$posts_array = get_posts( $args );
Note how you pick the name of your custom query field and make sure it’s not in danger of collision with any of the reserved terms.
Another way of looking at it
You may be better off looking at the whole situation from an archive’s perspective rather than a page. If you register your own custom taxonomy for your posts instead of a custom field, you’ll be able to query for posts based on that taxonomy without the manually adding additional rewrite rules.
The register_taxonomy()
function will allow you to add your custom_year
taxonomy and query for it getting archive pages back, without additional parsing, queries, etc.
You may have to flush_rewrite_rules()
once after registering the taxonomies in order to flush some new rules WordPress automatically generates when registering taxonomies.
Take note of the rewrite
argument you supply to register_taxonomy()
, set it to custom_year
and you should be able to query for posts in the taxonomy without further modifications.