Rewrite Rules

When editing RewriteRules, it’s important to remember this: rules which appear first tend to take priority. For instance, I discovered that the rules for http://schinckel.net/200_n_/page/_n_/ style URIs were missing. What was happening was the .htaccess file was finding the closest rule it could. The trick for finding what it’s actually doing under Blogsome is to have this code in your template:

1     {foreach from=$smarty.server.argv item=var}
2     {$var}
3     {/foreach}

This code will print out what the server is receiving. In the case of the URI: http://schinckel.net/2005/page/2/ it’s being sent:

wpblog=schinckel&year=2005&monthnum=&day=&name=page&page=2

The important part here is that the name of the post is being set to ‘page’. Clearly, this is not desired behaviour. The RewriteRule that should apply to this instance looks something like:

1     RewriteRule ^blogs/([_0-9a-z-]+)/([0-9]{4})/page/([0-9]+)/(.*)/    /wp-inst/index.php?wpblog=$1&year=$2&paged=$3 [L]

I don’t know exactly what the [L] stands for, but it needs to be there to stop Bad Server Errors™. The key thing to know here is that this must be before the greedy rule that was already grabbing the URL, and Rewriting it of its own accord. In my case, that was the line that looked like:

1     RewriteRule ^blogs/([_0-9a-z-]+)/([0-9]{4})/?([0-9]{1,2})?/?([0-9]{1,2})?/?([_0-9a-z-]+)?/?([0-9]+)?/?$          /wp-inst/index.php?wpblog=$1&year=$2&monthnum=$3&day=$4&name=$5&page=$6 [L]

I made sure my new rule was before this. A good place is where the other rules for subsequent pages of posts are. Of course, this rule only works for yearly archives, you’ll want one for monthly and daily archives (if you are a nutter who posts more times per day than fits onto your front page…):

1     RewriteRule ^blogs/([_0-9a-z-]+)/([0-9]{4})/([0-9]{1,2})/page/(.*)/    /wp-inst/index.php?wpblog=$1&year=$2&month=$3&paged=$4 [L] 
2     RewriteRule ^blogs/([_0-9a-z-]+)/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/page/(.*)/    /wp-inst/index.php?wpblog=$1&year=$2&month=$3&day=$4&paged=$5 [L]

Of course, on Blogsome, you cannot alter this file yourself, but I’m sure these changes will be implemented soon. If the link earlier in the post still gives you “No Posts Made”, then you know it hasn’t…

Simplest Spam Comment Killer

There are two main tasks that are required to implement a Comment Spam Protection system. The first is to disable comments for all people. The second is to enable it for people who legitimately want to comment. A very simple way to solve the first task is to remove the action from the form tag. In my template, the code looked like this:

1     <form action="{$siteurl}/wp-comments-post.php" method="post" 
2         id="commentform" name="commentform">
3     ...
4     </form>

(Obviously, I’ve removed most of the code for brevity.) Deleting the contents of the form action works to a certain extent, except it creates invalid code. Another option is to replace the action with another URI, such as http://www.google.com. The second task is to re-enable it where appropriate. Since most Spammers use an automated system of some sort to generate comments, and these bots don’t use JavaScript, we can just write a JavaScript that puts the right value back in. This will prevent a user who has JavaScript disabled, or who is in an old browser, from leaving a comment. I’m prepared to live with this. Anyway, I don’t usually add script tags directly into a page, but in this case I will, just to make it easier. After the close of the form tag, insert the following:

1     <script type="text/javascript">
2         document.forms[0].action="{$siteurl}/wp-comments-post.php";
3     </script>

Of course, if this isn’t the first form in your document, for example your search form appears in the source before this one, then you’ll need to change the number of forms[_x_] accordingly. You could try using document.getElementById("commentform").action, but I think there’s an issue with this method not being available until the DOM is complete, which it isn’t at this stage.