Posts tagged ‘WordPress’

How to Cope with a Hacked Site

There’s been a lot of articles on this topic over the years (I even wrote one). But I’m going to tackle this from a different angle, one that I’m not used to: A non-technical one.

Fixing a website “hack” is actually a fairly heavy technical thing to do. Most bloggers are not webmasters. They are not really technical people. They’re probably people who simply purchased a web hosting account, maybe set up WordPress using a one-click install, and started blogging. In an ideal world, this sort of setup would be perfectly secure. The fact that it’s usually not is really a problem for web hosts to figure out.

But often I find that the emails/posts I see that read “help me my site was hacked what do I do” or similar don’t get a lot of help. There’s a reason for this. People who are asking this question are not usually the type of people who are technically capable of actually fixing the problem. Guiding somebody through this process is non-trivial. Frankly, it’s kind of a pain in the ass. So those of us capable of fixing such a site (and there are plenty) are reluctant to try to help and basically offer our services for free. The amount of work is high, the frustration is equally high, and there’s not a lot of benefit in it.

So, with that in mind..

Step One: Regain control of the site

By “control”, I basically mean to get the passwords back and change them. Tell your webhost to do it if you have to, and read this codex article on how to change your WordPress password even when you can’t get into WordPress. Also, change your web hosting account password, your FTP password, the database password… Any password you have even remotely related to your site: change it. Note that doing this will very likely break the site. That’s okay, down is down, and it would be better to be down than showing hacked spammy crap to the world.

And that’s another point: take the site down, immediately. Unexpected downtime sucks, but if you’re showing spam to the world, then Google is sure to notice. If you’re down for a time, then Google understands and can cope, but if you’re showing bad things, then Google will think you’re a bad person. And you don’t want that.

The idea here is to stop the bleeding. Until you do that, you haven’t done anything at all.

Step Two: Don’t do a damn thing else

Once you have the passwords and the site is offline, leave it like that.

Seriously, don’t erase anything, don’t restore from backup, don’t do anything until you do what follows next…

Anything you do at this point destroys vital information. I cannot stress this enough.

Step Three: Hire a technically competent person to fix it for you

If you know me, then you know I rarely recommend this sort of thing. I tend to offer technical knowledge and try to help people do-it-themselves. But hey, for some people, there are times when it’s just a hell of a lot to take in. Webserver security is a complex subject, with a lot of aspects to it. There is a lot of background knowledge you need to know.

If you’re reading this and you don’t know how a webserver works, or config files, or you don’t know arcane SQL commands, or you don’t understand how the PHP code connects to the database and uses templates to generate HTML, then trust me when I tell you that you are not going to fix your website. Not really. Sure, you could probably get it running again, but you can’t fix it to where it won’t get hacked again.

So, find a website tech person. Somebody who knows what they’re doing.

(BTW, not me. Seriously, I’ve got enough to do as is. Just don’t even ask.)

How, you ask? I dunno. Look on the googles. How do you find anybody to do anything? There’s several sites out there for offering short-term jobs to tech wizards. There is the WordPress Jobs site, but note that I said you need a website person, not necessarily a WordPress person. A lot of people who know WordPress don’t know websites and security… Although many of them do and this is not an indictment on the community, it’s more a recognition of the fact that working with servers and websites in general is not really the same thing as working with WordPress. WP knowledge is useful, but generic server admin experience is much, much better in this situation.

And yes, I said HIRE. Seriously, pay up. This is a lot of work that requires special knowledge. I know that a lot of people try to run their websites cheaply and such… Look here, if you’re paying less than $300 a year to run a website, then why bother? How serious are you about your website anyway? Quality web hosting should cost you more than that, hiring a specialist for a short term day-job is going to run you a fair amount of money. Expect that and don’t give him too much hassle about it. Feel free to try to argue on the price, but please don’t be insulting. Offering $50 to fix your site is unfair, as that’s less than an hour’s pay for most consultants, and you need one with special skills here. This is a minimum of a day’s work, probably longer if your site is at all complicated. Just getting it running again without doing everything that needs to be done is probably a 4 hour job. Sure, somebody can hack together a fix in half an hour, but do you ask your automotive guy to just throw the oil at the engine until it runs? Have some respect for the fact that knowledge and skill is valuable, in any profession.

Basically, here’s what the website guy will be doing, if he knows his business.

First, he’ll probably backup the site. This includes the files, the databases, any logs that are available, everything. The idea is to grab a copy of the whole blamed thing, as it stands. This is a “cover-your-ass” scenario; he’s going to be making large scale changes to the site, so having a backup is a good idea, even if it is a hacked one. The person will need all of the relevant passwords, but don’t give them out in advance. He’ll ask for what he needs from you.

