get_template_part_content for Single Posts

I’ve been looking for a non-intrusive way to insert text before any of my WordPress Single Posts and Pages. In the past, I modified the themes directly, but since I didn’t own the themes I was using, anytime I updated the theme, I would lose all my changes.

I had found I can insert text at the top and bottom of my pages using add_action. For example:

add_action( 'get_footer', 'echo_hello_world' );

function echo_hello_world( $post )
{
   echo "hello world";
}

would add the phrase “hello world” to the bottom of every single page on my blog. You can find a list of tags on WordPress’ Action Reference page.

One of the things I wanted to do was insert some text beneath my header, but before my post. I had found get_template_part_content would do the trick on Pages, but not Single Posts. After I failed at finding a solution online, I looked into how the code differed between Pages and Single Posts.

Single Posts were calling:
get_template_part( 'content-single', get_post_format() );

while Pages were calling:
get_template_part( 'content', 'page' );

So I wondered if get_template_part_content_single would work, but nothing happened. I then tried get_template_part_content-single, lo and behold, it WORKED! Given that Google has 0 search results with that exact phrase, I’m guessing no one’s discovered this action tag or at least posted about it publicly.

So my code ended up looking like:

add_action( 'get_template_part_content', 'echo_hello_world' );
add_action( 'get_template_part_content-single', 'echo_hello_world' );

function echo_hello_world( $post )
{
   if( is_single() || is_page() )
   {
       echo "hello world";
   }
}

As a bonus, here’s a tag you can use to insert text between your post and the comments section: comments_template

Exclude WordPress Categories from your Main Page or Feed

So for a long time, I’ve gotten tired of having my Twitter logs fill my blog’s main page, and since I’ve winded down the HD-Trailers.net blog (moved everything to the main site), I didn’t want that to fill the blog up with Twitter spam either. But I love the archive ability of having my Twitter messages saved into my blog. It makes it a lot easier to search for stuff I’ve tweeted about.

After a bit of searching, I found this WordPress plugin: Ultimate Category Excluder. It allows you to exclude any category from your main page, feed, and archives.

As of now, I’ve excluded the Twitter category from the main page and feed, so it’ll still show up in the archives.

Pretty neat!

You are too awesome for Ping-o-matic.

If you’re trying to automate pinging Ping-o-Matic! via PHP/cURL, you may have hit into an issue where the response you get is:

You are too awesome for Ping-o-matic.

To fix this, all you have to do is add a user-agent to your curl options, e.g.
curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0" );

Once you set a user-agent, you should be able to get a valid response and have the Ping-o-Matic service ping all the services for you. Of course if you run that script too often, they’ll probably reject your request and tell you to slow down.

Getting WordPress.com Stats Helper to work with JetPack

WordPress recently released their JetPack plugin which replaced WordPress.com Stats plugin. After upgrading, things took a bit to update, but most things worked fine afterwards. However, my Popular Posts widget (Most Viewed Posts) remained broken with the error: WordPress.com stats not installed

I was too busy this week to look into the cause of the issue and a quick search online didn’t result in much traction. This weekend, I finally got some time and found this post on WordPress forums: [Hack] How to use Stats Helper beside Jetpack.

Thanks to herophuong’s help, I realized what was causing the issue. The Most Viewed Posts widget is part of the WordPress.com Stats Helper plugin and it was looking up a function that no longer exists. When you installed JetPack, it automatically deactivated WordPress.com Stats. The helper plugin needed the API key in order to query for data.

You can either do what herophuong suggested in his post, but I thought a more elegant solution would be to create a separate plugin that created the function that it was looking for. That way when there are updates to the plugin, it won’t trample over your changes.

Stats API Key

All this plugin does is add the missing function stats_get_api_key and return the API key. After you download this plugin, you have to add your API key to the plugin.

You probably have an API key already. There are a couple ways to retrieve it.

  • apikey.wordpress.com
  • Akistmet settings – Go into your WordPress Plugins page and click on settings underneath Akismet

You can always go to apikey.wordpress.com to sign up for one if you don’t have one already.

