Posts tagged as:

php

WordPress 2.5 & Bad Behavior 2.0.x

by Rick on March 25, 2008

If you are a Bad Behavior user, upgrade to version 2.0.14, and you won’t have to worry about WordPress 2.5 compatibility problems. Also on another note, if you have a high-traffic site, Bad Behavior may not be right for you. It might have been my imagination, but I noticed a slight increase in site responsiveness when I disabled Bad Behavior here back when I first learned it had issues with WordPress 2.5. (Additionally, FYI, I noticed a ginormous increase in site responsiveness when I disabled the Text Link Ads plugin!)

Bad Behavior in the Blogosphere

Like probably most early adopters and testers of the beautiful1 2.5 version for WordPress, I’ve had a lot of fun checking out what’s new, what’s different, and all of that.

I was particularly excited to try out the new interface for uploading media, which I didn’t have to wait long to do, due to the convention of having a graphic to head each post.

So I chose a picture and attempted to upload.

Then it happened; I apparently had killed the Intarwebs, and WordPress started complaining about “403 Forbidden” errors which neither carried with them any explanation or even showed up in my server’s error logs.

Crap, now what? So I trekked off to the WordPress testers mailing list and sought the help of the experts, and I was promptly taught the ways of tracking down media manager debug information by Andy Skelton (thanks again!).2

And I stared long and hard at that debug information. Something in that smattering of code and status information was the answer to my problem. I compared file requests, file names, and user-agents between the debug code and my server logs.

Then it occurred to me: the uploader is using the user-agent “Shockwave Flash”; could that be the problem?

I scanned the list of blocked user-agents active on my server — it wasn’t listed. Just to be safe, though, I removed the blocks and tried again. Still nothing.

Finally I decided to do what I should have done to begin with — deactivate all of my plugins and try again. So I did, and uploading worked! Hmm, a plugin was at fault the whole time, and it didn’t take much to narrow it down. Upon glancing at the list, I remembered that Bad Behavior3 had a user-agent blacklist.

So I opened up /wp-content/plugins/Bad-Behavior/bad-behavior/blacklist.inc.php and started scanning. Not too far down at all I came across this bit of code:

$bb2_spambots_0 = array(
[snip]
"PussyCat ",		// misc comment spam
"PycURL",		// misc comment spam
"Shockwave Flash",	// spam harvester
"TrackBack/",		// trackback spam
"user",			// suspicious harvester
[snip]
);

There it was!4 Removing the “Shockwave Flash” line allowed the new WordPress media manager to function properly.

Hopefully putting this out into the blogosphere will keep anyone else from re-sending to the Testers email or posting to a WordPress bug report about this issue. It’s an easy fix that anyone can do. :-)

  1. Specifically the new admin interface! []
  2. If you want to enable debugging in the media manager, open the file /wp-admin/includes/media.php, and replace debug: false with debug: true. Revisit the media manager to see the debugging in action; revert the change to turn debugging off again. []
  3. A great plugin for stopping possibly malicious users from ever even reaching your site. []
  4. The actual line # within the file was 41. []

{ 13 comments }

How to Optimize Page Titles in WordPress

by Rick on January 25, 2008

Mint

The following guide was developed using WordPress 2.3.2. Previous versions have not been tested.

As part of the recent redesign of this site, I looked into the subject of page titles — the content of HTML’s TITLE tags.

Previously, I was using a theme which output titles in this form: “Post at Site.” For example, a page title may have been, “How to Do This, That, and the Other at Foo’s Really Cool Bar.”

I had two problems with that.

First, the word “at” is extraneous; I should hope search engines ignore it as a minor word, but I would much rather have some form of punctuation or other symbol which unquestionably demarcates the post title and the site title. To deal in a hypothetical, imagine a blog named “Science at Home”; that blogger decides to write a post about an experiment which took place in his freezer, a post which he titles “Various Liquids at Sub-Freezing Temps.” Now put them together: “Various Liquids at Sub-Freezing Temps at Science at Home.”

I hope I’m not the only one who thinks such a title is less than great. We’re smart enough these days to distinguish “Article Titles” from Magazine Titles, so why not bring some clarity to the new media of blogging?

Second, when using Mint to track my stats, the pages that people visited would be organized based upon whatever was in the TITLE tags of the pages. That area of Mint’s stats very quickly looked cluttered with overly long titles containing useless information — it’s reasonable to assume that if you install Mint on “Science at Home,” the pages which are tracked will be part of “Science at Home.” We shouldn’t need Mint to tell us that. Resolving that became a priority as well.