Second, if you already have regular backups (please, start making regular backups… VaultPress is invaluable in this situation and can help the process out immensely), then he’ll probably want to restore to a backup from before the hack. And yes, you very likely WILL lose content in this restoration. However, since there is a backup, the content can be recovered later, if it’s worth the trouble.

(Note, if you don’t have any backups, then he’ll try to remove the hack manually. This is error prone and difficult to do. It also takes longer and has a much lower chance of succeeding. It’s also difficult to know that you got everything out of the site. If anything is left behind, then the site can be re-hacked through hidden backdoors. This is why regular backups are critically important to have.)

Third, he’ll update everything to the latest versions and perform a security audit of the site. This means looking at all the plugins, themes, permissions on the files, the files themselves, everything. This is to make sure all the main security bases are covered and that it doesn’t get rehacked while he does the next step. They may talk about “hardening” the site.

Fourth, from that backup he made earlier, he’ll likely try to trace where the hack started from. Logs help here, as do the files themselves. This is kind of an art form. You’re looking at a static picture of a dynamic system. And unfortunately, he may not even be able to tell you what happened or how the attackers got in. Attackers often hide their traces, especially automated tools that do hacking of sites. With any luck, the basic upgrades to the system will be enough to prevent them getting in again, and a security audit by a knowing eye will eliminate the most common ways of attackers getting in. That often is enough.

Step Four: Prevention

Once your site is fixed, then you need to take steps to prevent it from happening again. The rules here are the same rules as any other technical system.

  • Regular backups. I can’t recommend VaultPress enough. After my site went offline for a day due to some issues with my webhost (not a hack), I lost some data. VaultPress had it and restoring it was easy. There’s other good backup solutions too, if you can’t afford $20 a month (seriously, don’t cheap out on your website folks!).
  • Security auditing. There’s some good plugins out there to do automatic scans of your site on a regular basis and warn you about changes. There’s good plugins to do security checks on your sites files. There’s good tools to check for issues that may be invisible to you. Use them, regularly. Or at least install them and let them run and warn you of possible threats.
  • Virus scanning. My website got hacked one time only. How? A trojan made it onto my computer and stole my FTP password, then an automated tool tied to that trojan tried to upload bad things to my site. It got stopped halfway (and I found and eliminated the trojan), but the point is that even tech-ninjas like me can slip up every once in a while. Have good security on your home computer as well.
  • Strong passwords. There is no longer any reason to use the same password everywhere. There is no longer any excuse for using a password that doesn’t look like total gibberish. Seriously, with recent hacks making this sort of thing obvious, everybody should be using a password storage solution. I tried several and settled on LastPass. Other people I know use 1Password. This sort of thing is a requirement for secure computing, and everybody should be using something like it.

These are some basic thoughts on the subject, and there’s probably others I haven’t considered. Security is an ever changing thing. The person you hire may make suggestions, and if they’re good ones, it may be worth retaining him for future work. If your site is valuable to you, then it may be worth it to invest in its future.

And yes, anybody can learn how to do this sort of thing. Probably on their own. The documentation is out there, the knowledge is freely available, and many tutorials exist. But sometimes you need to ask yourself, is this the right time for me to learn how to DIY? If you need quick action, then it might just be worth paying a pro.

Modified YOURLS Plugin

I got tired of waiting for a “proper” YOURLS WordPress plugin to come out, so I did it myself. Hey, I’ve got other stuff to do, and I needed a working shortlink solution.

Basically, this is the “YOURLS: WordPress to Twitter” plugin, with all the Twitter bits removed.

While I was in there, I also fixed the password saving bug that I kept having in Chrome (just cut out the submit button JS), switched it to eliminate the Pear_JSON package entirely (WordPress has JSON support built in already), and did some other minor things. I’m sure I missed some bits, but for the most part it was really just a hack and slash job. Eliminated about 30% of the plugin’s main code and all the ancillary Twitter libraries.

On a side note, this sort of thing only reinforces something I’ve said before: Plugins should only try to do one thing, and to do it well. Trying to have a twitter solution in this plugin when I didn’t want to use that bit at all basically just made it stop doing the shortlinks correctly. That’s a real problem when it’s really a shortlink plugin to begin with. I already had a really good twitter solution, trying to have all this extra crap in there just made it not work properly.

If I had more time, I’d also remove all the JS stuff on the settings page too. That’s not really necessary when you only have a few fields to enter. But I guess it works, sort of. Whatever. Not important.

Anyway, here you go. I won’t be putting this in the plugins repository, since it’s not really my code. But I am posting it here in case it helps anybody. And if Ozh changes his plugin to eliminate the Twitter stuff (or to at least make it optional without impacting functionality), then it would be worth switching to that in the future. I won’t be supporting this plugin anytime soon.