After you download the plugin and obtain your API key, open the included stats-api-key.php and replace ENTER_API_KEY_HERE with your API key. Remember to leave the quotes.

Upload this file to your WordPress plugins directory (usually wp-content/plugins/) and go back to your WordPress Plugins Page, refresh the page if needed, locate the newly added Stats API Key plugin, and activate it.

Your Most Viewed Posts and any other thing that relies on WordPress.com Stats Helper should work now.

A couple things I noticed was it took a couple minutes for it to successfully retrieve the stats. Before it completed that, my most viewed posts widget would show my latest 5 posts. But be patient and it’ll eventually work.

Traffic Spike on 5/9

So I was just checking my blog stats and I noticed a giant spike on 5/9, something that I had not anticipated:

Krunk4Ever! Stats

Going through my other stats, it turns out a particular set of search terms hit my blog that day:

5/9 Search Terms

Guess people were really looking for Mother’s Day comics. My guess is they landed on this Calvin and Hobbes strip.

I hope everyone remembered to wish their mom a happy mom day 🙂

Google Gears + WordPress

WordPress 2.6 first introduced the Turbo button I believe which allowed it to work with Google Gears. I never really thought much about it, but recently I had to modify a bunch of posts on my HD-Trailers.net blog and lets just say things weren’t as snappy as I’d like them to be. Updates took about 10-20 seconds. However I finally decide to try out the Turbo button and see where I could go from there.

Apparently what it does is that it downloads a bunch of static pages, so it doesn’t have to fetch them every time I load any of the editor/admin pages. And I do have to say things are now much snappier. It’s not lightning fast, but lets just say that post updates take less than 5 seconds. One would usually attribute these type of slowness to the webhost involved, but I’m seeing similar slowness on both Dreamhost and 1&1. However, after installing Google Gears and enabling it for both my blogs, things have been very smooth and I’m a much happier camper.

I also hate using my mouse to navigate the WordPress UI and wish they would implement some more keyboard shortcuts/hot keys. I did learn a new one. Apparently alt+shift+p publishes or updates a published post. For more WordPress keyboard shortcuts, take a look at The Ultimate List of WordPress Keyboard Shortcuts.

A few shortcuts I would really like are:

  • Save Draft
  • Preview
  • Jump to a specific section (i.e. Editor, Title, Tags, Categories, etc.)

Finally, I searched around to see what other stuff I use supported Google Gears. I couldn’t find anything officially posted by Google, but Wikipedia had this list:

There are a number of web applications that use Gears. These applications come from a variety of companies, including Google (Gmail, YouTube, Docs, Reader, Picasa for mobile, Calendar), MySpace (Mail Search), Zoho (Writer, Mail), Remember The Milk, and Buxfer. WordPress 2.6 added support for Gears, to speed up the administrative interface and reduce server hits.

The only things I use on that list other than WordPress are Google Reader and YouTube. Gears allows Reader to work offline, which is neat I guess, but half the stuff in my RSS feeds requires me to visit the site. For YouTube, I believe Gears support was only added to the uploader and <sarcasm>you know how big a video uploader I am on YouTube</sarcasm>.

Why Twitter? Why blog?

As you may have noticed, I haven’t blogged much recently. In fact, the only blog posts in the past 2 weeks were my twitter aggregations.

Earlier today, a friend tells me he doesn’t fully understand why people use twitter and he really doesn’t understand why people post tweets on their blog.

First and foremost, I’d like to point out there are many different reasons why people use Twitter. Initially, I thought it was rather stupid too. Who in the right mind would want to tweet about what they’re doing all the time? See Penny Arcade!’s Le Twittre. And who in their right mind would care about knowing every mundane detail of what’s going on in your life? Unless of course you’re a stalker, but then you wouldn’t be in your right mind anyway. However, I found a very different use for Twitter. I’ve only been using it for about 2 months, and I’ve been slowly adapting on how I would like to use it.

My current twitter usage pattern is something similar to my Random Crap posts, in what I like to call mini-blog posts. I hear about something I want to share or I see a link I want to share. I used to aggregate this into 1 giant random crap post and then post it. Otherwise, I would create a draft in hopes one day when I have time, I would expand on it. Looking at my drafts count of 46, I don’t think it’s likely most of them will ever be published.