In solving these issues, I came up with a nifty little function that can be added to your WordPress blog theme’s functions file. You’ll also need to edit your theme’s header.php file to take advantage of our new function.

  • Open and/or create the file functions.php in your theme’s folder. If you had to create the file, go ahead and add this content:

    <?php
    
    ?>
  • Next, you’ll need to add the following code, which is designed to put together what I consider to be a fairly optimal title. Various archives, page not found errors, pages, posts, and so on are all accounted for. If there is already content in the file aside from the tags added in the previous step, scroll all the way down. Now you’ll need to add the following code just before the closing ?> (keeping ?> on its own line at the end, of course).
    function title_construct($mint = false)
    {
    	$separator = ' — ';
    
    	if (is_home())
    	{
    		if ($mint)
    		{
    			echo 'Home page';
    		}
    		else
    		{
    			bloginfo('description');
    			echo $separator;
    			bloginfo('name');
    		}
    	}
    	elseif (is_404())
    	{
    		echo 'Content Not Found', $separator;
    		bloginfo('name');
    	}
    	else
    	{
    		// Page / Single post
    		if (is_page() || is_single())
    		{
    			if (have_posts())
    			{
    				echo trim(wp_title('', false));
    			}
    			else
    			{
    				echo 'Content Not Found';
    			}
    		}
    		// Category archive
    		elseif (is_category())
    		{
    			single_cat_title();
    			echo ' (category archive)';
    		}
    		// Tag archive
    		elseif (is_tag())
    		{
    			single_tag_title();
    			echo ' (tag archive)';
    		}
    		// General archive
    		elseif (is_archive())
    		{
    			wp_title('');
    			echo ' (archive)';
    		}
    		// Search results
    		elseif (is_search())
    		{
    			echo get_query_var('s'), ' (search results)';
    		}
    
    		if (!$mint)
    		{
    			if (!is_home() && !is_404())
    			{
    				echo $separator;
    			}
    			bloginfo('name');
    		}
    	}
    }

    That code is based off of the title-generating code in the header file of K2.

  • Save and upload the functions file; visiting your blog should confirm that nothing has broken, but it will also confirm that the above code does nothing. That’s because we haven’t actually called that function anywhere. So go ahead and open your theme’s header.php file.
  • Locate the TITLE tags; they look like <title>...</title>. What is actually between them will vary from theme to theme. However, what you will want to do is delete everything between the tags and add a call to our function which we defined just a bit ago. In other words, modify the TITLE tags so that they look like this and then save and upload that file:
  • You should now see a difference in how page titles are rendered when you visit your blog.

Excellent, you now have optimized titles which emphasize the title of the current page while still providing the site name as well as tertiary data such as “(tag archive)” or “(category archive).”

The above code can very easily be customized, too! For instance, I have it outputting “Content Not Found” in 404 situations. You can change that text to whatever you want (e.g., “HTTP 404″ or “Uh-oh, You Broke It!”). Likewise, the tertiary info mentioned in the previous paragraph is very much based upon my own tastes. You may prefer a tag archive to have a title of “Tagname Tag Archive,” in which case you’ll want to find and replace “(tag archive)” with “Tag Archive.” My theory is that by using the parenthetical form, the name of the tag itself will be further emphasized.

Moving along, you can take advantage of the title_construct() function in tracking stats with Mint as well. If you followed the Mint install instructions correctly, you should have a bit of code in header.php which follows the title of your site and looks similar to this: <script src="/mint/?js" type="text/javascript"></script>

It has been reported that you can override the title that Mint sees with a very brief bit of JavaScript, which is exactly what we’ll be doing here. Between the TITLE tags that we added title_construct() to above and the Mint JavaScript code, go ahead and add the following:

<script type="text/javascript">// <![CDATA[
	var Mint_SI_DocumentTitle = '<?php title_construct(true); ?>';
// ]]></script>

It is very important that the code appears after your page’s regular title but before the call to Mint’s JavaScript. If it appears anywhere else, you’re just wasting your time as Mint will not pick up on the code.

If you want a live example, go ahead and view the source of this page. I choose to keep most of my JavaScript in the footer of the page, so you’ll have to scroll nearly to the end to see the added code. Note that by adding the code to the footer, it’s definitely doing to be after the regular page title!

Once that code is added and you’ve saved and uploaded the header.php file, you should start seeing nicer titles appearing in your Mint stats; keep in mind, though, that it may take a while for old data to cycle through.

