Access the same page from multiple urls (wildcard)

I want to serve a specific WordPress page for multiple urls. Basically I want to point all the urls in a specific format to a known page:

/some-prefix-* => /target-page

And accessing /some-prefix-and-here-something it should load /target-page.

How to do this?

Note I do not want to redirect the user but to be able to serve an existing page to multiple urls.

The .htaccess looks like this:

# BEGIN s2Member GZIP exclusions
RewriteEngine On RewriteRule ^prefix-*$ some/path/to/directory-$1 [NC,L]
<IfModule rewrite_module>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{QUERY_STRING} (^|?|&)s2member_file_download=.+ [OR]
    RewriteCond %{QUERY_STRING} (^|?|&)no-gzip=1
    RewriteRule .* - [E=no-gzip:1]
</IfModule>
# END s2Member GZIP exclusions

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

DirectoryIndex index.php index.html

I thought by adding RewriteEngine On RewriteRule ^prefix-*$ some/path/to/directory-$1 [NC,L] will serve /prefix-* from some/path/to/directory-$1. For example: when accessing example.com/prefix-foo should be the same with example.com/some/path/to/directory-foo (which resolves to example.com/some/path/to/directory-foo/index.html).

Also, if there is already a WordPress page with the name prefix-bar, /prefix-bar should not load example.com/some/path/to/directory-bar/index.html.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

You can use template_include, but before you hook to this filter you must do the following steps:

  1. Create page template. e.g: page-target.php
    <?php
    /**
     * Template Name: Page Target
     */
    ...
  2. Manually query the contents of target-page on page-target.php template, because the global $post will be referencing to your some-prefix-* page.
  3. (Optional): Edit and apply page template Page Target to your /target-page from the Page Attributes

Then add the following to your functions.php file

add_filter('template_include', function($template) {
    global $post;

    $prefix = 'some-prefix-'; // Your prefix
    $prefixExist = strpos($post->post_name, $prefix) !== false;

    if ($prefixExist) {
        return locate_template('page-target.php'); //Your template
    }

    return $template;
});

Above filter will override the template with page-target.php if condition met, otherwise default

Edit:

I think I have found a better way to resolve this using add_rewrite_rule

function custom_rewrite_basic() {
  $page_id = 123; //Your serve page id
  add_rewrite_rule('^some-prefix-.*', 'index.php?page_id=' . $page_id, 'top');
}
add_action('init', 'custom_rewrite_basic');

IMPORTANT: Do not forget to flush and regenerate the rewrite rules database after modifying rules. From WordPress Administration Screens, Select Settings -> Permalinks and just click Save Changes without any changes.

Method 2

Note that search engines might not like multiple paths to the same content!

Here I assume you want e.g.:

example.tld/some/path/to/painting-orange
example.tld/painting-blue
example.tld/painting-red
example.tld/painting-yellow

to behave like it was this page:

example.tld/paintings

but not so for paths like:

example.tld/painting-white/painting-brown/large
example.tld/painting-brown/small

The rule here is to match the prefix on the left side of basename( $path ).

Here’s a little hack with the request filter, to check if the current page name is correctly prefixed:

<?php
/** 
 * Plugin Name: Wildcard Pages
 */
add_filter( 'request', function( $qv )
{
    // Edit to your needs
    $prefix = 'painting-';
    $target = 'paintings';

    // Check if the current page name is prefixed
    if(    isset( $qv['pagename'] )
        && $prefix === substr( basename( $qv['pagename'] ), 0, strlen( $prefix ) ) 
    )
        $qv['pagename'] = $target;

    return $qv;
} );

Modify this to your needs. Then create the plugin file /wp-content/plugins/wpse-wildcard-pages/wpse-wildcard-pages.php file and activate the plugin from the backend.

We could also add a check with get_page_by_path() on the target page, just to make sure it exists. We might also want to restrict this to certain post types.

Method 3

Create a hook to init and wp_redirect when the current post’s slug starts with your prefix.

function wp_init() {

    global $post;
    $slug = $post->post_name;
    $prefix = 'foobar';
    if (substr($slug, 0 strlen($prefix))==$prefix) {
        wp_redirect(123); // your page id
    }

}
add_action('init', 'wp_init');


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x