Forum Moderators: phranque

Message Too Old, No Replies

How Do I Use 301 to Redirect to a sub folder and change extension?

using 301 redirects in .htaccess to redirect pages to WordPress subfolder

         

Egbert Souse

7:43 pm on Dec 24, 2015 (gmt 0)

10+ Year Member



Hi!

I have a website, and have the main pages all with .php extensions in the root.

eg. https://example.com/my-great-page.php

There are over 100 pages, the URL's may contain one or my hyphens, and/or underscores.

Some of the pages are ranking very high in search engines.

Recently I decided to move to a WordPress site.
So I set up a sub directory /wp/

https://example.com/wp/

I recreated the 100+ pages in WordPress and gave them the same URL without the .php extension
e.g.
https://example.com/wp/my-great-page

What I would like to do is use a blanket statement in .htaccess to redirect all traffic to those pages to the /wp/ folder and strip off the .php extension.

Moving
https://example.com/my-great-page.php
to
https://example.com/wp/my-great-page

I did find this

# Redirect domain.com to domain.com/folder/

RewriteEngine On
RewriteRule ^$ /folder/ [R=301]

# end redirect


But that does not strip out the .php

Thank You in Advance for Your Advice and Help!

lucy24

7:55 pm on Dec 24, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



What have you tried so far? Redirecting to extensionless has got to be one of the Top Ten apache questions.

The real question, however, is: Why do you need or want to redirect URLs that are doing fine the way they are? Why not just rewrite (internally) and then you can decide later about redirecting if you really think it's worth it.

the URL's may contain one or m[an]y hyphens, and/or underscores

A lowline counts as a \w ("word character") so that's no problem. The hyphen doesn't, so your pattern is
^([\w-]+)\.php

If and when you do decide to redirect, you may also want to do something about the hyphens and lowlines. One or the other, fine, but using both seems a bit messy unless there's a solid reason for it.

Egbert Souse

10:38 pm on Dec 24, 2015 (gmt 0)

10+ Year Member



Hi Lucy,

Thank you for your reply.

"What have you tried so far?"
I went into cPanel and manually did 301 redirects, unfortunately that caused some errors.
And I really do not want a huge .htaccess file with so many redirects (1 line per page).

"The real question, however, is: Why do you need or want to redirect URLs that are doing fine the way they are? "
I copied all the pages into WordPress. Word Press will not accept a page with a .php extension.
I moved everything to Wordpress because I believe it will be easier to maintain the site in the future if it si in wp, and there are a bunch of plug-ins that provide extra security, slides, and more.

Since I will be penalized for duplicate content on my site, I want to pull down the .php pages and just have everything in the WP site. (with the exception of the shopping cart I am using -- CubeCart)

Since the page URL's have underscores, and or hyphens and they are ranking highly, I do not want to run the ratings, and links to those pages.

Is there a better way to go, so I don't lose rankings, and disrupt links while having all content (with the exception of the cart) in the wp folder?

I'm no expert by any means. And always eager to learn.

lucy24

11:43 pm on Dec 24, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Since the page URL's have underscores, and or hyphens and they are ranking highly, I do not want to run the ratings, and links to those pages.

But you'll be changing the URLs anyway, since you're redirecting for two other reasons: the extension change and the added directory. In fact, will any pages be staying behind in the root? Or in other directories that were there all along? (Other directories is not a problem. Non-page content is not a problem. Pages that are staying in the root can be messy.)