And yes, I know that there is a plugin available which allows you to specify custom titles for Mint. However, I didn’t want to go that route because it was a whole lot less “set it and forget it” than the above method is. The plugin only set custom titles for Mint on posts, and it only did that if a custom title was specified in the post’s custom fields. If that’s all you need, by all means go get the plugin! And I gotta admit, I’m impressed with how quickly the plugin was developed and released!

So anyway, that’s what I’m doing to get optimized titles around here. If you have any questions, recommendations, or concerns, feel free to drop a comment!

I’m pretty sure if you end a post title with a “\” you will break the JavaScript which sets a custom title for Mint; the ending “\” will escape right out of the apostrophes enclosing the custom title. That is bad. I’d appreciate any possible solutions to that problem, though I’d imagine ending a post title with a “\” is a rare enough occurrence for me to let it slide for the time being.

{ 0 comments }

How to Stop WordPress Comment Spam in Its Tracks

by Rick on January 24, 2008

Spam

I’m about to say one of the very few things I have ever posted here which probably every one of my (legitimate human) readers will be able to agree with:

Spam sucks!

And to be quite honest, I’m getting sick of it. I think a lot of people simply get sick of dealing with the spam, but it’s getting to the point that having to look at comment spam here and on the other blogs I maintain is sickening.

I log in to my spam filter knowing that there’s going to be at least some comments that need purging, but I do so hoping that they are of the variety, “Great blog post. Check my link. Happy Thursday,” and so on. At least those I can scan over and not feel as though my eyes need bleaching. Rarely are those the only bits of garbage in the can. It’s the large chunks of fetid, festering filth that have motivated me to think about better spam protection here on the blog.

And I wanted to do this with as little fuss as possible:

  • Plugins which simply send spam to the moderation queue are pointless here — I don’t want to have to deal with it at all; a moderation queue requires, well, some moderation in order to prevent spam (read: legitimate comments) from being blocked.
  • WordPress offers built in moderation and blacklist lists within which common spam words can be added. Comments which match something in the moderation list will be held for moderation, while comments which match anything in the blacklist will be deleted on the spot. I like this idea, but maintaining such a list has got to be a pain in the butt, and I can imagine all sorts of discussions — such as comments concerning anti-spam solutions — which may make use of any number of spam words. I don’t want to hurt legitimate users!

So what to do?

I’ve heard it mentioned many times before, and it suddenly started sounding like a good idea: simply rename the /wp-comments-post.php file to something else, and spam bots will no longer be able to post.

So that’s what I did. There was only one line of code which I had to change as well. In the /comments.php of my theme, I had to adjust the address for the commenting form. The bit of code that needed changed looked like this:

/wp-comments-post.php

So I edited that to match the new filename I had chosen, saved it, and uploaded. After a test comment to make sure everything was kosher, I breathed a sigh of relief, thinking everything would be smooth sailing — though I’d still receive trackback spam, I’m sure, but that’s another subject for another time.

Still the spam comes in. Evidently, spam bots are being more intelligently written; I checked my host’s access logs and noticed that the spammers are loading posts first and submitting the spam in a very legitimate looking way. That sucks.

Perhaps my change will slow the influx of spam. I can hope, right?

I’m curious if anyone else has any ingenious little antispam tweaks in place on their sites? It doesn’t have to be specific to WordPress; I don’t have access to my Apache httpd.conf, but I certainly can tweak around in .htaccess.

{ 8 comments }

How to Update Your WordPress Permalinks Without Causing Link Rot

by Rick on January 18, 2008

If you are changing your permalinks structure differently than what is described below (e.g., going from name-based permalinks back to name and date-based permalinks), there is a WordPress plugin that can take care of you. If all you want to do is change from name and date-based permalinks to name-based permalinks, the method described below should be a bit faster, as the redirect is handled at the server level rather than at the PHP level.

This is a follow-up to my earlier post Seamless Permalink Updating. The problem I faced was that I wanted to change my WordPress permalink settings from being date and name based to something which was simply name based.

