Until recently, Striderweb.com was made up of static HTML files except for the blog sections themselves. After a while, I decided I wanted to run the entire site off of WordPress, but to do that I realized that the existing pages would have issues until I had converted all of them by remaking them inside the WordPress hierarchy. (The “hard” .htm files would conflict with WordPress Pages that have a similar “virtual” location.)
After a bit of tinkering, I figured out that this could be fixed with a small change to the mod_rewrite section that WordPress puts into the site’s .htaccess file. As a happy side effect, this system also allows you to manually cache a particular page, such as if you are suddenly getting hammered by an Instalanche or a Digg link.
Open your site’s .htaccess and you should see the following, which was put there by WordPress:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Change it to this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}/index.htm !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . /index.php [L]
</IfModule>
# BEGIN WordPress
# END WordPress
With this modification to the basic WordPress .htaccess rewrite, you can now put a hard-coded file in a particular place in the hierarchy.
How Does it Work?
For an example, let’s look at this page in a typical WordPress site:
http://example.com/archives/123
With WordPress running the site, there is no actual folder called “archives”, and in turn no actual “123″ folder or file. WordPress is creating the pages on the fly as they are called. Normally, if you were to actually put a folder called “archives” in that location, WordPress would hand control over to the actual directory.
We, however, don’t want that. We want WordPress to relinquish control with /archives/123, but not with, say, /archives/122, or even just /archives.
Our new .htaccess code above changes how WordPress handles “real” directories. With the new code, it only gives up control if the directory in question contains a file named either “index.htm” or “index.php”
So, to manually override /archives/123, we create an “archives” directory at the root of the site. In “archives”, we create a “123″ folder; and inside that, we create either index.htm or index.php that contains the override page.
Note that the base /archive directory, and any other pages or posts within it (e.g. /archives/122), are still controlled as normal by WordPress.
Another part of the reason I did this was that I have a page on this site that is a demonstration of a CSS method, and I wanted the demo page to be an independent page not run by WordPress (specifically, not complicated by the WordPress template).
You can see it in action here:
http://striderweb.com/nerdaphernalia/webcraft/complexspiral/
Note that http://striderweb.com/nerdaphernalia/webcraft/ is still run normally by the WordPress install that runs the rest of Nerdaphernalia. If I wanted to, I could also make sub-pages of the “ComplexSpiral” page that are also run by WordPress.
You will also note that the “ComplexSpiral” page is listed in the Page listing created by WordPress. That is, the WordPress system knows that there’s a page there, even though it’s not running it. How did I do that? Quite simply, actually. I just made a page with the same address within WordPress — a “placeholder” of sorts. It doesn’t matter what’s in the placeholder page1, because we’ll never see it — it’s overridden by the hard-coded page we created. But it creates the entry within the WordPress system and thus we see a link to the page within the normal WordPress page listings.
(And yes, you could use it to override a particular post, too.)
There is one final step, and this is important: Be sure to change the permissions on your .htaccess file so that WordPress doesn’t overwrite it with the defaults.
Enjoy!
9 Comments
brill, good articles. thanks for thr .htaccess tips.
Yes, “brill” covers it. Thanks for spending the extra time to explain … so many really good plugins don’t share their voodoo … this serves as a real good working example, kinda like a tutorial.
p.s. I just grabbed your pull-quote plugin; it’s really lovely. (You gonna create a plugins category?
Ben — I’m trying (retroactively in some cases) to keep blog categories fairly broad. (Though I will probably be moving my plugins to a dedicated “WordPress” section instead of “Features”)
You can, however, pull up a page of just WordPress-related posts by clicking on the WordPress tag at the end of this post — in the “Filed Under” list. Looks kinda like this: WordPress. You can even get an RSS feed by tacking
/feed/to the end of the URL.Just one more thing I love about WordPress — great URL structure!
I think there’s something about the Category/Tag relationship I don’t understand. To my way of thinking, tags should be as though nested beneath category … so (making up an example here) Extension/WordPress should produce a different set than Extenxion/Firefox … I don’t think that happens at the moment.
I’m rushing right now, so forgive me if this is valueless to you, but it’s interesting:
There are 30ish top-level categories, each with a number of 2nd level categories, each with a number of 3rd level categories… when I add additional 3rd level categories, often they don’t show up in admin>manage>categories or on
the site itself, though they are in MySQ”
“Is there a limit” in the [WP-Pro] list
And yaa, that was a typo … my example shudda used Extension in both cases. *sigh*
This is good stuff! I’m having a similar .htaccess problem that maybe somebody here could help me with. I have the standard wordpress stuff shared above in my htaccess file and have also added the following:
RewriteEngine On
RewriteRule ^product/([0-9]+)/$ /product.php?sku=$1
I’m trying to be able to use product/1234 in the url string but still grab the sku number as a GET variable on my static (not controlled by wordpress) product.php page.
If I delete the wordpress stuff, my rewriterule works perfectly, but of course the rest of the site doesn’t because the wordpress directives are gone. But with the wordpress stuff in place my rewriterule doesn’t work. Any suggestions for me?
Ben — for my take on tags vs. categories, see this post.
I want to be able to modifiy the wordpress templates. I was told a while back all you had to do was make a .htaccess file and some information inside that file to be able to modifiy templates inside wordpress dashboard. What code do i need to accomplish this.
Jason –
The method described here completely overwrites a page with a static HTML page. I don’t think you can do it on WordPress.com.
If you mean modifying the template on an install you’re hosting yourself… just modify the template files!