How To Remove (Or Change) “Private” Or “Protected” From WordPress Post Titles

If you make a post private in WordPress, the post’s title with be prefixed with “Private”. The same will happen if you password protect the post, although it will be prefixed with “Protected”. If you’d like to remove these, just add the following code to your theme’s functions.php file:

add_filter( 'private_title_format', 'yourprefix_private_title_format' );
add_filter( 'protected_title_format', 'yourprefix_private_title_format' );

function yourprefix_private_title_format( $format ) {
	return '%s';
}

The above code will remove the prefix by changing the format from Private: %s and Protected: %s to just %s where %s is the existing post title.

If you’d like to change it to something else, you can just change what the function in my example returns. If you want to change them independently of each other, then you’ll need to use two separate callback functions.

How To Create Custom WordPress Cron Intervals

This is mostly a reminder for myself so I can stop tracking it down every time I forget, but here’s how to have WordPress code execute on a different schedule than the default intervals of hourly, twicedaily, and daily. This specific example is for weekly execution.

<?php

// Add a new interval of a week
// See http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
add_filter( 'cron_schedules', 'myprefix_add_weekly_cron_schedule' );
function myprefix_add_weekly_cron_schedule( $schedules ) {
	$schedules['weekly'] = array(
		'interval' => 604800, // 1 week in seconds
		'display'  => __( 'Once Weekly' ),
	);

	return $schedules;
}

// Schedule an action if it's not already scheduled
if ( ! wp_next_scheduled( 'myprefix_my_cron_action' ) ) {
	wp_schedule_event( time(), 'weekly', 'myprefix_my_cron_action' );
}

// Hook into that action that'll fire weekly
add_action( 'myprefix_my_cron_action', 'myprefix_function_to_run' );
function myprefix_function_to_run() {
	// Add some code here
}

?>

On a side note, I believe this must go in a plugin and not your theme’s functions.php which I hear loads too late.

Two Handy Sublime Text 2 Plugins

After using EditPlus for the better part of a decade, I made the switch to the totally awesome Sublime Text 2 text editor a few weeks back. One of the great things about Sublime is it’s support for plugins.

Two such plugins I’d like to recommend are SublimeBrackets and SublimeTagmatcher. Both improve how the highlighting of opening and closing items are handled.

By default, Sublime just underlines paired brackets. When you have a ton of code, this can be really hard to see. SublimeBrackets changes this to something more apparent:

Much better, right? I personally use the solid background green style.

SublimeTagmatcher does something similar but for HTML tags. When you have your cursor inside of an HTML tag, it will highlight both the current tag and it’s opening or closing counterpart. This is helpful for making sure you have the correct number of opening and closing tags.

Translating Strings In WordPress Containing Multiple Placerholders

I really often see a common mistake made when translating strings in WordPress so I thought I’d write a blog post in order to shed more light on the issue.

But first, here’s a quick refresher on how to internationalize code in WordPress:

<?php _e( 'Welcome to my blog!', 'my-plugin-text-domain' ); ?>

For dynamic strings, it’d be something like this:

<?php printf(
	__( 'Welcome to my blog, %s!', 'my-plugin-text-domain' ),
	$name
); ?>

But what about when you have multiple variables to use in your string? A common mistake is to do something like this:

<?php printf(
	__( 'Welcome to my blog, %s! Today\'s date is %s.', 'my-plugin-text-domain' ),
	$name,
	$date
); ?>

The issue with this is that you’re requiring the person’s name to always come before the date. If for internationalization reasons it needs to be in a different order, then it won’t work. You’ll end up with something like Today's date is Alex. Welcome to my blog, November 2nd!.

The solution is to use standard sprintf() argument swapping parameters:

<?php printf(
	__( 'Welcome to my blog, %1$s! Today\'s date is %2$s.', 'my-plugin-text-domain' ),
	$name,
	$date
); ?>

Now translators are free to re-order the string to whatever makes the most sense for the language in question without having to worry the order of the variables.

For a more in-depth review of this, check out the WordPress Codex where many real world examples can be found.

Code Snippet: Generate A Plaintext Data Table

Inspired by some awesome-as-always code written by my co-worker Mike Adams, here’s a helper function to help create plaintext data tables in PHP. This is particularly useful for PHP-based CLI scripts (we use quite a few at Automattic) or for plaintext e-mails.

But first, here’s an example output with the optional dividers enabled:

   ID | First Name     | Last Name
-------------------------------------
    1 | Alex           | Mills
    2 | John           | Smith
    3 | Barack         | Obama
    4 | Fred           | Flinstone
12345 | ReallyLongName | IsReallyLong

Click here to keep reading and see the code »

Code Snippet: Helper Class To Add Custom Taxonomy To Post Permalinks

Say you have a custom taxonomy called “sport” and you wanted to inject “football” into the permalink of posts that have the “football” term assigned to it. How would you go about doing that? Well below is a helper class that will make it easy to accomplish exactly that.

Click here to read the rest of the post and see the code »

Code Snippet: Add A Link To Latest Post To WordPress Nav Menu

Someone on #wordpress IRC support channel was trying to add link to their latest blog post to their WordPress navigation menu, so I threw together a few lines of code to help them accomplish this.