YOURLS – WordPress (no Twitter)

Edit: Note that I did this mainly because I wanted to use my own Simple Twitter Connect instead for posting items to Twitter. That works fine and uses the shortlink from this plugin fine. But the extra Twitter stuff in the original plugin interfered with it, and there was no good way to disable that stuff short of editing the plugin. I’m a fan of not editing other people’s plugins, but in this case there really wasn’t a lot of choice. YOURLS is a good system and I like using it, I just wish the WP plugin for it wasn’t trying to do so much. Just so you know. :)

Creating a WordPress site using SVN

While the WordPress upgrade system is great, sometimes people prefer to use command line tools or similar to manage their sites.

I hadn’t done this much until recently, but when I was at #wptybee, Matt asked me to set up a site using SVN externals. This turned out to be easier than expected, and a great way to keep a site up-to-date and easy to manage. So I thought I’d document the process a little bit here.

This is actually not an uncommon way of creating sites and maintaining them. I’d just never seen it documented anywhere before. If you know SVN, you probably already know how to do this.

Prerequisites

First, you’ll need to have a website on a host. Obviously.

You’ll also need shell access on that host. SSH will do fine.

Next, you’ll need that host to have SVN. Easy way to check: just run “svn –version” at the command line.

Finally, you’ll need an SVN server. A central place to store your files. Some hosts let you set these up easily. Sometimes you’ll have to set one up yourself. How to do this is slightly outside the scope of this article.

Create the SVN environment

The first thing you’ll want to do is to check out your SVN area into a directory on the machine. You can do this part on either your local machine, or on the server. I did it on my Windows 7 laptop, using TortoiseSVN.

The basic idea here is that this site will become your new public_html directory. Alternatively, you can make it a subdirectory under that and use .htaccess rules or any form of rewriting to change where the root of your website is. Regardless, the directory as a whole will be your main website directory.

SVN Externals

Now, we’re going to get WordPress installed into your SVN. To do that, we setup the WordPress SVN to be an external of the SVN root.

If you use TortoiseSVN, then you’re going to right click inside the root of your checkout, then select TortoiseSVN->Properties. In the dialog that follows, you’ll create a new property named “svn:externals” and give it a value of “wp http://core.svn.wordpress.org/trunk/“. Hit OK to make it stick (note, do not select the recursive option).

Note, if you’re using the command line, a guide on svn externals is here: http://beerpla.net/2009/06/20/how-to-properly-set-svn-svnexternals-property-in-svn-command-line/.

What this does is simple, really. It tells the SVN that the contents in the “wp” directory will come from http://core.svn.wordpress.org/trunk , which is the main trunk version of WordPress.

Alternatively, if you’re not brave enough to run trunk all the time, you could use http://core.svn.wordpress.org/branches/3.0, which would make it get the latest 3.0 version at all times (which is 3.0.4 right now). And if you wanted to use a directory name other than “wp”, you could change that as well.

The point being that instead of having to manually update WordPress, you’re telling your SVN server that the contents there actually come from another SVN server. So when you do an “update”, it will go and grab the latest version of WordPress directly, without having to updated by hand.

After you’ve modified the externals setting for that root directory, you have to do a commit, to send the new property to the SVN server. Then you can do an update and watch it go and grab a copy of WordPress and put it into your directory directly.

Custom Content

So now we have a WordPress setup, but it’s not installed. No worries, but we’re going to make a custom installation here, so we’ll hand edit the wp-config file eventually.

Why are we doing this? Well, we want our wp-content folder to live outside of the WordPress directory. It’s going to contain our custom plugins and themes and so forth. That way, no changes to WordPress’s files in their SVN can ever touch our own files.

So we need to make a folder in the root called “custom-content”. Or whatever you want to call it. Since this name will be visible in your HTML, you might want to choose a good one.

Now inside that folder, make a plugins and a themes directory. For the themes, you’re probably using a custom theme for your site, and you can just put it in there directly.

Plugins are a different matter.

Plugins as Externals

I assume that whatever plugins you are using are coming from the plugin repository. Or at least, some of them are. For your custom ones, you can do pretty much the same as the themes and just drop the plugins into your plugins directory. But for plugins from the repo, there’s a better way.

In much the same way as we made the wp directory an external pointer to the core WordPress SVN, we’re now going to do the same for our plugins.

So step one, choose a plugin you want. Let’s choose Akismet for a demo.

Step two, in your plugins directory, do the SVN Properties thing again, and this time, add this as an svn:externals of
akismet http://plugins.svn.wordpress.org/akismet/trunk/” to get the akismet trunk.

Step three, commit and update again, and voila, now you have Akismet.

But wait, we might want more than one plugin. Well, we can do that too. Let’s add the stats plugin.