Now, here's the complication: I assume you've got the WP install in the directory you talked about. WP is built around mod_rewrite, which does not inherit in the normal way. (By default it doesn't inherit at all. Even if you tell it to inherit, it does so in a "two steps forward, one back" system ... which come to think of it seems to be a hallmark of mod_rewrite in other respects too.) Are you on Apache 2.2 or 2.4? Apache 2.4 has a wider range of inheritance options and possibly different defaults, but hasn't been very widely adopted on shared hosting.

Without the WP complication, going to extensionless and adding a directory would be a simple matter of
RewriteRule ^([\w-]+)\.php http://www.example.com/newdir/$1 [R=301,L]
...
RewriteRule ^(newdir/[^.]+)$ /$1.php [L]
in that order, in the same root-level htaccess file. External redirect to intercept requests for old-style URL and redirect them to new URL; internal rewrite to serve content from new page. In WP, the second rule would not need to exist at all, because WP would take care of it. This may sound good, but the problem is that the first rule might not execute either, thanks to the two different htaccess files, and then where are you?

Word Press will not accept a page with a .php extension.

What do you mean by "will not accept"? Didn't WP start out with nothing but long messy URLs in ".php" with a query string, and then all the pretty-URL stuff came along later? Surely there's a plugin. There's always a plugin. In fact, I recommend that you mosey over next door to the WordPress subforum, because I have a strong impression there is also a plugin that will camouflage the directory change. not2easy or someone like her will know. Although, ahem, possibly not today ;)

not2easy

2:12 am on Dec 25, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



WP already is rewriting URLs, the real WP name of a page like example.com/wp/weather-balloons might be example.com/wp/?p=28 and those ugly links are used invisibly for the internal workings for categories, tags, archives and such. It is translated on creation to use the permalink structure in the Settings. For that reason it is not something you want to mess with in rewriting URLs because it will only display a 404 error for every page. WP can only display URLs based on the permalink structure configured in its settings.

It makes sense to 301 the requests for existing URLs to their new WP equivalent, but it is better not to try to keep the same URL extension because of the way WP internally handles URLs. I hope I've explained it in a way that doesn't cause confusion.

Egbert Souse

2:11 pm on Dec 25, 2015 (gmt 0)

10+ Year Member



Thank you Lucy24.

Not2easy, some examples of extensions are:

control-diabetes-diagnose-prevent

dark-chocolate

cocoa-powder

stevioside

My URLs typically have descriptive keywords in them. So if I did the "301" without the .php then the URL would be different in that there is no .php if U understand you correctly. Is that right?

Lucy24 -
I added a page called example.com/my-great-page.php

Then I went into WordPress created a page called "my-great-page" with no .php extension.

Then I went into cPanel and use the "Redirects" to create a 301 to the wp.

This is what cPanel wrote in the .htaccess file

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^my\-great\-page\.php$ "https\:\/\/example\.com\/wp\/my\-great\-page" [R=301,L]

Is there a way to make this generic so it covers all pages rather than just a specific page?

As I said before, I am a neophyte at mod-rewrites :)

Thanks!

not2easy

3:32 pm on Dec 25, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Yes, those would be the new page names, but with a 301, any request for
example.com/dark-chocolate.php
would now be
example.com/wp/dark-chocolate

Extensionless URLs have been used to make more user friendly (more memorable or 'pretty') URLs for a long time now.

cPanel does a lot of things well, rule taxonomy is not one of them. The target URL does not normally need the escaping slashes cpanel added there and the condition is pretty broad. I would go with the solution lucy24 offered above to cover all page requests.

Egbert Souse

4:07 pm on Dec 25, 2015 (gmt 0)

10+ Year Member



Currently the server is using Apache 2.2.26

So I would just copy and paste the entire

RewriteRule ^([\w-]+)\.php http://www.example.com/newdir/$1 [R=301,L]
...
RewriteRule ^(newdir/[^.]+)$ /$1.php [L]


Or do I remove the "..."

And of course change the "example.com" to my actual domain
and /newdir/ to /wp/ (my WordPress directory)

I also need the 301 to cover if someone enters the "www.example.com" or just "example.com"

Thank you for your assistance and patience with me :)

not2easy

4:53 pm on Dec 25, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



This rule is separate from your domain canonical rule for the www/non-www 301 and you don't need the "..." part, I think that was added to separate the two rules here. That first rule is to capture all URLs with lowlines and/or hyphens though it looks to me like it will add on the .php for the new URL (though I don't read these things as accurately as lucy24 who breathes regex).

You are using one htaccess file in the root directory, correct? In a previous post I saw "two htaccess files" mentioned, but there should be only one in the root normally. You also mention using a cart - is that in a separate directory I hope? You don't want to capture URLs for the cart in this rule to add /wp/ to the URLs.

Egbert Souse

5:27 pm on Dec 25, 2015 (gmt 0)

10+ Year Member



not2easy - Thank you for your reply.

The cart is in a separate folder /cart/
Unfortunately CubeCart does not integrate into WP like some of the others. Fortunately CubeCart is free with and does everything I want it to :)

I was using OS Commerce before and that was in a separate folder/directory /cart/ Those pages did not have a high ranking, so I really don't care about changing the entire URL for them which I already did.

It's just the main pages that were at root and are now being transferred to the wp folder/directory.