// Front end only, don't hack on the settings page
if ( ! is_admin() ) {
	// Hook in early to modify the menu
	// This is before the CSS "selected" classes are calculated
	add_filter( 'wp_get_nav_menu_items', 'replace_placeholder_nav_menu_item_with_latest_post', 10, 3 );
}

// Replaces a custom URL placeholder with the URL to the latest post
function replace_placeholder_nav_menu_item_with_latest_post( $items, $menu, $args ) {

	// Loop through the menu items looking for placeholder(s)
	foreach ( $items as $item ) {

		// Is this the placeholder we're looking for?
		if ( '#latestpost' != $item->url )
			continue;

		// Get the latest post
		$latestpost = get_posts( array(
			'numberposts' => 1,
		) );

		if ( empty( $latestpost ) )
			continue;

		// Replace the placeholder with the real URL
		$item->url = get_permalink( $latestpost[0]->ID );
	}

	// Return the modified (or maybe unmodified) menu items array
	return $items;
}

Place the above code in a plugin or just in your theme’s functions.php file.

Create a new “Custom Link” menu item where the URL is #latestpost (which will act as a placeholder and target for the code). You can title the item whatever you please. This code will then find that menu item (by looking for the placeholder URL) and then replace it’s URL with that of the latest post’s URL. Since the filter is before the code that adds the selected CSS classes runs, the menu highlighting will even work. When you visit the latest post on your blog, this menu item will light up.

Rather simple and elegant. You gotta love WordPress hooks.

Translating WordPress Plugin Details

Plugin authors: did you know that you can allow translators to localize the plugin details that show up in the plugins list in the WordPress administration area? Your plugin’s name, description, and so forth? Well you can! It’s actually really simple to do and all you need to do is add one or two additional plugin headers to your file.

The first is Text Domain and this is the text domain for your plugin, i.e. the first argument that you are passing to load_plugin_textdomain().

The second one is Domain Path and is optional. It’s only needed if you store your translation files in a subfolder inside of your plugin’s folder.

Here’s an example load_plugin_textdomain() call from one of my newest plugins:

load_plugin_textdomain(
	'add-descendants-as-submenu-items',
	false,
	dirname( plugin_basename( __FILE__ ) ) . '/localization/'
);

That loads translation files from a subfolder called “localization” inside of my plugin’s folder. This turns into the following plugin header:

Plugin Name:   Add Descendants As Submenu Items
Plugin URI:    http://www.viper007bond.com/wordpress-plugins/add-descendants-as-submenu-items/
Description:   Automatically all of a nav menu item's descendants as submenu items. Designed for pages but will work with any hierarchical post type or taxonomy.
Version:       1.1.0
Author:        Alex Mills (Viper007Bond)
Author URI:    http://www.viper007bond.com/

Text Domain:   add-descendants-as-submenu-items
Domain Path:   /localization/

An extra line break isn’t needed nor is the extra spacing but I added both just for aesthetic reasons.

And that’s it! WordPress will then attempt to translate the plugin’s name, URI, description, author, author URI, and version fields. I personally only include the plugin’s name and description in my translation template files though as I don’t feel translators need to localize the other fields.

If you need help generating a translation template file for your plugin, log into WordPress.org and then visit the “Admin” tab on your plugin’s page on WordPress.org. You can generate a POT file for your plugin there.

Editing Your Hosts File In Windows

Andrew Nacin mentioned here at WordCamp San Francisco where your hosts file is on Mac (and Linux), but I thought I’d point out where your hosts file is on Windows and how to change it so that you can point domain names to your local computer.

The easiest solution is to create a shortcut that will open Notepad and then tell it to open your hosts file. Right-click your desktop and select New → Shortcut. Paste the following into the field that pops up:

%windir%\system32\notepad.exe %windir%\System32\drivers\etc\hosts

Once you’re done creating the shortcut, right-click it and select “Properties”. Under the “Shortcut” tab is an “Advanced” button. Clicking it will show a checkbox for “Run as administrator”.

Start by opening Notepad in Administrator mode. Type “Notepad” into your Start Menu search box and then right-click it and select “Run as administrator”. This is important because otherwise you won’t be able to save your changes as the file is a protected one.

Now that you have Notepad open, do File -> Open and browse to C:\Windows\System32\drivers\etc. You won’t see any files because by default Notepad will only show *.txt files. To change this, click on the dropdown that is currently showing “Text Documents (*.txt)” and change it to “All Files (*.*)”. Now you’ll be able to see your hosts file.

Opening it will show a little documentation and some examples. If you want to add your own, just add it to the bottom in this format:

	127.0.0.1	yourdomain.com

Saving the file and then visiting the domain in your browser will now show you files served by your local development environment. Note: a hard refresh may be required to due to your browser’s DNS cache. This can be accomplished by pressing control and F5.

Accessing Other Databases/Servers From Within WordPress

Say you have a WordPress install where you need to pull in data from a separate database or server. The normal $wpdb instance of the wpdb class is limited to the database that your WordPress tables are located in. Yes, you could use mysql_connect() and the other standard PHP database functions, but then you don’t get all of the WordPress magic. So what to do?

The answer is surprisingly simple: make a new instance of the wpdb class! Dion Hulse (DD32) was kind enough to point out this great solution to me a few weeks back and I thought it was worth sharing with you all.

$myotherdb = new wpdb( $dbuser, $dbpassword, $dbname, $dbhost );

$myotherdb->get_results( "SELECT id, name FROM mytable" );