Initially, I kept my blog and Twitter separate, however I soon realized that people who come to read my blog are people who want to see what I’m up to or what I find interesting, basically the same stuff I’ve been posting on Twitter, but in short bursts of 140 characters or less. Therefore, my new weekly Twitter digest posts are akin to my Random Crap posts, containing links and whatever else I wanted to share during the week.

I understand that my twitter also includes response/replies that readers may not care about. Then again, probably half the stuff I ever post here you wouldn’t care about, so I don’t think that would make much a difference. It’s also not uncommon for me or others to respond to someone specifically in a blog post. In fact, this blog post by itself can be considered a response to the statement posed to me earlier today. Besides, most of the response/replies included are stuff I do want to share, or else I would’ve used the Direct Message feature in Twitter.

Of course, there’s also nothing stopping you from skipping/ignoring my twitter posts if you don’t fancy them.

Updated Gallery2 to Use JW FLV Media Player

So this little exercise started with the fact I was introduced to the JW FLV Media Player a few weeks back. Today, I wanted to share an flash video and thought it would be a good time to hack Gallery2 to use this flv video player.

If you’ve seen flash videos in my Gallery before, you’ve noticed it was using the default G2flv (Gallery2 Flash Video) player:

G2flv Player

One of the things I disliked about it was that it didn’t have a full screen mode, and it’s double-size feature behaved differently in IE and Firefox.

So I downloaded the latest version of JW FLV Media Player (currently at 4.3) and uploaded into the libs folder: /modules/flashvideo/lib

Then I had to modify modules/flashvideo/classes/FlashVideoRenderer.class to tell it to use the new flv player. I would highly recommend you back up that file before you modify it. Here’s a copy of what my resulting FlashVideoRenderer.class looks like: FlashVideoRenderer.class using JW FLV Media Player.

I’ll explain the changes I made.

I disabled forceSessionId as the url generated wasn’t like by the script. I’m guessing it did not like the ‘?’. I also added a pointer to the new .js file and updated the playerUrl.

$urlGenerator =& $gallery->getUrlGenerator();
$src = $urlGenerator->generateUrl(
        array('view' => 'core.DownloadItem',
              'itemId' => $entity->getId(),
              'serialNumber' => $entity->getSerialNumber()),
        array('forceFullUrl' => true,'forceSessionId' => false,
              'htmlEntities' => false));
list ($width, $height, $title) =
        array($entity->getWidth(), $entity->getHeight(),
              $item->getTitle());
GalleryCoreApi::requireOnce(
    'lib/smarty_plugins/modifier.markup.php');
$title = smarty_modifier_markup($title, 'strip');
 
/* Default player: G2flv.swf */
$swfObjectUrl = $urlGenerator->generateUrl(
        array('href' => 'modules/flashvideo/lib/swfobject.js'),
        array('forceFullUrl' => true));

$playerUrl = $urlGenerator->generateUrl(
        array('href' => 'modules/flashvideo/lib/player.swf'),
        array('forceFullUrl' => true));
$flashVars = 'flvUrl=' . urlencode($src) . '&amp;Width=' . $width .
            '&amp;Height=' . $height . '&amp;title=' .
            urlencode($title);
$extraAttr = '';

This remaining was basically following the instructions on JW FLV Media Player on how to use their code. I also added another paragraph where I would put the fallback code (e.g. Download Movie). If you prefer that to only show up when the item could not load, I would suggest putting the %s in the paragraph above.

return sprintf(
    '<div id="flashvideo">
 
        <p id="%s" %s%s></p>
        <p id="fallback">%s</p>
 
        <script type="text/javascript" src="%s"></script>
        <script type="text/javascript">
        var s1 = new SWFObject("%s","player","%s","%s","9");
        s1.addParam("allowfullscreen","true");
        s1.addParam("allowscriptaccess","always");
        s1.addParam("flashvars","file=%s");
        s1.write("%s");
        </script>
 
    </div>',
 
    !empty($params['id']) ? $params['id'] : 'movie',
    !empty($params['class']) ?
        ' class="' . $params['class'] . '"' : '', $extraAttr,
    $fallback, $swfObjectUrl, $playerUrl, $width,
    $height, $src,
    !empty($params['id']) ? $params['id'] : 'movie');