And yes, just one htaccess folder in the root

If I understand what lucy24 gave me
the first redirect removes the .php from all pages
and
the second redirect, redirects the pages to the "new" directory (whatever I call it) which in my case is wp.

Is my understanding correct?

Thank you for your kind assistance!

lucy24

8:27 pm on Dec 25, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



This is what cPanel wrote in the .htaccess file

RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^my\-great\-page\.php$ "https\:\/\/example\.com\/wp\/my\-great\-page" [R=301,L]
Oh, great. Now I know for a fact that cPanel is a ### idiot.
#1 hyphens never need to be escaped except--sometimes--inside grouping brackets.
#2 colons never need to be escaped anywhere
#3 slashes only need to be escaped if the RegEx engine uses / / to delimit Regular Expressions, which does not apply to mod_rewrite
#4 NOTHING in a target needs to be escaped, ever.

Grrr.

Or do I remove the "..."

Haha, the ... is not part of the ruleset, in fact it would crash your server. (That is, create a 500-class error.) I just meant: the first rule goes in one place, the second rule goes in another place. At an absolute minimum, the two would be separated by your domain-name-canonicalization redirect, which is typically your last external redirect. But remember that this whole post was hypothetical. Things are different when you throw WP into the mix, because now you've got two different htaccess files using mod_rewrite, and trying to figure out the inheritance is giving me a headache. (Apache 2.2 is good in this case, because I'm more familiar with it.)

Uhm. Maybe I should read the last 24 hours of posts before I say anything more. If not2easy-- who, unlike me, speaks WordPress-- has already answered everything, I can go back to YouTube ;)

lucy24

8:35 pm on Dec 25, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



:: elapsed time here ::

Oh, wait. Your htaccess file is in the root? So the /wp/ directory is for your WordPress (or other CMS) URLs, but it's not a real, physical directory that contains an htaccess of your own?

Please clarify, because if I misunderstood, then things are a lot simpler than I thought.

:: vague notion that the foregoing is a fairly general truth in my case ::

Egbert Souse

9:32 pm on Dec 25, 2015 (gmt 0)

10+ Year Member



Hi lucy24
my example.com has the .htaccess
then there is a sub folder/sub directory
example.com/wp/

RE: Cpanel - maybe that is why I got errors before when I tried the cPanel individual page redirect :)

I removed the elipse (...) :)

lucy24

10:24 pm on Dec 25, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Oh, and I forgot
RewriteCond %{HTTP_HOST} ^.*$
#5 if the Condition will always succeed ("host is anything or nothing") and does not involve a capture, it is not needed at all.

If there is only one htaccess, you can go back over my previous posts and mentally delete all the "you could do this if not for X" phrases, since the "if not" parts don't apply after all.

Order of mod_rewrite when there is a CMS involved:

RewriteEngine on
{all your own RewriteRules with [F] flag, if any}
{all your RewriteRules with 301 flag, if any}
{domain-name-canonicalization redirect as the last 301 rule}
{all your own RewriteRules with [L] flag only, if any}
{CMS section, probably beginning and ending with comment lines like "# begin WordPress" and including a further "RewriteEngine on" which is superfluous but does no harm }

If you choose to redirect, make sure your rules are set up so everything happens at once; see earlier example involving .php in the pattern and /newdir/ in the target. Note however that you can achieve the same result, without any external redirects, with the single line
RewriteRule ^([\w-]+)\.php /wp/$1 [L]

You're then keeping your established URLs but your CMS won't know the difference.

Note also that since you are using WP-or-whatever, not your own rewrite, you o not use the second rule at all-- the one ending in $1.php for rewriting extensionless URLs --because WP-or-whatever will take care of it.

Wait, wait, come back. One more question that didn't get answered, unless I overlooked it: Will any of your root-level URLs (example.com/blahblah.php) not get redirected? That potentially includes your own error documents if they happen to end in php.

not2easy

10:30 pm on Dec 25, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



To clarify the typical WP setup - it is in a real directory or in root, but the .htaccess is in the root. The location shown in URLs can be root or the name of the directory it is installed in. That part- what the URLs show- is set in the Admin/Settings page of the WP interface. It is why rewrites can often give surprising results when WP is involved.
The rewrites in this case are only inserting /wp/ and existing page names (minus .php extension) for existing pages currently in the root directory.