Step one, go back to the SVN->Properties of the plugins directory.

Step two, edit the existing svn:externals setting. This time, we’re going to add “stats http://plugins.svn.wordpress.org/stats/branches/1.8/” on a new line. Basically, you can have as many externals you want, just be sure to put each one on a new line.

Step three, commit and update and it’ll download the stats plugin.

Repeat for all the plugins you want to keep up-to-date.

You’ll note that I used a branch of the stats plugin instead of the trunk. That’s because the trunk isn’t the latest version in the case of the stats plugin. Not every plugin author treats the trunk/tag/branch system the same, so you should investigate each plugin and see how they keep things up-to-date with their setup.

Theme note

Note that I am using a wholly custom theme, but you might not be. Maybe you’re using a child theme of twentyten. Themes exist inside an SVN too, and you can create externals to them in the same way.

For example, in the themes directory, you could set svn:externals to  ”twentyten http://themes.svn.wordpress.org/twentyten/1.1/” and get the twentyten theme for use. Any theme in the Themes directory should be available in this way.

Custom wp-config.php

Now we need to create our wp-config.php file. Grab a copy of the sample wp-config file and put it in the root. Yes, not in the wp directory. WordPress looks in both its own directory and in one directory above it, so having it in the root will still allow it to work and will keep the wp directory untouched.

Edit the file, and go ahead and add all the database details. Then add these lines:

define( 'WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'] . '/custom-content' );
define( 'WP_CONTENT_URL', 'http://example.com/custom-content');

You’ll need to use your own directory names and URL, of course. The purpose here is to tell WordPress that the wp-content directory isn’t the one to use anymore, but to use your custom content directory instead.

Special .htaccess

Because we’ve installed wp in a subdirectory off of what will be the root of the site, it would normally be referenced as http://example.com/wp/ which is undesirable. So I crafted some simple .htaccess rules to move the “root” of the site into the /wp directory, and still have everything work.

Options -Indexes
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/wp/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /wp/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ wp/index.php [L]

The Options -Indexes just turns off the normal Apache directory indexing. I don’t like it when people try to look through my files. :)

The rest basically rewrites any URLs for directories or files that don’t exist into calls to the /wp directory, without actually modifying the URL. The rewrite is internal, so the URL remains the same. This has the effect of moving the root to the /wp directory, but still allowing calls to the custom content directory to serve the right files.

After you’re done, save the file, and commit everything you’ve done so far.

Running it on the site

At this point, you should be capable of going to the site and loading up all that you’ve done onto it. So SSH in (or whatever) and do a checkout of your new SVN setup into the proper location for it. You may need to rename your existing public_html directory and/or set proper permissions on it and such.

If you’re setting up a new site, you’ll be able to go to it and have it create the database tables and such as well.

What’s the point?

Okay, so you may have read through all this and wondered what the point was. Well, it’s simple, really.

Go to your server, and do “svn up public_html”… and then watch as it proceeds to update the entire site. WordPress, plugins, themes, your custom files, everything on the site. The externals makes WordPress and the plugins and such all update directly from the WordPress SVN systems, allowing you to do one command to update them all.

If you didn’t use trunk, then updating is only slightly harder. Basically, you just change the externals to point to the new version, then commit and do an svn up.

In fact, if you want to live dangerously, you can hook everything to trunk and then have it automatically do an svn up every night. Not many people recommend running production sites on trunk, but for your own personal site, why not? You’ll always get access to the latest features. :)

An additional thing to keep in mind is that with a system like this, the files on the site are always backed up on the SVN server. For things like inline file uploads, you’ll need to log in every once in a while and do “svn add” and “svn commit” to send the new files to the SVN server, but for the most part, everything on the site will be in your SVN and you can work with it locally before sending it to the site proper.

And it’s expandable too. You can get your sites files from any host that has svn on it. You could run more than one webserver, and have them on a rotation or something. There’s a lot of possible configuration methods here.

It sure is a nice way to update though. :D

WP Quickie: Adding Chrome Voice Search

Saw this post about Chrome voice searching in HTML forms on Google’s blog today. Very cool, so I had to give it a try. If you check the “Search” box in the upper right corner of the page, you’ll see a little icon (if you’re using a dev version of Chrome). Click it to do a search-by-voice.

What I didn’t expect was how totally easy it is to implement. Seriously, it’s less than a line of code.

Example. Say your search box (possibly in your theme’s searchform.php file) looks like this:

<form id="searchform" action="<?php bloginfo('home'); ?>/" method="get">
<input id="s" name="s" size="20" type="text" value="<?php _e('Search') ?>..." />
</form>

All you have to do is to add some bits to the input element box. Specifically, you add x-webkit-speech speech onwebkitspeechchange=”this.form.submit();”. That’s it. Seriously:

<form id="searchform" action="<?php bloginfo('home'); ?>/" method="get">
<input id="s" name="s" size="20" type="text" value="<?php _e('Search') ?>..." x-webkit-speech speech onwebkitspeechchange="this.form.submit();" />
</form>

Note that this won’t validate, if you care about that sort of thing. Works fine though.

You can do a whole lot more with Javascript and events and translations and multiple choices and such, if you’re thinking of developing something cool with it. I’m just shocked and amazed that this is already in my browser and I had no idea it was there. Very cool.

WordPress 3.1 and XML-RPC


Every time I look through the beta of WordPress 3.1, I find something new. Today I found the WP_HTTP_IXR_Client. The IXR_Client was there in previous versions, but it didn’t use the WordPress HTTP API, and so it rarely worked for me. This wrapper/rework of it works like a charm. Some quick examples:

Testing the client to see if it can talk to another blog:

$client = new WP_HTTP_IXR_Client('http://example.com/xmlrpc.php');
$client->query('demo.sayHello');
echo $client->getResponse();

That will print “Hello!” if it succeeded.

Testing something with parameters, like adding two numbers:

$client = new WP_HTTP_IXR_Client('http://example.com/xmlrpc.php');
$client->query('demo.addTwoNumbers', 4, 5);
echo $client->getResponse();

That will produce an output of 9… Okay, let’s do something meaningful.

$client = new WP_HTTP_IXR_Client('http://example.com/xmlrpc.php');
$client->query('wp.getOptions', 0, 'username', 'password', 'software_version');
$response = $client->getResponse();
echo $response['software_version']['value'];

It returns what version of WordPress I’m running on that test site. In this case, that would be 3.1-beta2-17056.

Take a look through the class-wp-xmlrpc-server.php file for the various things you can do. Maybe you can think of some handy ways to make your blogs talk to each other. :)

How to Add Audio to WordPress Posts

Saw a few tweets by @lastraw today, asking Matt and others if they could make the Add Audio function in the WordPress editor work.

Well, @lastraw, the audio function does actually work, it just doesn’t do what you expect it to do.

Basically, the WordPress uploader does provide a few different kinds of uploader buttons: image, video, audio, and media. All of these buttons behave in different ways. The Audio button in particular lets you upload an audio file, and then insert a link to that file in your post.

WordPress upload buttons in the post editor

However, the link it inserts is just a bare link. This is because WordPress doesn’t come with a flash audio player, and HTML 5 hasn’t gotten standard enough to allow sane use of the <audio> tags.

Still, plugins can modify things to make audio files embed. I just wrote a quick plugin to take those bare audio links and turn them into embedded audio players using Google’s flash audio player. This is the same player they use on Google Voice and in several other locations in the Google-o-sphere.

Example:


Download MP3 file

How did I do that? Easy, I activated my plugin, then used the Add Audio button to just insert the plain link to my audio file (which I uploaded). Naturally, this audio player will only show up on your site. People reading through an RSS reader or some other method won’t see it, they’ll just see the plain audio link and can download the file.

Couple limitations on this: It only handles MP3 formats. You could conceivably use a player that could handle more formats, I only made this as an example. MP3 is the most common format in use anyway, and I didn’t want to go searching for a more complicated player to use. Also, I made it only handle links on lines by themselves. If you put an audio link inline into a paragraph or something, it won’t convert it.

Here’s the plugin code if you want to use it or modify it or whatever. It’s not the best code in the world, but then it only took 5 minutes to create, so what do you expect? ;)

<?php
/*
Plugin Name: Google MP3 Player
Plugin URI: http://ottodestruct.com/
Description: Turn MP3 links into an embedded audio player
Author: Otto
Version: 1.0
Author URI: http://ottodestruct.com
*/

add_filter ( 'the_content', 'googlemp3_embed' );
function googlemp3_embed($text) {
	// change links created by the add audio link system
	$text = preg_replace_callback ('#^(<p>)?<a.*href=[\'"](http://.*/.*\.mp3)[\'"].*>.*</a>(</p>|<br />)?#im', 'googlemp3_callback', $text);

	return $text;
}

function googlemp3_callback($match) {
	// edit width and height here
	$width = 400;
	$height = 27;
	return "{$match[1]}
<embed src='http://www.google.com/reader/ui/3523697345-audio-player.swf' flashvars='audioUrl={$match[2]}' width='{$width}' height='{$height}' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed><br />
<a href='{$match[2]}'>Download MP3 file</a>
{$match[3]}";
}

This is mainly intended as a demo. There’s more full featured plugins for this sort of thing in the plugins directory. If you need to embed audio, using one of them might be a better way to go.