Why did I want to do this?

  1. Permalinks would be shorter; removing the date information results in URIs which are eleven characters shorter.
  2. Permalinks would not only be more readable, they would be more meaningful to humans; dates aren’t as important as the content the page itself contains. If presented with a list of permalinks from this site, users should have a good idea of what they’ll get when they click them. There’s no reason to muddy those waters by injecting date information into the mix, diluting the impact of the domain and post slug.
  3. The content part of the permalinks (domain name + post slug) would carry more impact in various search engines, without date information (that may or may not be recognized as dates by search engine algorithms) diluting the value of whatever keywords may be present.
  4. Yes, this is a blog, and yes information is posted chronologically; however, this isn’t a novel, and the material here need not be read in a chronological manner in order to understand it. Having date-based permalinks creates the illusion that the date the material was posted is more important than it really is. Besides, posts are displayed with the date anyway; why give it to the user twice when I’m betting the date included with the post is glanced over by most users.

Great reasons, I think, which should suffice for now. So I wanted to change my permalinks; what did I do about it?

WordPress makes the process ridiculously simple.

  1. Visit the Permalinks page of the administration panel (/wp-admin/options-permalink.php).
  2. Select the button labeled “Custom, specify below.”
  3. In the box labeled “Custom structure,” enter the text /%postname%/
  4. Submit the change via the “Update Permalink Structure »” button.
  5. Visit your site and verify that posts are not being given permalinks in the style example.com/post-name-here/. Beautiful, no?

Like I said, ridiculously easy!

But consider: What happens to all the links out there on the Internet to your blog which make use of the previous style of permalinks? Try it out for yourself; find an old permalink in your browser’s history that still makes use of “Date and name based” permalinks and visit it.

404! You broke the Internet! File not found! It’s the end of the world as you know it!

But don’t worry, you can feel fine about it because I have a solution, provided that you are using Apache as your server environment (chances are, you are) and mod_alias is enabled (I’m unsure how common it is). We’ll be fixing our problem using the RedirectMatch directive of mod_alias.

  1. Download your blog’s primary .htaccess file; most likely, it’ll be in the same directory as your blog’s wp-config.php file.
  2. Open it up, and find WordPress’ permalinks code. If you’ve never edited your .htaccess file before, it will most likely be the only code present. The code looks like this, give or take a line break:

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    # END WordPress
  3. Before that WordPress code, you’ll want to add one of the following:
    • If your WordPress is installed in your domain’s root directory (e.g., example.com/wp-config.php), add this code, adjusting example.com to your proper domain name:

      RedirectMatch permanent ^/[0-9]{4}/[0-9]{2}/[0-9]{2}/([a-z0-9\-/]+) http://example.com/$1
    • If your WordPress is installed in a subdirectory of your domain (e.g., example.com/blog/wp-config.php), add this code, adjusting example.com/blog to your proper domain name and directory:

      RedirectMatch permanent /blog/[0-9]{4}/[0-9]{2}/[0-9]{2}/([a-z0-9\-/]+) http://example.com/blog/$1
  4. Save & upload the .htaccess file, and revisit one of your older date-based permalinks. If all went according to plan, you should be seamlessly redirected to your new name-based permalinks.

That’s all there is to it! If anyone can provide a better means, I’m open to it, but I’ve tested this out, and it works exactly as I want it to — posts work, paged posts work, pages work, and so on. I can’t promise this won’t break any WordPress plugins, so be prepared to give up this method (which is as easy as deleting whatever you add to .htaccess and switching your permalink structure back).

For the curious, this is what the code above does, piece by piece:

RedirectMatch
Begins the call to Apache’s mod_alias module.
permanent
Sends the client (i.e., the user, whether human or robot) instruction that this redirect is a permanent redirect and that the old address is invalid and should be from now on replaced with the new.
^/[0-9]{4}
The address which we’re trying to match begins with a four-digit year stamp, so we first look for a slash followed by four numbers.
/[0-9]{2}
The address will next have a two-digit month stamp, so we check for another slash followed by two numbers.
/[0-9]{2}
The address will next have a two-digit day stamp, so we check for yet another slash followed again by two numbers.
/([a-z0-9\-/]*)
The address will then have the post slug, which can consist of a variety of lowercase letters, numbers, and dashes. So we look for any number of those. A post slug may include additional information after it, such as a page number on paged posts, so we include any number of slashes in our search as well. It’s enclosed in parentheses so we can capture that data and use it in the next section.
http://example.com/$1
This is the location of where we want to redirect to. The $1 at the end will be replaced by whatever was matched by the code in parentheses in the previous statement.

Edit: Whoops! Using the above RedirectMatch code prevented viewing of day archives (e.g., /2008/01/01/); swapping the asterisk (*) out for a plus sign (+) resolved the issue and allows day archives to be viewed. The code above has been corrected.

{ 22 comments }