You'll want to be sure that the WP snippet that it put in your htaccess fie is at the end of other rewrite rules, this new rule should come before the www/non-www rewrite, then the WP thing.

Egbert Souse

1:11 am on Dec 26, 2015 (gmt 0)

10+ Year Member



OK now I'm totally confused.

Note however that you can achieve the same result, without any external redirects, with the single line


So does that mean I can use
RewriteRule ^([\w-]+)\.php /wp/$1 [L]

in lieu of
RewriteRule ^([\w-]+)\.php http://www.emperorsherbologist.com/wp/$1 [R=301,L]

RewriteRule ^(newdir/[^.]+)$ /$1.php [L]


Would I start the command like this?
RewriteEngine On 
RewriteCond %{HTTP_HOST} ^.*$


So the whole thing -- assuming it would be one line to do the actual rewrite would be
# BEGIN strip out php and then rewrite to /wp/
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^([\w-]+)\.php /wp/$1 [L]
# END strip out php and then rewrite to /wp/

If that is correct, then I could set my .htaccess file like this?

<Files .htaccess>
order allow,deny
deny from all
</Files>
<Limit PUT DELETE>
order deny,allow
deny from all
</Limit>

# Force redirect to https top level
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# End top level redirect

# BEGIN HTTPS Redirection Plugin
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# END HTTPS Redirection Plugin

# BEGIN strip out php and then rewrite to /wp/
RewriteEngine On
RewriteCond %{HTTP_HOST} ^.*$
RewriteRule ^([\w-]+)\.php /wp/$1 [L,R=301]
# END strip out php and then rewrite to /wp/

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

# END WordPress


Or did I screw this up and add redundancies and creat eother issues for myself?
(They told me I was good for nothing, but i'm really good at screwing things up :) )

I did add a SSL to the site so I'm forcing non SSL pages to SSL wiht the 301 so they will be permanent.

One more question that didn't get answered, unless I overlooked it: Will any of your root-level URLs (example.com/blahblah.php) not get redirected? That potentially includes your own error documents if they happen to end in php.


Every page with an extension of .php in root will be redirected to the /wp/ folder/directory

To clarify the typical WP setup - it is in a real directory or in root, but the .htaccess is in the root


The WP set up is a subdirectory of root

For example the structure in /public_html
.htaccess
my old .php files
a folder for wp
a folder for the shopping cart

Thank you lucy24 and not2easy I really appreciate your help and guidance!

lucy24

5:34 am on Dec 26, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



So does that mean I can use

Before you touch anything, make a decision: whether to change your visible URLs or not.

If you want to change the URLs, then you redirect using something like this (before the WP section of your htaccess):
RewriteRule ^([\w-]+)\.php http://example.com/wp/$1 [R=301,L]
If you want to keep the existing URLs, you rewrite using something like this (also before the WP section, but after any 301 redirects you might happen to have):
RewriteRule ^([\w-]+)\.php /wp/$1 [L]

Either way, your WP directory will receive the input
/wp/blahblah
and will handle it in exactly the same way. The only difference is what the user sees, assuming they even bother to look up at their browser's address bar.

Wait, one more thing. What about requests for the root? Is the physical file for your front page currently called "index.php" or does it have some other extension? Sure, it's theoretically possible to redirect the root along with everything else, but it looks a little weird to have no "example.com/" page.

Edit:
RewriteEngine On 
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
Oh, criminy, where did that come from? Get rid of it. If you need to redirect to https, we'll talk about that later.

Would I start the command like this?
RewriteEngine On 
RewriteCond %{HTTP_HOST} ^.*$
You do not need this condition at all, ever. Maybe cPanel thinks you have multiple domains passing through the same htaccess and the same group of RewriteRules?

The statement "RewriteEngine on" needs to be present before any RewriteRules. You only need to say it once. You will actually be saying it twice, but that's only because it's part of the WP boilerplate, which you should leave as-is.

Egbert Souse

2:15 pm on Dec 26, 2015 (gmt 0)

10+ Year Member



My decision is to have the URL's permanently redirected and looking the same as they currently do

So If I understand you correctly, I would use this line and put it in front of the WP section in my htaccess
RewriteRule ^([\w-]+)\.php /wp/$1 [L]

Then the pages will redirect:
https://example.com/my-great.page.php
is permanently redirected and looks like:
https://example.com/wp/my-great-page/

To get it permanently redirected, don't I need to add the R=301 right after the L ?

Maybe cPanel thinks you have multiple domains passing through the same htaccess and the same group of RewriteRules?

Actually, I do have some parked domains that point to example.com

And I will remove this

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) [%{HTTP_HOST}%{REQUEST_URI}...] [R=301,L]


