<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Xaprb &#187; mod_rewrite</title>
	<atom:link href="http://www.xaprb.com/blog/tag/mod_rewrite/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.xaprb.com/blog</link>
	<description>Stay curious!</description>
	<lastBuildDate>Wed, 17 Mar 2010 00:49:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Get Maatkit fast from the command line</title>
		<link>http://www.xaprb.com/blog/2008/05/21/get-maatkit-fast-command-line/</link>
		<comments>http://www.xaprb.com/blog/2008/05/21/get-maatkit-fast-command-line/#comments</comments>
		<pubDate>Wed, 21 May 2008 12:57:46 +0000</pubDate>
		<dc:creator>Xaprb</dc:creator>
				<category><![CDATA[Maatkit]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.xaprb.com/blog/2007/07/19/feedburner-stuff-plugins-to-install/</guid>
		<description><![CDATA[I have been using Maatkit in a different way since I joined Percona as a consultant.  When I&#8217;m working on a system now, it&#8217;s a new, unfamiliar system &#8212; not one where I have already installed my favorite programs.  And that means I want to grab my favorite productivity tools fast.

I intentionally wrote [...]


Related posts:<ol><li><a href='http://www.xaprb.com/blog/2009/03/25/mysql-command-line-tip-compare-result-sets/' rel='bookmark' title='Permanent Link: MySQL command-line tip: compare result sets'>MySQL command-line tip: compare result sets</a> <small>Here</small></li><li><a href='http://www.xaprb.com/blog/2010/03/16/try-mk-query-advisor-a-new-maatkit-tool/' rel='bookmark' title='Permanent Link: Try mk-query-advisor, a new Maatkit tool'>Try mk-query-advisor, a new Maatkit tool</a> <small>We have an</small></li><li><a href='http://www.xaprb.com/blog/2009/03/31/maatkit-version-3329-released/' rel='bookmark' title='Permanent Link: Maatkit version 3329 released'>Maatkit version 3329 released</a> <small>Maatkit ve</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>I have been using Maatkit in a different way since I joined <a href="http://www.percona.com/">Percona</a> as a consultant.  When I&#8217;m working on a system now, it&#8217;s a new, unfamiliar system &#8212; not one where I have already installed my favorite programs.  And that means I want to grab my favorite productivity tools fast.</p>

<p>I intentionally wrote the <a href="http://www.maatkit.org">Maatkit</a> tools so they don&#8217;t need to be &#8220;installed.&#8221;  You just run them, that&#8217;s all.  But I never made them easy to download.</p>

<p>I fixed that.  Now, at the command line, you can just run this:</p>

<pre>wget http://www.maatkit.org/get/mk-table-sync</pre>

<p>Now it&#8217;s ready to run.  Behind the scenes are some Apache mod_rewrite rules, a Perl script or two, and Subversion.  When you do this, you&#8217;re getting the latest code from Subversion&#8217;s trunk.[1][2]  (I like to run on the bleeding edge.  Releases are for people who want to install stuff.)</p>

<p>Because there&#8217;s some Perl magic behind it, I made it even easier &#8212; it does pattern-matching on partial names and Does The Right Thing:</p>

<pre>baron@kanga:~$ wget http://www.maatkit.org/get/sync
--21:38:50--  http://www.maatkit.org/get/sync
           =&gt; `sync'
Resolving www.maatkit.org... 64.130.10.15
Connecting to www.maatkit.org|64.130.10.15|:80... connected.
HTTP request sent, awaiting response... 302 Moved
Location: http://www.maatkit.org/get/mk-table-sync [following]
--21:38:50--  http://www.maatkit.org/get/mk-table-sync
           =&gt; `mk-table-sync'
Connecting to www.maatkit.org|64.130.10.15|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-perl]

    [      &lt;=&gt;                            ] 163,259      136.51K/s             

21:38:51 (136.13 KB/s) - `mk-table-sync' saved [163259]</pre>

<p>The redirection is there because otherwise wget will save the file under the name &#8217;sync&#8217; instead of &#8216;mk-table-sync&#8217;.</p>

<p>And if you&#8217;ve forgotten which tools exist, you can just click on over to <a href="http://www.maatkit.org/get/">http://www.maatkit.org/get/</a> and see.</p>

<p>A quick poll: instead of getting the latest trunk, should this give you the code from the last release?  I can do that, if you want.</p>

<p>[1] OK, it&#8217;s only refreshed every hour.  So you&#8217;re getting code that&#8217;s up to an hour old.</p>

<p>[2] <strong>update:</strong> now /get/foo gets the latest release, and /trunk/foo gets the latest trunk code.</p>

<p>Related posts:<ol><li><a href='http://www.xaprb.com/blog/2009/03/25/mysql-command-line-tip-compare-result-sets/' rel='bookmark' title='Permanent Link: MySQL command-line tip: compare result sets'>MySQL command-line tip: compare result sets</a> <small>Here</small></li><li><a href='http://www.xaprb.com/blog/2010/03/16/try-mk-query-advisor-a-new-maatkit-tool/' rel='bookmark' title='Permanent Link: Try mk-query-advisor, a new Maatkit tool'>Try mk-query-advisor, a new Maatkit tool</a> <small>We have an</small></li><li><a href='http://www.xaprb.com/blog/2009/03/31/maatkit-version-3329-released/' rel='bookmark' title='Permanent Link: Maatkit version 3329 released'>Maatkit version 3329 released</a> <small>Maatkit ve</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.xaprb.com/blog/2008/05/21/get-maatkit-fast-command-line/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to install and maintain multiple WordPress blogs easily</title>
		<link>http://www.xaprb.com/blog/2008/03/11/how-to-install-and-maintain-multiple-wordpress-blogs-easily/</link>
		<comments>http://www.xaprb.com/blog/2008/03/11/how-to-install-and-maintain-multiple-wordpress-blogs-easily/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 02:20:17 +0000</pubDate>
		<dc:creator>Xaprb</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[World Wide Web]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.xaprb.com/blog/2008/03/11/how-to-install-and-maintain-multiple-wordpress-blogs-easily/</guid>
		<description><![CDATA[<p>My wife has a site that needs two WordPress blog installations.  The URLs differ by a subdirectory name.  Both blogs need to be (URL-wise) subdirectories of /blog/.  They need to be completely independent of each other, yet use the same custom theme.  And there used to be just a single blog, which was <em>not</em> in a subdirectory; its permalinks must not break.  (It has nice URLs with the date and title in them, not post ID-style URLs).  And because I'm the husband, I get to maintain it, so tack "easy to maintain" onto the requirements  (it must be easy to upgrade WP in both blogs, for example).  In this article I'll show you how I did it with a single .htaccess file, a single copy of WordPress, two MySQL databases, and a single configuration file.</p>


Related posts:<ol><li><a href='http://www.xaprb.com/blog/2009/06/07/an-ongoing-thread-of-blogs-on-mysql-performance/' rel='bookmark' title='Permanent Link: An ongoing thread of blogs on MySQL performance'>An ongoing thread of blogs on MySQL performance</a> <small>In the las</small></li><li><a href='http://www.xaprb.com/blog/2009/08/09/how-to-round-to-the-nearest-whole-multiple-or-fraction-in-sql/' rel='bookmark' title='Permanent Link: How to round to the nearest whole multiple or fraction in SQL'>How to round to the nearest whole multiple or fraction in SQL</a> <small>Every once</small></li></ol>

Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>My wife has a site that needs two WordPress blog installations.  The URLs differ by a subdirectory name.  Both blogs need to be (URL-wise) subdirectories of /blog/.  They need to be completely independent of each other, yet use the same custom theme.  And there used to be just a single blog, which was <em>not</em> in a subdirectory; its permalinks must not break.  (It has nice URLs with the date and title in them, not post ID-style URLs).  And because I&#8217;m the husband, I get to maintain it, so tack &#8220;easy to maintain&#8221; onto the requirements  (it must be easy to upgrade WP in both blogs, for example).  In this article I&#8217;ll show you how I did it with a single .htaccess file, a single copy of WordPress, two MySQL databases, and a single configuration file.</p>

<h3>Fixing URLs</h3>

<p>As I mentioned, there used to be a blog at /blog/ which must not break.  Suppose this blog was about dogs and my wife has recently started blogging about cats.  She wants two completely independent blogs: /blog/dogs/ and /blog/cats/.  Now the old permalinks structure, e.g. /blog/2006/03/01/dogs-are-great/, must redirect to /blog/<strong>dogs/</strong>2006/03/01/dogs-are-great/.  How to do this?</p>

<p>I&#8217;m not a mod_rewrite wizard, but I figured there must be a way.  And indeed there is: if an incoming URL doesn&#8217;t contain dogs or cats, it can be rewritten and redirected to the new URL.  Here&#8217;s the code, which goes in /blog/.htaccess:</p>

<pre>
RewriteBase /blog/
RewriteCond %{REQUEST_URI} !dogs|cats
RewriteRule ^(.*)$ http://www.furryfriends.org/blog/dogs/$1 [R]
</pre>

<p>(By the way, the furryfriends thing is just an example, not the real site name).</p>

<p>So far, so good.  That works just fine: when I access a URL without dogs or cats in it, it redirects me.  But I need to do more: I need rewrite rules to match the date-and-title permalinks both blogs will use.  I accomplish that like so:</p>

<pre>
RewriteCond %{REQUEST_URI} dogs|cats
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (dogs|cats) /blog/$1/index.php [L]
</pre>

<p>This is basically the same thing WordPress usually does, but I&#8217;ve made it tolerate either dogs or cats and figure out which installation should get the request.  The .htaccess file lives in /blog/, not inside /dogs/ or /cats/ where it would be hard to maintain (it would get wiped out with upgrades).  I can see different ways of doing this, but this is the way I chose.  So here&#8217;s the whole file:</p>

<pre>
<IfModule mod_rewrite.c>
RewriteEngine On

# Anything to the old address (e.g. /blog/foo/bar) goes to the new address
# (e.g. /blog/dogs/foo/bar)
RewriteBase /blog/
RewriteCond %{REQUEST_URI} !dogs|cats
RewriteRule ^(.*)$ http://www.furryfriends.org/blog/dogs/$1 [R]

# If that fired, then we didn't reach this code.  If we did, then this rule
# should do what a normal WP rule does.
RewriteCond %{REQUEST_URI} dogs|cats
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (dogs|cats) /blog/$1/index.php [L]
</IfModule>
</pre>

<p>Are there any better ways of doing this?  I&#8217;m curious.  Leave a comment if you know of one.</p>

<h3>Fixing the maintenance headache</h3>

<p>Installing two copies of Wordpress, then customizing both is a pain.  And it makes upgrades harder, too.  I&#8217;d have to upgrade them both, fiddle with plugins (some of them are customized, too) etc etc.  Even backups would be more complicated.  It would be all too easy to screw up and delete some data.  There are just so many ways this is a bad idea.</p>

<p>It occurred to me that I could use a single copy and turn the dogs/ and cats/ subdirectories in the filesystem into symbolic links.  (Windows users, you can stop reading now: this won&#8217;t work for you).</p>

<p>To make the blogs, the Wordpress installation, and the custom blog theme all independent of each other, I created the following filesystem hierarchy:</p>

<pre>
blog/
   wordpress/
      2.3.2/
         [The usual WP files are here]
      wp_content/
         plugins/
         uploads/
         themes/
            my_custom_theme/
</pre>

<p>What I&#8217;ve done is separate the custom bits &#8212; the parts that don&#8217;t ship with WordPress &#8212; away from the files I want to upgrade when I upgrade Wordpress.  How will this work, though?</p>

<p>I&#8217;ll make symbolic links from the dogs/ and cats/ directories to the currently installed version of Wordpress.  So, from the root directory of the website, I type the following at the command line:</p>

<pre>
$ ln -s wordpress/2.3.2/ dogs
$ ln -s wordpress/2.3.2/ cats
$ cd wordpress/2.3.2/
$ rm -rf wp-content/
$ ln -s ../wp-content wp-content
</pre>

<p>The directory hierarchy now looks like this:

<pre>
blog/
   cats/ -&gt; wordpress/
   dogs/ -&gt; wordpress/
   wordpress/
      2.3.2/
         [The usual WP files are here]
         wp-content/ -&gt; ../wp-content
      wp_content/
         plugins/
         uploads/
         themes/
            my_custom_theme/
</pre>

<p>This is looking pretty good!  There&#8217;s only one minor detail missing: because both blogs are running literally the same code via the magic of symlinks, each blog is trying to access the same database tables.  I need to customize the Wordpress configuration file, too.  I&#8217;ll just give each installation a different table name prefix in wp-config.php:

<pre>
$table_prefix  = strpos($_SERVER['REQUEST_URI'], 'blog/cats/') ? 'wp_cats_' : 'wp_dogs';
</pre>

<p>And voila, it works perfectly now.  I accessed the two URLs, ran through the installation procedure twice, and have two completely independent blogs running the same code in the same database.</p>

<h3>The upgrade procedure</h3>

<p>So, this is all a little complicated, right?  What if I&#8217;ve forgotten how I did it when I upgrade next time, or what if someone else does it instead of me?  I wrote myself a little README file to fix this.  Here&#8217;s what it says:</p>

<pre>
This is how to upgrade Lynn's blog.

The two blogs are actually using shared files, which are symlinked to make
it so there is only one copy of files.  You can't change the files in one
without changing them in the other.

The wp-content subdirectory is symlinked.

The wp-config file is customized so it will work in either blog:

$table_prefix  = strpos($_SERVER['REQUEST_URI'], 'blog/cats/') ? 'wp_cats_' : 'wp_dogs';

To upgrade, 

 1. Download the latest version and unpack it inside wordpress/ as 2.3.2/
    or whatever version it is.
 2. Then go into that directory.
 3. Remove the wp-content/ directory completely.
 4. Then symlink it like this: ln -s ../wp-content wp-content
 5. Now re-customize wp-config.php
 6. Go back to the blog/ directory.  rm dogs cats
 7. ln -s wordpress/2.3.2/ dogs
 8. ln -s wordpress/2.3.2/ cats
</pre>

<p>It&#8217;s still a manual process, but it should take me all of thirty seconds.  I&#8217;m okay with that.  As long as I remember there&#8217;s a README file, that is!</p>

<p>Related posts:<ol><li><a href='http://www.xaprb.com/blog/2009/06/07/an-ongoing-thread-of-blogs-on-mysql-performance/' rel='bookmark' title='Permanent Link: An ongoing thread of blogs on MySQL performance'>An ongoing thread of blogs on MySQL performance</a> <small>In the las</small></li><li><a href='http://www.xaprb.com/blog/2009/08/09/how-to-round-to-the-nearest-whole-multiple-or-fraction-in-sql/' rel='bookmark' title='Permanent Link: How to round to the nearest whole multiple or fraction in SQL'>How to round to the nearest whole multiple or fraction in SQL</a> <small>Every once</small></li></ol></p>
<p>Related posts brought to you by <a href='http://mitcho.com/code/yarpp/'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://www.xaprb.com/blog/2008/03/11/how-to-install-and-maintain-multiple-wordpress-blogs-easily/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
	</channel>
</rss>
