6

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.

  • Just do write redirect rules in your site .htaccess – WPTC-Troop Dec 28 '15 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 ;-) – Pieter Goosen Dec 28 '15 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. – Ionică Bizău Dec 28 '15 at 7:18
  • @WPTC-Troop Something like RewriteRule prefix-(.*) target-page? – Ionică Bizău Dec 28 '15 at 7:22
  • Yes RewriteEngine On RewriteRule ^some-prefix-*$ http://example.com/target-page [R=301,L] – WPTC-Troop Dec 28 '15 at 7:29
9
+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.

  • 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? – Ionică Bizău Jan 2 '16 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 – Rahil Wazir Jan 2 '16 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! :-) – Ionică Bizău Jan 2 '16 at 16:36
  • @IonicăBizău Sure, but please let me know if it doesn't work – Rahil Wazir Jan 3 '16 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! – Ionică Bizău Jan 8 '16 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.

  • Where should we put this code? – Ionică Bizău Jan 1 '16 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? – Ionică Bizău Jan 1 '16 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 Jan 1 '16 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? – Ionică Bizău Jan 1 '16 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 Jan 1 '16 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');
  • Thanks, but I don't want redirect, I want to serve the page. – Ionică Bizău Dec 28 '15 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". – Fleuv Dec 28 '15 at 7:18
  • @IonicăBizău You mean /some-prefix-and-here-something would serve /target-page without change in url? – Rahil Wazir Dec 28 '15 at 7:24
  • @rahilwazir Exactly! – Ionică Bizău Dec 28 '15 at 7:30
  • @rahilwazir I added the .htaccess file. How can I edit it to get this working, but without redirect? – Ionică Bizău Dec 30 '15 at 18:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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