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:
https://beamusup.com/generate-htaccess/
https://www.htaccessredirect.net/
I hope that helps!
]]>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.
]]>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?
]]>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.
]]>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.
]]>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/
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.
]]>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.
]]>