WordPress's .htaccess file is suboptimal
-
The .htaccess file that WordPress generates during installation is suboptimal.
The primary issue is that, “out-of-the-box”, the .htaccess file functions properly only when the location of the WordPress installation does not change.
In a collaborative, version-controlled environment, it is unreasonable to expect that every developer places every WordPress project in his Web-server’s document root. However, the .htaccess file at the root of the installation seems to be generated with this expectation.
I hardly ever use WordPress, so I can’t speak to the evolution of this issue, but I seem to recall WordPress including the .htaccess file in the actual source package at some point in the past (as opposed to the file being generated dynamically during installation). If my recollection is correct, perhaps the fact that the file is generated dynamically now is in an effort to address the issue I’ve outlined herein.
The following issues are at the core of why clean-URLs are not accessible when the WordPress installation is not at the Web-server’s document root:
a.) the leading / before index.php in the last rule (
RewriteRule . /index.php [L]
); andb.) the
RewriteBase /
directiveAgain, I don’t know enough about WordPress to know whether the proposed adjustments will “break” other functionality, but it seems that two simple adjustments would alleviate this problem entirely.
# BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^index\.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] </IfModule> # END WordPress
With these two changes, I am able to move the WordPress installation to any subdirectory of the Web-server’s document root and clean URLs continue to function as expected.
As a related corollary, the above changes do not address the fact that WordPress stores core configuration directives in the database, so the developer will still need to adjust the ‘siteurl’ and ‘home’ values in the
wp_options
database table whenever the installation is moved.P.S. This forum software is inserting HTML markup into my post (specifically, between the code tags) whenever I edit the post.
-
The primary issue is that, “out-of-the-box”, the .htaccess file functions properly only when the location of the WordPress installation does not change.
…
a.) the leading / before index.php in the last rule (RewriteRule . /index.php [L]); and
b.) the RewriteBase / directive
Just for my own curiosity and nothing else, aside from any perceived inelegance, is there a tangible penalty for doing it the default way which is generated whenever you save your permalink settings?
I’m not suggesting you’re incorrect or that you shouldn’t modify your
.htaccess
file this way, I just want to know if there is any harm in the default method. ??Hi, Jan, thank you for the prompt and courteous reply. Rest assured that I am not “complaining”; quite the opposite. I hope to make WordPress a better platform and to alleviate some of the issues that developers (I know; not WordPress’s primary target audience, historically) face while working with version-controlled code and local copies of the WordPress installation.
Thanks for clarifying the important point that the .htaccess file is generated whenever the permalink settings are saved, and not during installation. This is a pleasant surprise.
That said, it is not possible even to log into WordPress, no less access the Permalink Settings, when the ‘sitehome’ and/or ‘home’ values, as defined on the
wp_options
table, are not accurate. This is a separate but related issue.In other words, whenever we “publish” a WordPress installation (that is, perform a “build” on our development server and copy the files into a staging environment and eventually production), we can’t log into WordPress at all. We have to go into the database and change the aforementioned option values manually before even being able to log-in.
So, to answer your question, no, there is no harm in letting WordPress generate the .htaccess file whenever the Permalink Settings are modified, but the values that are written to .htaccess appear to come directly from ‘siteurl’ and/or ‘home’, so unless those values are accurate, the .htaccess file will not be effective.
The following issues are at the core of why clean-URLs are not accessible when the WordPress installation is not at the Web-server’s document root:
a.) the leading / before index.php in the last rule (RewriteRule . /index.php [L]); and
b.) the RewriteBase / directive
You can get clean URLs with WP in non-root. I think I’m missing why you think this is a problem.
When WP isn’t in root, and you don’t want to run it ‘from’ root, like example.com/wp/, you just put the .htaccess in the /wp/ folder. That lets you have other apps on the server.
If you want it to be in root, you can change the rewrite base to /wp/ and it works fine.
Where are you seeing this being a problem?
When WP isn’t in root, and you don’t want to run it ‘from’ root, like example.com/wp/, you just put the .htaccess in the /wp/ folder.
This doesn’t work (unless the Permalinks Settings are updated to be accurate, in which the .htaccess file is updated accordingly). It works for the homepage, but clean-URL links to other pages yield 404 responses.
I have a WP installation at https://localhost/project (the fully-qualified path to WP’s index file is https://localhost/project/index.php). The WP files are stored in a “real” location on the filesystem, and relative to Apache’s document root, the path is /project (again, the index file is located at /project/index.php). So, this is precisely the setup that you describe, yet only the homepage is accessible.
If you want it to be in root, you can change the rewrite base to /wp/ and it works fine.
Are you addressing configurations in which WP is installed in the Web-server’s document root, but should be accessible at a different URL, e.g., /wp/? Or configurations in which WP is not installed in the Web-server’s document root, but should be accessible at the root URL (e.g., https://localhost/)?
In any case, the impetus behind my initial post was that I would like for WP installations to be “portable”. That is, I would like for a given WP installation to function identically whether it is installed at the Web-server’s document root or not, and whether the URL at which the WP installation is accessed is / or not. Further, I would like not to have to manipulate the database manually any time the FQDN for the WP site changes.
My gripe with having to manipulate the database manually has more to do with using WP in a collaborative development environment than anything else. In my organization, the WP database tables are version-controlled, so that each developer is working with the same data. The fact that WP stores critical URL-related data in the database means that each developer has to change the
siteurl
andhome
option values every time he updates his local working copy. (I realize that these values can be overwritten using WP’supdate_option()
function; more on that shortly.)I understand that my “ideal implementation” is not possible without some kind of a configuration file. WP already has
wp-config.php
, which seems like a far more appropriate location in which to store core/critical configuration directives (the WP installation’s fully-qualified URL falls into this category) than the database.In other words, I would prefer that WP store the
siteurl
andhome
values inwp-config.php
, as opposed to the database. If this were the case, our development woes would be solved, aswp-config.php
is added to each developer’s “ignore list” within his version-control client.To summarize, it seems that WP would be far more portable and better suited to collaborative development environments if:
1.) The proposed changes are made to .htaccess (provided that no security risks are introduced as a result); this would also eliminate the need to modify this file whenever the Permalinks Settings are changed.
2.) The
siteurl
andhome
are moved intowp-config.php
. Alternatively, the WP installation documentation is modified to include examples of how to overwrite the values in the database using inline definitions, e.g.:update_option('siteurl', https://localhost/project); update_option('home', https://localhost/project);
The latter option is less desirable, however, due to the associated overhead (writing to the DB every page-request). A possible improvement would be to wrap the above snippet in conditional logic such that the
update_option()
calls are not executed when the values in the DB already match those specified inline.This doesn’t work (unless the Permalinks Settings are updated to be accurate, in which the .htaccess file is updated accordingly). It works for the homepage, but clean-URL links to other pages yield 404 responses.
Huh?
If I install at https://example.com/wp/ all my URLs work just fine, no 404s.
Ditto if I install it in https://example.com/wp/ but use https://example.com/ as my front facing URL. All my posts will be https://example.com/2011/postname and so on.
I have a WP installation at https://localhost/project (the fully-qualified path to WP’s index file is https://localhost/project/index.php). The WP files are stored in a “real” location on the filesystem, and relative to Apache’s document root, the path is /project (again, the index file is located at /project/index.php). So, this is precisely the setup that you describe, yet only the homepage is accessible.
If that’s the case, you screwed something up. I have a WP install also at localhost/tester, and it works just fine. All my pretty permalinks work perfectly and they always have.
Also this statement is 100% incorrect:
this would also eliminate the need to modify this file whenever the Permalinks Settings are changed.
You never need to update the .htaccess when you change permalinks UNLESS you move to a new location. Swear to god. I don’t keep my .htaccess writable, and I often change my permalinks six ways from sunday while testing. Once I set it, .htaccess never changes. Otherwise debugging the multisite masses would be a nightmare! Yow!
I would like for a given WP installation to function identically whether it is installed at the Web-server’s document root or not, and whether the URL at which the WP installation is accessed is / or not.
That’s the thing, it DOES exactly that. Obviously the URLs are different, but that’s really how it works.
Further, I would like not to have to manipulate the database manually any time the FQDN for the WP site changes
That’s something else entirely and highly unlikely. Look at how WordPress stores links and images. They’re all using the full path. https://example.com/2012/postname
That’s not going to change.
In other words, I would prefer that WP store the siteurl and home values in wp-config.php, as opposed to the database.
See this:
https://codex.www.ads-software.com/Editing_wp-config.php#WordPress_address_.28URL.29In addition to what everybody else here is saying, don’t track your .htaccess file in version control. Those overrides are meant to be directory specific for that machine’s exact setup. For example, I don’t want the caching rules from W3TC coming down into my dev and test environments.
Also, learn to write a virtual host entry and use some more descriptive hostnames. You’ll save yourself a world of pain if you’re using similar names for production and dev (e.g. example.com and example.dev).
If I install at https://example.com/wp/ all my URLs work just fine, no 404s.
Ditto if I install it in https://example.com/wp/ but use https://example.com/ as my front facing URL. All my posts will be https://example.com/2011/postname and so on.
Right, you are installing WP to these locations. You are not installing it to another location and then attempting to get WP to function again when you move the installation to a completely different server that has a completely different FQDN and a different URL to the WP installation.
If that’s the case, you screwed something up. I have a WP install also at localhost/tester, and it works just fine. All my pretty permalinks work perfectly and they always have.
Again, you are installing WP to a specific location, so the values in the
wp_options
database table are accurate, and the values in your.htaccess
file are also accurate. Of course everything “just works”. I am talking about moving existing WP installations here.Also this statement is 100% incorrect:
this would also eliminate the need to modify this file whenever the Permalinks Settings are changed.
You misunderstood my statement. I am not talking about modifying the
.htaccess
file manually after changing Permalinks Settings. I am saying that WP’s internal logic would not have to modify the .htaccess file when Permalinks Settings are changed, as it does presently. Trust me, WP attempts to modify.htaccess
any time you click “Save” on the Permalinks Settings page (even if nothing is changed, if I recall). Jan stated this in his post above, I tested it, and he is correct.That’s the thing, it DOES exactly that. Obviously the URLs are different, but that’s really how it works.
Again, you are fundamentally misunderstanding the entire premise of this thread. I am not installing WP to a specific location and wondering why it doesn’t work. I am moving WP installations around and annoyed with the manual labor that is involved each time.
That’s something else entirely and highly unlikely. Look at how WordPress stores links and images. They’re all using the full path. https://example.com/2012/postname
That’s not going to change.
How is that URL not going to change if I migrate the WP installation from example.com to different-example.com? Of course all of the URLs are going to be different (and therefore the values in the DB need adjusting).
Andrea_r, thank link looks to address my concerns, in part if not in full. I will read through the information, digest it, and post back on Monday if I have any questions. Thank you.
John P. Bloch, by making the modifications I have described, the same
.htaccess
file works just fine for everyone on our development team who is working locally, despite different hostnames and WP paths, which is largely the point of my post.For example, I don’t want the caching rules from W3TC coming down into my dev and test environments.
Right, which is exactly why we don’t store those settings in a
.htaccess
file; we store them in Apache’s virtual-host configuration file for the virtual-host in question. There are plenty of reasons for this approach, not least of which is performance.Your statements seem somewhat contradictory; you suggest not keeping WP’s .htacess file in version-control, but at the same time suggest learning how to write a vhost entry (something with which I am perfectly familiar, by the way).
You are not installing it to another location and then attempting to get WP to function again when you move the installation to a completely different server that has a completely different FQDN and a different URL to the WP installation.
…
How is that URL not going to change if I migrate the WP installation from example.com to different-example.com?
…
Of course all of the URLs are going to be different (and therefore the values in the DB need adjusting).
Sorry, but the whole premise of your discussion is based upon Doing It All Wrong?.
WordPress is not an application that can be moved like that. Never has been. You can’t just pick up and move it and expect everything to work without massaging the database. Which even with or without your solution, you admit needs doing.
If you need to touch the database then do it (using one of) the right way as documented.
If you are developing a site and you want to move it to another server lock, stock, and barrel then it’s not difficult to do.
https://codex.www.ads-software.com/Moving_WordPress#When_Your_Domain_Name_or_URLs_Change
Which really does benefit from using this script.
https://interconnectit.com/124/search-and-replace-for-wordpress-databases/
It also requires that you have an understanding of permalinks, how URLs and references are stored in the database, options etc. and it works for both standalone WordPress as well as multisite.
works just fine for everyone on our development team who is working locally, despite different hostnames and WP paths, which is largely the point of my post.
If you are doing this and it works for you and your team, kudos.
But where do you address the links embedded in the posts, the media library, serialized settings, etc? That’s not something that an updated
.htaccess
will or can address.There’s a handy little plugin called MigrateDB
https://www.ads-software.com/extend/plugins/wp-migrate-db/
Just enter the new URLs and path to root and migrate the database!Sorry, but the whole premise of your discussion is based upon Doing It All Wrong?.
WordPress is not an application that can be moved like that. Never has been. You can’t just pick up and move it and expect everything to work without massaging the database. Which even with or without your solution, you admit needs doing.
Massaging the database directly is not necessary when the
update_option()
“hack” is used.If WP is not an application that can be moved like that, a) it should be, and b) I will not recommend it to clients. Why should WordPress be exempt from basic application design considerations, among the foremost of which is portability?
The first paragraph in the article you cited makes me shake my head:
The files and database can be moved, however references to the old domain name or location will remain in the database, and that can cause issues with links or theme display.
The fact that WP stores fully-qualified URLs anywhere in the database makes me cringe. I am curious to hear the rationale for this and in my humble opinion this was a poor design decision. Maybe I am just an ignorant boob with no knowledge of WP’s inner-workings and therefore entirely unqualified to offer my expertise.
Now, before everybody pig-piles on the “hater”, and defends every poor design decision blindly and without due discourse, consider the fact that there are plenty of other CMSs that do not store fully-qualified URLs in the database.
A more sensible approach is to use Web-server and filesystem path constants to define critical paths, and all paths on the filesystem and in the database are defined relative to those. The constants’ values do not affect so-called “clean-URLs”.
The Web-server constants define a protocol, a domain name, a port, and a base-path, and those four strings are sufficient to compose any URL necessary. When the domain or installation path changes, those are the only values that need adjustment. There’s no need to perform selective string replacements on an entire database. There are a number of ways to ensure that the URLs are composed accurately and in accordance with the defined constants when they are output.
Look, I’m not here to argue. I was under the impression that this is a request and feedback forum. I’m given you mine. Take it or leave it.
Thanks to those who provided alternatives and additional work-arounds.
Now, before everybody pig-piles on the “hater”
Nope, no worries, it’s all good. You are definitely not a “hater”. ??
Look, I’m not here to argue. I was under the impression that this is a request and feedback forum. I’m given you mine. Take it or leave it.
You’re in the right place and it’s feedback. Like I said, it’s all good.
There’s a comment by Otto on why WordPress uses absolute URLs. It’s not in the main post content, but down in the comments as a reply to someone who asked.
https://ottopress.com/2011/howto-html5-video-that-works-almost-everywhere/
If you really want to know, read this thread:
https://lists.automattic.com/pipermail/wp-hackers/2011-October/thread.html#41155
It’s long, it’s detailed, and that’s everything you need to know about why it’s done this way.
If WP is not an application that can be moved like that, a) it should be, and b) I will not recommend it to clients. Why should WordPress be exempt from basic application design considerations, among the foremost of which is portability?
a) No.
b) That’s your call. No one’s going to stop you, though it’d be nice if you’d read the above link first and see that the pros and cons have been fought over a hundred times before ?? There is a reason.
Thanks, Jan; I appreciate your willingness to acknowledge that criticism is not off-limits.
I read every single word of the thread you cited, Ipstenu.
For those who can’t be troubled, Marcus Pope has a long, drawn-out debate on this very subject with Otto (presumably some self-professed WP guru).
Marcus basically embarrasses Otto at every turn and reinforces everything that I’ve stated in this thread thus far. Rob Lusby jumps-in with poignant observations from time to time in support of Marcus’s position.
Having read every single post, it is fair to say that Marcus and Rob trampled Otto in a civil debate, and guess which position they took? They were in favor of relative URLs.
Otto really makes his position clear with this remark:
Yes, okay, you move sites around a lot. I get it. That’s great and
maybe your ideas help you. Fine.But most people *don’t* do that. Most people write content in order to
have that content read by other people. And your ideas make that a)
harder and b) broken. That’s what I’m trying to get across to you.
Your viewpoint is your own, and by far not the correct viewpoint for
the majority of people.That’s what I want you to see here. You think that relative URLs are
some kind of [expletive deleted] godsend idea, whereas I’m trying to tell you that
using relative URLs would *not work* for me or the majority of people
who aren’t building sites but are instead just publishing their
content.Aside from being hard-headed and simply incorrect on nearly every single front, Otto does a great job of alienating those who should constitute a significant portion of WP’s target audience: developers.
Elsewhere in the thread, Jonathan Bailey underscores the core of the debate:
And this is more like the crux of the issue. Is WordPress a platform for developing webapps or a platform for people to share blog entries? I’m starting to feel as if these things are diverging….
So, I guess that’s where we’ll leave it. Some people feel like WP is meant to be installed by an end-user who knows nothing about its inner-workings and never should. This end-user will never change domains and his content will live-on forever. To the contrary, some people feel like WP should be “developer-friendly” and lend itself well to the enterprise Web Software Development Life-Cycle.
Like Otto said, “[We] are welcome not to use WordPress,” and for projects of any size or import, we’ll do just that.
Cheers for the helpful suggestions, links to plug-ins, etc., and for entertaining the debate.
- The topic ‘WordPress's .htaccess file is suboptimal’ is closed to new replies.