11

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.

9
  • Just do write redirect rules in your site .htaccess
    – WPTC-Troop
    Commented Dec 28, 2015 at 6:01
  • Plugin recommendations are off topic, I have removed that part. I also believe this type of question was asked a while ago IIRC, so use the site search to look for possible solutions ;-) Commented Dec 28, 2015 at 6:01
  • @PieterGoosen True. I was just wondering if someone wrote this before. I also googled a little bit, but honestly I'm not a PHP hacker... :D I'm hoping that you guys will help me. I'm more in the Node.js/JS side. Commented Dec 28, 2015 at 7:18
  • @WPTC-Troop Something like RewriteRule prefix-(.*) target-page? Commented Dec 28, 2015 at 7:22
  • Yes RewriteEngine On RewriteRule ^some-prefix-*$ http://example.com/target-page [R=301,L]
    – WPTC-Troop
    Commented Dec 28, 2015 at 7:29

3 Answers 3

13
+50

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.

8
  • Thanks! Will test this tomorrow. I think instead of 'index.php?page_id=' . $page_id I can pass any existing path to an HTML file (which is stored in the public directory), right? Commented Jan 2, 2016 at 16:15
  • @IonicăBizău Yes you can, also don't forget to flush and regenerate the rewrite rules whenever you modify the above add_rewrite_rule Commented Jan 2, 2016 at 16:26
  • don't forget to flush and regenerate the rewrite rules whenever you modify the above add_rewrite_rule – good point. Hopefully it will work. If it does, I will consider adding a 50 point bounty to reward you! :-) Commented Jan 2, 2016 at 16:36
  • @IonicăBizău Sure, but please let me know if it doesn't work Commented Jan 3, 2016 at 19:51
  • I does work. I tested it out and working. Once this will go on production being tested enough, I will open a bounty to reward you. :) Thanks a lot! Commented Jan 8, 2016 at 7:41
4

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.

5
  • Where should we put this code? Commented Jan 1, 2016 at 10:33
  • We put that in functions.php and we got a blank page everywhere. Also, how can I serve a static index.html file located at /foo/bar/index.html (where bar is dynamic) instead of a Wordpress page? Commented Jan 1, 2016 at 10:37
  • Sorry for the syntax error, was one extra ). I updated the answer regarding that. Here I assumed the target page was a WordPress page that you could adjust it's content to your needs. It's possible to include static html file like this hack (without css/js), but if you're dealing with serving such (external) static HTML files, then I would recommend you to try to solve this purely with the webserver instead. @IonicăBizău
    – birgire
    Commented Jan 1, 2016 at 11:22
  • But if you're dealing with serving external static HTML files, then I would recommend you to try to solve this purely with the webserver instead. – we have already paths like /foo/bar/some-page/index.html. This allows us to access in the browser /foo/bar/prefix-some-page. Instead of this, I want to access /prefix-some-page which will serve ``/foo/bar/prefix-some-page. The prefix-some-page` is something that is dynamic, so I want to do something like: /prefix-* => /foo/bar/prefix-$1/index.html. This will happen only if there is no prefix-... page in the Wordpress. How to do this? Commented Jan 1, 2016 at 11:29
  • You could try: RewriteRule ^(.*)prefix-([^/]+)/?$ /foo/bar/prefix-$2/index.html [NC,L] to serve e.g. http://example.tld/prefix-test/ as it were http://example.tld/foo/bar/prefix-test/index.html But this is of course unaware if there's any such page already in WordPress. To add such a check, maybe this rule would need to be generated within WordPress on a reqular basis? @IonicăBizău
    – birgire
    Commented Jan 1, 2016 at 14:09
0

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');
8
  • 1
    Thanks, but I don't want redirect, I want to serve the page. Commented Dec 28, 2015 at 7:15
  • @IonicăBizău you can redirect to any page as well as to a page with the message "this page has been reserved".
    – luukvhoudt
    Commented Dec 28, 2015 at 7:18
  • @IonicăBizău You mean /some-prefix-and-here-something would serve /target-page without change in url? Commented Dec 28, 2015 at 7:24
  • @rahilwazir Exactly! Commented Dec 28, 2015 at 7:30
  • @rahilwazir I added the .htaccess file. How can I edit it to get this working, but without redirect? Commented Dec 30, 2015 at 18:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.