Using YOURLS with WordPress

I recently acquired a short domain name, otto42.com (the otto.com domain is owned by a German company, and I use Otto42 as my alias a lot on sites as “Otto” is usually already taken). So I decided to use it to make my own URL shortener.

I looked at various methods for this, including simply writing my own (honestly, it ain’t that hard), but I wanted to see what was already available first.

First thing I looked at was the shortlinks system built into Google Apps. I’ve used it before, and it’s fairly nifty. They even have an API available for interfacing it to other things. And hey, the redirections would be served up by Google’s servers, which you can’t beat for reliability. Sadly, after screwing around with this for a while, and trying out some example code, I was totally unable to get their API to work. The whole thing is written in Python, which I have an intense dislike of (whitespace my ass!), and when trying to access the thing via direct calls, it gave me nothing but errors and annoyances.

So I searched around a bit more, and was relegated to building my own, when a tweet by @ozh mentioned that he’d put a blog up on yourls.org. This looked promising, as I know Ozh is active in WordPress, and so of course it would have a plugin. After investigating, I went with it. It works pretty well, actually.

How to do it

First thing I did was to point my short domain at a directory on my hosting account. If it’s going to run code, it needs to have a place to do it from. So I made a yourls directory and pointed the domain to it using my hosting control panel.

Next, I grabbed a copy of the yourls code and installed it there. 300+ files to FTP? Yikes. Complex. A quick bit of reading told me that it needed a database and a config file. Very similar to WordPress in this respect, except the config file resides in the includes subdirectory for some reason. Not so obvious, but whatever.

I toyed with the idea of using the same database for yourls that I already use for WordPress, but ended up creating another one for it. I’m now thinking that it might be worth merging them though, as that way, VaultPress would probably back up the yourls tables too.

After some hosting weirdness, the thing was up and running.

Plugin

Installing the WordPress plugin is a snap. Just find it in the Add New Plugin interface and hit install. After Network Activating it for all my sites, I went to configure it. I had to configure it on each site separately, but no big deal.

Configuration is fairly straightforward. Tell it URL of the API interface, give it my username and password, and voila. Worked first try.

There’s a bunch of Twitter stuff there as well which I only set up to make it stop bothering me about it. I don’t want this plugin to send out my tweets on new posts, as I already use my own Simple Twitter Connect for that. Still, it bugs you with an error message if you don’t set it up, so I did. Thankfully, there’s checkboxes to turn the autotweeting on and off, so I just leave these turned off. Honestly, I think this whole Twitter thing should be removed from the plugin, but I can understand the “easy” factor here for new users. Making them totally optional would be a nice enhancement though.

At first, I was confused because when I turned it on, I saw no way to make it back-populate my old posts into the shortener. Turns out I didn’t need to, it started doing it all by itself shortly afterwards. I think it actually does shortening on an on-demand basis, creating a shortlink whenever there isn’t one already there for a post.

The plugin also hooks into the Shortlink API, meaning that my Twitter plugin will automagically use the new shortlink. You can see that the shortlink box below this post has the otto42.com shortlink in it. I had to make zero changes to make that work. Isn’t interoperability fun?

One other thing I did have to do was to turn off the old wp.me shortlinks I used. These are provided by the WordPress.com Stats plugin, and there’s a checkbox in its options page to turn them off. No big deal.

Final thought

So yeah, if you have a short domain and want to make your own shortlinks, then YOURLS is a pretty good choice. I haven’t played with the stats gathering part of it yet, for the simple reason that I only just turned it on and thus have no stats to view. Still very easy to do, on the whole. Of course, if it could be entirely a WordPress plugin, then I might think it much cooler. :)

Update: There is a minor problem in the way the YOURLS plugin handles the WP Shortlink API. I’ve reported it upstream, hopefully it can be fixed soon. Still, it’s a minor issue. The workaround for now is to call wp_get_shortlink(get_the_ID()) when you want to get the shortlink for a post inside the Loop.

Heading to Savannah

If you don’t get immediate responses from me for the next few days, that’s probably because I’m not here. As you can tell from my new sidebar badge, I’ll be in Savannah, GA for WordCamp Savannah 2010. I’ll be around the SCAD River Club all of Saturday and Sunday, and also Friday (if they’ll let me hang out, I didn’t sign up for that). Looks like it’s going to be awesome, Jane has really pulled it together nicely.

I will be trying though, and the hotel claims to have internet, but this is going to be my first real road-trip for a WordCamp, so I’ll be mostly unavailable for quick answers like I know a lot of people are used to getting from me. Don’t worry, I will get to you. Eventually.

If you’re coming to Savannah, please make it a point to come and ask me anything you like. I’m looking forward to meeting people and getting to know the community better. My only meat-space connection with the WordPress community has actually been meeting (and working for) Matt, and he’s clearly a biased source. ;)