From the htaccess file

Thank You in Advance.

lucy24

8:15 pm on Dec 26, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



My decision is to have the URL's permanently redirected and looking the same as they currently do

If they're redirected, they will not look the same. That's what "redirect" means. See the two very similar rules at the beginning of my preceding post. One's an external redirect; the other is an internal rewrite.

Egbert Souse

2:57 pm on Dec 27, 2015 (gmt 0)

10+ Year Member



My Nomenclature is probably wrong, so I will describe what I want to do.

I want to be able to remove the old .php pages and have them replaced by the pages on a permanent basis

e.g.
https://example.com/my-great-page.php
becomes
https://example.com/wp/my-great-page

So when a visitor comes to my site, they got there by either clicking on a link in a search engine, from a bookmark, or possibly a link form another site (that will not change the link to the new URL I am using for that page) but will bring them to the new page.

When the search engines come back to index my site instead of indexing
https://example.com/my-great-page.php
they now index
https://example.com/wp/my-great-page
etc.

Is this a redirect or a rewrite?

If I understand correctly (after reading and re-reading everything so far) I would use
RewriteRule ^([\w-]+)\.php http://example.com/wp/$1 [R=301,L]


To do what I want the system to do. Is that correct?

lucy24

8:24 pm on Dec 27, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Is this a redirect or a rewrite?

That's a redirect. It's called RewriteRule because you're doing it in mod_rewrite, but the [R] flag makes it a redirect.
Is that correct?

Yup.

Egbert Souse

2:13 pm on Dec 28, 2015 (gmt 0)

10+ Year Member



Thank you for your help. I really appreciate it!

One more question.
Do I need to enter separate lines for www.example.com and example.com

RewriteRule ^([\w-]+)\.php http://example.com/wp/$1 [R=301,L]
RewriteRule ^([\w-]+)\.php http://www.example.com/wp/$1 [R=301,L]

To cover both instances, or will one
RewriteRule ^([\w-]+)\.php http://example.com/wp/$1 [R=301,L]
cover both instances?

lucy24

3:52 pm on Dec 28, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



The server doesn't even look at the hostname unless you tell it to in the Condition; by default it looks only at the path. Part of every redirect is specifying your own preferred hostname.

Egbert Souse

5:25 pm on Dec 28, 2015 (gmt 0)

10+ Year Member



So
RewriteRule ^([\w-]+)\.php http://example.com/wp/$1 [R=301,L]
would cover if someone entered the URL with or without the www then?

lucy24

11:31 pm on Dec 28, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Yes, exactly.

Egbert Souse

1:41 pm on Dec 29, 2015 (gmt 0)

10+ Year Member



Thank You lucy24.
Sorry for being so thick headed about this :)

Two last questions

1. Since I have some other domains pointing to example.com will anyone entering those domains get a 404?

2. Once this is implemented, can I delete the php pages in root?

And as Monty Python use to say
And now for something different


Very early on in this long thread :) You said
If you need to redirect to https, we'll talk about that later.


I do need to redirect to https. How would I do that?
I had:
RewriteEngine On 
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]


But I'm sure you have a more efficient and better way to do it.

lucy24 again I Thank You for your patience and assistance.

not2easy

2:29 pm on Dec 29, 2015 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



There is a current discussion on this topic here: [webmasterworld.com...] where your question is answered in good detail. :)

Egbert Souse

4:40 pm on Dec 29, 2015 (gmt 0)

10+ Year Member



Thank You reading that now :)

lucy24

6:45 pm on Dec 29, 2015 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Since I have some other domains pointing to example.com will anyone entering those domains get a 404?

Unfortunately no: they will get a 301 or a 200 depending on what was requested. The 301 of course is fine, because the target includes an explicit "example.com" so everyone will end up on the (literally) same page; the 200 is not so good. But Duplicate Content is a whole nother thread.

But wait! You've got a domain-name-canonicalization redirect, right? Or at least you will after you've finished reading that other thread ;) If the condition is expressed as a negative
!^(example\.com)?$
then anyone requesting a different hostname will also get redirected, even if the path was otherwise correct.