I’ll probably update my Gallery2 mp3 audio player to use this new player some time in the future.

WordPress Flash Upload Not Working

After upgrading to WordPress 2.7 awhile back, I noticed they included a flash uploader for images. However, I never did get it to work as I was unsure what to do with the following UI:

WordPress Flash Uploader Not Working

I ended up switching over to the browser uploader, which has worked for me.

The other day I decided to go figure out what was wrong. At first I thought it was because I didn’t have the latest version of Flash, but even after upgrading to Flash 10, it still did not work. Then I thought maybe it only works in IE and not Firefox, but even on IE with the latest version of Flash, it didn’t work.

I started researching the issue online and found: Flash Upload Not working in Latest 2.7 ver

Turns out the version of swfupload included with WordPress is incorrect or broken. I went to swfupload – Google Code and download the latest version, and overwrote the files in /wp-includes/js/swfupload. The only file you really need to keep in there is handlers.js.

Now the flash uploader is working like a charm:

WordPress Flash Uploader Working

WordPress Automatic upgrade

Apparently there’s a plugin that does what I’ve been waiting for WordPress to incorporate all this time: WordPress Automatic upgrade:

WordPress Automatic Upgrade allows a user to automatically upgrade the wordpress installation to the latest one provided by wordpress.org using the 5 steps provided in the wordpress upgrade instructions.

WordPress automatic upgrade upgrades your wordpress installation by doing the following steps.

  1. Backs up the files and makes available a link to download it.
  2. Backs up the database and makes available a link to download it.
  3. Downloads the latest files from http://wordpress.org/latest.zip and unzips it.
  4. Puts the site in maintenance mode.
  5. De-activates all active plugins and remembers it.
  6. Upgrades wordpress files.
  7. Gives you a link that will open in a new window to upgrade installation.
  8. Re-activates the plugins.

The plugin can also can be run in a automated mode where in you do not have to click on any links to go to the next step.

Sweet! I thought the automatic plugin update was really neat already. If this works, then it’ll be sweet! Just make sure you haven’t actually modified WordPress code or your upgrade would overwrite it. Previously, I went and modified WordPress core code to get my collapsible sidebar menus, since that wasn’t exposed in the theme layer. However in my recent upgrade, I forwent all that and only made slight changes to the theme so it’d be easier for later upgrades, so upgrading won’t have to be a multi-hour process and tons of breaking changes. I’ll also be able to upgrade more frequently instead of every 6 months to 1 year.

Next thing they need to add is the ability to download and install new plugins on the fly. Currently I have to download the zip file and upload it myself. But given that they can already automatically upgrade plugins to the latest version, I’d think adding a new plugin shouldn’t be too hard.

Update: Speak of the devil. WordPress 2.7 was just released today. Got to test the plugin first hand today and it was a smooth as a baby’s butt. It was basically the steps above, one after another. Personally I think it requested confirmation too many times. Like I don’t think it really needed my confirmation to go and download the latest version of WordPress. I think it should be 2 simple steps: 1. Backup, 2. Upgrade. Any option needed for backup should be on the 1st page. Any option needed for upgrade should be on the 2nd page. However, it definitely made the upgrade process a lot simpler.

Tons of new stuff that I have yet to check out. Definitely a big improvement over 2.6. The editor space is a lot bigger now (fills up the width of your screen instead of set at some fixed width). The common panes (publish, tags, and categories) are move to the right side. Unfortunately they haven’t made it possible to resize the panes individually. I still don’t understand why you can resize the editor window when it’s in Visual mode, but not in HTML mode.

I just watched the video on their blog and they’ve basically rendered this plugin useless. They’ve apparently built the WordPress upgrade directly into 2.7. They’ve also addressed a few of the points I’ve brought up (i.e. automatically downloading and installing plugins).