So enjoy your week, everybody! I know I will!

And I WILL be having dinner at the Crab Shack. This is a requirement.

Passing parameters from PHP to Javascripts in plugins

A while back, I wrote a post detailing why it was a bad idea to generate Javascripts using PHP in WordPress plugins. In that post, I mentioned a couple of better ways to do it.

At the time, I didn’t know about the third, and best way, to accomplish this. Mike’s comment over there reminded me of it. WordPress has it built in.

If you already know about wp_localize_script, you can stop reading now.

The wp_localize_script function was made in order to allow for WordPress translations to be able to also translate some of the JS files inside WordPress. Thus the name “localize”. The way it works is to load up the translated versions of text from the translation files and then include them into the resulting HTML output as a Javascript object. The scripts then use that object to produce any text output they need to produce.

Turns out that’s really similar to our goal of sending arbitrary parameters from WordPress to be used by Javascript code.

How to do it:

1. Make your script static (instead of generated) and enqueue your script as per normal. Example:

wp_enqueue_script('my-script','/path/to/whatever.js',…);

No real changes there. You’ll have to come back and modify your script to use these parameters it’s getting passed, but we’ll get to that in a minute.

2. Build an array of your parameters that you want to send to the script.

$params = array(
  'foo' => 'bar',
  'setting' => 123,
);

Note that my parameters are simple examples, but this is PHP code. You can get your parameters however you like. Such as get_option to pull them from the database, perhaps.

3. Call wp_localize_script and give your parameters a unique name.

wp_localize_script( 'my-script', 'MyScriptParams', $params );

What this will do is make WordPress output an inline script with your parameters (properly encoded) just before the enqueue outputs the script tag that loads your script in the first place. So then those parameters will be available to your script as an instance of an object with “MyScriptParams” (from my example).

This means that Javascript code can now reference them as attributes of the name you gave.

So, step 4. Modify your script to use those parameters. In my example, I used “MyScriptParams” and the parameter names are “foo” and “setting”. In my Javascript code I can use them as “MyScriptParams.foo” and “MyScriptParams.setting”.

Much cleaner. One static and unchanging JS file to cache. Parameters get put into your HTML itself as a one-liner. You can deal with the parameters using a normal PHP array before passing them over. No need to screw around with generating Javascript from PHP or looking for wp-load or even messing with tricky actions.

Perfect.

WordPress PROTIP: Child Themes

While this isn’t affecting a lot of people now, it will be in the future. Especially if you use well-supported themes.

Somewhere in version 2.8 or 2.9, WordPress started supporting Theme Updates. In the same way that it supports automatic plugin updates from the plugin repository, a theme developer can now make updates to their theme in the themes repository, and you can upgrade it directly from the WordPress interface.

This is a great thing. Theme developers can fix problems, add features, and have it easy for the users to get those changes right away.

Unfortunately, the theme has historically been the user’s playground. Themes are frequently modified by the user directly. Whether it be for looks or for adding code to be used by plugins or whatever, the theme you’re using is very probably not the theme you downloaded. So upgrading will blow away your changes. Thus, most people are disinclined to upgrade their themes.

The way to avoid this is with a child theme. Child themes derive from another theme, called the parent theme. A child theme, by default, looks exactly like the parent. Then you make your changes to the child, and those changes are used on the site. The parent remains untouched. So, when you upgrade the parent theme, the changes you made don’t go anywhere. They stay right where they are.

So let’s dive right in:

How to Make a Child Theme

First, obviously, install the parent theme. Take note of what directory name it goes into. You can find this on the Theme’s screen, it will tell you what directory each theme is in. The new default theme in 3.0 is “twentyten”. So let’s use that one as our parent.

Now, create a new directory in your /wp-content/themes directory. This is where we’ll put our child theme. Let’s call it “mytheme”.

In the mytheme directory, create a new style.css file. Put this in it:

/*
Theme Name: My Theme
Template: twentyten
*/
@import url('../twentyten/style.css');

Finally, load up WordPress and go activate your new “My Theme” theme. You’ll notice that WordPress tells you both what directory your child theme is in and what directory its parent is located in.

Now you’re running on a child theme. It doesn’t have any changes in it, so it looks exactly like the twentyten theme does, but still, we’re running it.

How to Change Things

Let’s say I wanted to change the color of the post titles to, say, green. A silly change, but it illustrates the point.

Normally, I’d go edit the theme, find wherever the color of the text is defined, and change it or add to it to make the titles change in the way I want. In this case, I do the same thing, but I modify the child theme, and I do it in a way that overrides the specificity of the parent’s CSS code.

