• Hi.
    I wonder if someone could help me to generate some redirect rules?
    I am thinking of finally changing my permalink structure.

    When I first established my permalink structure, I had to choose for technical reasons: /index.php/%post_id%/%postname%/
    Back then the server where I host my blog could not handle it without the index.php. And the %post-id% was just me being idiotic. Yeah.

    So now I would like to finally change the permalinks to /%year%/%monthnum%/%day%/%postname%/.

    Now for the rewrite rules:

    1. Can it be done in my .htaccess using rewrite rules?
    Or would you recommend the Redirection plug in?
    (I would prefer to do it in .htaccess if possible)

    2. How can I express the %post-id% ?

    Here’s what I have so far (this would be using the plugin), but without the syntax for the post-id I am stuck:

    Source: ^/ [post-id syntax] /?(.*)
    Target: /\d{4}/\d{2}/\d{2}/$1/

    As far as writing this as a rewrite rule for the .htaccess I am completely lost, And would love to get some pointers, if this can be done.

    • This topic was modified 6 years, 2 months ago by pie0o.
Viewing 11 replies - 1 through 11 (of 11 total)
  • Howdy @pie0o,

    I’ve seen folks have this issue when hosting in certain places.

    I’ve used Redirection for a number of years on many sites. It, of course, makes it easy to generate individual or blanket rewrites. You can even export your Redirection rules to .htaccess format so you can copy/pasta into your .htaccess (backup first).

    So, I’d recommend giving that a shot. Redirection also has a bunch of helpful articles here: https://redirection.me/support/

    You could also try an online .htaccess generator like:

    http://beamusup.com/generate-htaccess/
    https://www.htaccessredirect.net/

    I hope that helps!

    Thread Starter pie0o

    (@pie0o)

    Thanks. Seems to me – if I understand it correctly – with Redirection I would need to to a rule for each post, no? With over 5000 items that’s crazy.
    Or maybe I didn’t see it right?

    Moderator bcworkz

    (@bcworkz)

    Yeah, that would be crazy! I’m not a user of Redirection, but it appears to support regexp, so you can capture the essential element from the source URL and utilize it in the target URL. It’s conceivable that one rule can cover all posts. As you probably know, .htaccess rewrite rules also use regexp, so one rule set could cover all situations there as well. AFAIK, .htaccess rewrites are more efficient than using WP, provided we are looking at only one rule to handle all rewrites.

    There is a point of diminishing returns. Excessive .htaccess rules can become less efficient than WP methods because all rules have to be evaluated with every request before going to WP, even if they don’t apply.

    I’m not so sure you need to do anything. WP normally rewrites alternative single post requests to the established permalink automatically. You just need to be sure the old style single post URLs still work and the preferred permastruct is properly configured.

    For example. I had created a custom query var that gets a custom post type by ID. Something like example.com/index.php?my-news=1234. A silly unnecessary approach, index.php?p=1234 would have worked.

    My custom post type permastruct is now example.com/news/%post-name%/. Now when I request posts using my old silly custom query var, the appropriate news item is returned and rewritten to its new permalink. Other than setting pretty permalinks, I did nothing special for this to happen.

    Thread Starter pie0o

    (@pie0o)

    Thank you for your answer. Yes, I am pretty sure WP can handle rewrites from the original URL index.php?p=1234 to a new “pretty” permalink structure as eg. mine /index.php/%post_id%/%postname%/.

    However I am not sure, the same applies if I switch between two types of “pretty” permalink structures eg. from /index.php/%post_id%/%postname%/ to say /%year%/%monthnum%/%day%/%postname%/.

    It is my understanding, that this would lead to errors for incoming links, and there for mess with search engine ranking etc. To avoid that I would need a regexp for that. htaccess versus plugin, I guess each have their advantages.

    But I am stuck on how to write this regexp rule. I think I figured out the basic structure, but I am unclear how to write the /index.php/ and the /%post_is%/ part of the rule.

    Source: ^/ [index.php] / [post-id syntax] /?(.*)
    Target: /\d{4}/\d{2}/\d{2}/$1/

    Can anyone help me to write the exact regexp?

    Moderator bcworkz

    (@bcworkz)

    You should find that just about any URL ending with a post slug will return the single post and redirect to it’s permalink. If a valid post slug is my-first-post, requesting example.com/terms/that/mean/nothing/to/wp/my-first-post/ will redirect to the current post’s permalink. Where we run into trouble is if any of those terms do mean something to WP, the request will likely 404. For example, numeric terms rarely work because WP will try to interpret them as date parameters. Chances are they will not match the post date, so no match will be found. Such automatic redirects return with 301 status, so search engines should properly handle them.

    But if you feel explicitly making redirects will be beneficial, there’s no reason not to. The regexp syntax is only accepted for source URLs. Target URLs must be composed of a combination of fixed string literals and capture groups from the source regexp. There’s no opportunity to insert variable data from the DB, such as a post’s date, if it is not available in the source URL.

    To get to URLs that contain data that is not from the source, the source needs to be rewritten to query vars. With the right query vars, WP will find the right post and redirect to the established permalink, using DB data to fill in any blanks.

    For example, if your source URL is /index/id/1234/, you cannot rewrite to /02/03/2018/my-thousandth-post/ There is no date data or slug data in the source. The necessary data does not exist. What you can do is rewrite to index.php?p=1234 because 1234 can be captured from a regexp. WP will then find post 1234 and redirect to the established permalink /02/03/2018/my-thousandth-post/ for you. You don’t have to use post ID in rewrites, only something that WP can use to get to a single post. It can be the post slug or a set of meta data that resolves to a single post. But it has to be available in the source. The only data that can be created are string literals that do not change for a particular regexp match.

    Writing regexps that work is certainly a challenge. I suggest you work out what you need using any one of several regexp “fiddle” tools (such as regexr.com) where you can easily try different regexps until you arrive at one that does the job.

    Thread Starter pie0o

    (@pie0o)

    ^bump

    Moderator bcworkz

    (@bcworkz)

    @pie0o – Please do not try to bump threads in these forums. Not only does it not comply with our guidelines, but you’ll find it does nothing to change the visibility of your thread. So there’s really no point to it.

    For the reasons I’ve explained in my last post, no one will be able to suggest precise rewrite rules using the criteria you’ve so far set forth, it’s impossible to do. Only once you set forth a viable scheme within the constraints I’ve identified would anyone be able to suggest something.

    Thread Starter pie0o

    (@pie0o)

    Yes, sorry for the bump. For some reason your response earlier did not load for me this morning.

    Thank you for clarifying. So it can’t be done.

    So I either have to create a redirect for every single link individually in a plugin like Redirection.

    Or could I do this with a regexp, just lose the index.php and the post_id?

    /index.php/%post_id%/%postname%/

    to

    /%postname%/

    Thank you very much for the help.

    How would I write post_id?

    Source: ^/\index/\./\php/ [post-id syntax] /?(.*)
    Target: /$1/

    • This reply was modified 6 years, 2 months ago by pie0o.
    • This reply was modified 6 years, 2 months ago by pie0o.
    • This reply was modified 6 years, 2 months ago by pie0o.
    Moderator bcworkz

    (@bcworkz)

    Yeah, the caching on this site can be pretty wonky sometimes. I figured something like that happened when you bumped my post πŸ˜€ The fact remains bumping doesn’t do any good because posts are always ordered by first post date, not recent reply.

    I am assuming you are looking for .htaccess syntax. The WP rewrite rule syntax is slightly different. I agree that .htaccess rewrites are preferable for your situation. The following is what I suggest:

    <ifmodule mod_rewrite.c>
    	RewriteEngine on
    	RewriteBase /
    	# Don't process URL already rewritten
    	RewriteCond %{REQUEST_URI} !^/[^/]+/$
    	RewriteRule ^/index\.php/[0-9]+/([^/]+)/?$ /$1/ [L]
    </ifmodule>

    I’ve noticed in your past posts that you’ve been attempting to escape slashes / in your regexp attempts as /\. FYI, that’s backwards. A backslash \ is the regexp escape character, it always precedes the character being escaped. We escape characters that have special meaning in regexp when we want the literal character and not the special regexp meaning. For example, the dot . character has special meaning, it matches any single character. To actually match a dot and only a dot, it has to be escaped. That’s why I have index\.php. I’ve not escaped my slashes because a slash doesn’t have special meaning in .htaccess regexp.

    The only reason slashes are escaped in other regexp is because the slash is a common regexp delimiter. But any character without special regexp meaning can be a delimiter, so if we do not use a slash as a delimiter, then we do not need to escape slashes. Typical regexp to match “/index.php/”: '/^\/index\.php\/?/'
    Because the delimiters are slashes, we must escape literal slashes within.

    Valid alternative: '|^/index\.php/?|'
    Here the delimiter is the pipe | character, thus slashes within do not need to be escaped. If we needed to match a literal pipe within, then it would need to be escaped. In the previous example it would not be necessary.

    Because .htaccess regexp does not use delimiters and slashes have no special regexp meaning, slashes in .htaccess regexp do not need to be escaped. I hope this makes sense and helps you in the future with understanding regexp. Regexp is certainly something very difficult to grasp without a great amount of effort and experimenting.

    Thread Starter pie0o

    (@pie0o)

    Thank you so much for your help and your patience. Much appreciated!

    The thing I now need to consider is that this form of permalink is not really that useful, as it contains no additional information for search engines and such, it’s just prettier.

    • This reply was modified 6 years, 2 months ago by pie0o.
    Moderator bcworkz

    (@bcworkz)

    Understood. .htaccess can only work with the data it’s given. It can add static data, but it cannot dynamically fill in data unique to a particular post. Only WP can do that. Given a valid URL that resolves to a single post, whether by ID or slug, WP will automatically rewrite the supplied URL to the post’s established permalink, using whatever data it needs to provide the correct date and other elements.

    If an URL like /index.php/%post_id%/%postname%/ resolves to a single post even though your current permastruct is /%year%/%monthnum%/%day%/%postname%/, then WP should be rewriting to that permastruct. There wouldn’t be any reason to have an intermediate .htaccess rule if the original /index.php/%post_id%/%postname%/ is understood by WP. But if it no longer works because the permastruct has changed, .htaccess can rewrite it to a URL that WP will accept, such as /%postname%/. WP will then rewrite to match the current permastruct.

Viewing 11 replies - 1 through 11 (of 11 total)
  • The topic ‘Redirect help’ is closed to new replies.