To do this, I add this code to mytheme’s style.css file:

#content h2.entry-title a {
   color: green;
}

Why that change? Well, I looked at the parent theme and found that “#content .entry-title a” was what it used to define the color of the post title links. To override that, I need to be more specific.

Specificity is a difficult concept for some people, but basically it breaks down to this: When the browser is parsing the CSS, more specific rules take precedence over less specific rules.

In my case I needed to be more specific than “#content .entry-title a“. By adding the h2 to the .entry-title rule, I achieve that because h2.entry-title only will affect h2′s with the entry-title class, while just .entry-title can affect any tag on the page with that class.

The fact that only the h2′s on my page have .entry-title is irrelevant. The HTML doesn’t actually matter in regards to specificity. A rule is more specific based on what it can affect, not on what it actually affects.

So by making my rule more specific, I can override the color of those title’s in my own CSS file separately, and without changing anything about the parent theme.

Overriding Templates

Child themes are not limited to overriding only styling, although in many cases that may be the only customization you need. Best to stick with the rule of the minimum; try to make the most minimal change you can make to accomplish what you want to accomplish. But if you do want to change the way some of the templates work, you can do that too.

All you have to do is to copy the specific template file you want to alter from the parent theme into the child theme’s directory, then make your changes. The way WordPress works is when it looks for some template file, it looks in the child theme first, then it goes to the parent theme if the file it wants isn’t there.

Note that you’re not limited to overriding existing files in the parent. The entire Template Hierarchy applies to child themes too, so if you want to define a category.php file for Category Templates, and the parent theme doesn’t have that file, then you can create a new one in your child and it will be used. You will probably still want to start out with some existing template from the parent though, so look at the Template Hierarchy to see which template the parent is using for your case. The index.php is the usual suspect in these cases, so you can probably just copy that to the child theme and rename it to the template file you want it to be.

Overriding Functions

One exception to the overriding mechanism of child themes has to do with the functions.php file. In a child theme situation, both functions.php files from both themes are loaded. This is necessary because elements of your parent theme might require pieces of the functions.php file to be loaded. This can make overriding functions in the parent theme tricky unless it’s written to allow you to do just that.

The key to this is that the functions.php file of the child theme is loaded first. So if the parent theme is written in a manner WordPress calls “pluggable“, then you can override those functions.

In the twentyten theme’s functions.php file, several of the functions are defined like this:

if ( ! function_exists( 'twentyten_admin_header_style' ) ) :
function twentyten_admin_header_style() {
...
}
endif;

That is a pluggable function. Basically, before it defines the function, it checks to see if the function is already defined. If the parent theme uses this mechanism, then a child theme can override this function by simply defining a function of the same name first. So all you have to do to change it is to copy the function into your child’s functions.php file and make your changes. When the parent theme loads, it will see that you already defined the function and continue on.

Another way to override things is through the normal WordPress action and filter hook mechanisms. If a theme’s functions.php file uses those, then you can simply add your own hooked functions with different names. However, because the child’s functions.php file loads first, it can’t actually unhook things defined by the parent theme.

The way to get around this is to use the after_setup_theme action hook. This action is called immediately after both functions.php files are loaded.

For example, if I look at the twentyten theme, I’ll find this:

function twentyten_excerpt_length( $length ) {
	return 40;
}
add_filter( 'excerpt_length', 'twentyten_excerpt_length' );

I don’t want that, I want my excerpts to be 55 words instead. So I add this to my functions.php file:

function my_excerpt_length( $length ) {
	return 55;
}
add_filter( 'excerpt_length', 'my_excerpt_length' );

Whoops! It doesn’t work. Why not? Because I didn’t remove twentyten’s hook, and its filter is overriding mine. So I have to add this too:

function my_undo_hooks( $length ) {
	remove_filter( 'excerpt_length', 'twentyten_excerpt_length' );
}
add_action( 'after_setup_theme', 'my_undo_hooks' );

And then it works. I’ve added my filter, and removed the one in twentyten. Voila.

Programmer Note

In a WordPress theme you’ll often find references to “stylesheet_uri” and “stylesheet_dir”. You’ll also find references to “template_uri” and “template_dir”. Normally, these are the same thing. In a child theme case, they’re not. Stylesheet refers to the child theme. Template refers to the parent theme. This is an important distinction that you’ll want to make when creating your theme. You should probably use stylesheet in most cases, except for when you need to specifically refer to the parent (for image URL creation and such).

Conclusion

Child themes are a very good way to survive theme upgrades, and if you’re using a well supported theme, these are likely to become more common. It’s still perfectly safe to modify your theme directly (except for twentyten! Normal WP upgrades overwrite twentyten), but it’s always a good idea to keep your customizations separate. They’re a lot easier to manage that way.