Archive for the ‘wordpress’ Category

Locale dependent actions in WordPress

Wednesday, April 2nd, 2008

For some reason or other there are actions in WordPress that have translatable fields in them, so when these actions are used on other languages than English, they change. They are actions involving the $page_hook variable., e.g. admin_head-$page_hook. I ran into this problem when updating More Fields. The problem in the context of plugins is that the language is not loaded when the plugins are loaded, so that the needed translation is not available. To get around this, the actions requiring translation are called at the ‘admin_init’ action instead.

function mf_pre_queue_js () {
    add_action('load-' . sanitize_title(__('Settings')) . '_page_more-fields', 'mf_queue_js');
}
add_action('admin_init', 'mf_pre_queue_js');

I got help with this on the wp-hackers mailng list - a great source for WordPress insights.

>Try adding your actions on the init hook, I think that runs after
>the translatable stuff has been loaded and setup.

Correct.

Everything related to languages should be done at init or later, so that everything is loaded and any plugins that modify the content are loaded.

So, at the init/admin_init hook, we’re safe to assume that the appropriate language has been loaded.

More Fields version 0.6

Monday, March 31st, 2008

I’ve just updated More Fields to version 0.6, compatible with WordPress 2.5.

New features:

  • Compatible with the new admin introduced in WordPress 2.5
  • Set default value in a select list.
  • Enable right hand column boxes in WP 2.5.
  • Option of removing the ‘Related’ links on the right hand side on the Write/Edit page.
  • A new set of actions, enabling users to change the behavior of More Fields. The documentation has been updated to include an example on how to use these actions.

The plugin can be downloaded from wordpress.org.

Any feedback is always greatly appreciated.

Setting the template for individual posts

Thursday, March 20th, 2008

I hashed together a plugin that enables authors to specify a specific template file to be used for a post (this functionality is already built in for pages, but not for posts).

<?php
/*
Plugin Name: Template for posts
Plugin URI: http://labs.dagensskiva.com
Description: Set the template file for a post by setting the Custom Field 'dsc_template' to the filename of the template
Version: 0.1
Author: Henrik
*/
?>

function dsc_post_template() {
  global $post, $wp_query;

  if (count($wp_query->posts) == 1) {
    $id = $wp_query->posts[0]->ID;
    if ($temp = get_post_meta($id, 'dsc_template', true)) {
      include( TEMPLATEPATH . '/' .$temp );
      exit(0);
    }
  }
}
add_filter('template_redirect', 'dsc_post_template', 9);

Usage: a Custom Field called ‘dsc_template’ is set to equal the basename of the file, e.g. ‘interview.php’, placed inside your theme folder. Simple as that. It only applies the template file if $wp_query contains only one post, i.e. where the template file ’single.php’ would normally be applied.

Importing posts into WordPress programatically

Tuesday, March 4th, 2008

I’ve been working on exporting the content of the old dagensbok.com site, which runs ASP and MSSQL, into an installation of WordPress. Using the MSSQL functionality in PHP, the MSSQL server is accessed from within the WordPress installation I’m importing into. The PHP code that performs the import is contained in a plugin.

A few basic notes on MSSQL versus MySQL:

  • The MySQL LIMIT 10 clause becomes ‘SELECT TOP 10
  • SHOW TABLES‘ becomes ‘“SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ‘BASE TABLE’”;
  • Selecting a random row in MSSQL can be done by ‘ORDER BY NEWID()

To do the import into WordPress I’m populating the $_POST variable, as if the post was created in the Admin:

<?
$_POST = array();
$_POST['post_title'] = $ret['header'];
$_POST['post_type'] = 'post';
$_POST['content'] = $ret['text'];
$id = wp_write_post();
add_post_meta($id, 'dbc_author', $ret['fname'] . ' ' . $ret['lname']);
...
?>

where $ret is the variable returned from mssql_fetch_assoc(). Similarly, the comments to a post are added using wp_insert_comment($commentdata); - populating the $commentdata array first.

Contributing to WordPress 2.6 2.5

Tuesday, February 12th, 2008

WordPress is an excellent platform and it provides us at dagensskiva.com with a lot of built-in functionality that is required to run the site. The functionality that WordPress does not supply internally, we can add using our own custom made plugins, and, of course, plugins that other developers wrote. However, as any piece of software, WordPress is not perfect, and there are php files that we have to hack manually to get the desired functionality, particularly in the admin. To help WordPress become a better platform, I submitted this change to WordPress trac - now proposed to be part of WordPress 2.6 2.5. The change is very small but solves a problem that have been vexing us for quite some time.

One hack down, a handfull to go!

UPDATE: It got bumped to 2.5!

Patched XML-RPC

Tuesday, February 5th, 2008

Updated dagensskiva.com with the patch for XML-RPC released in conjunction with WordPress 2.3.3:

WordPress 2.3.3 is an urgent security release. A flaw was found in our XML-RPC implementation such that a specially crafted request would allow any valid user to edit posts of any other user on that blog. In addition to fixing this security flaw, 2.3.3 fixes a few minor bugs. If you are interested only in the security fix, download the fixed version of xmlrpc.php and copy it over your existing xmlrpc.php. Otherwise, you can get the entire release here. 

Decided to patch rather than do the entire update since we have a lot of registred users that potentially could exploit the security flaw, to make a quick fix to a potential situation.

Upgraded to WordPress 2.3.2

Sunday, January 20th, 2008

I upgraded our servers to WordPress 2.3.2, which offers a security fix and some xmlrc enhancements (which I don’t think anyone uses). A pretty smooth ride as of yet. Through some plugin work, there’s only one thing that we have to hard-hack in the WordPress codebase - this relates to bbPress’ feeds that are blocked by a 404 from WordPress.

I also upgraded to More Fields version 0.4 and Ad-minister version 0.3.2. I’m gonna do some finishing touches to the latter plugin and roll out version 0.4 to the WordPress SVN server - hopefully I’ll get around to that this weekend - it is a nice plugin, even if I say so myself…

And, apparently it’s WordPress and not Wordpress. :)

We release the ‘More Fields’ Wordpress plugin!

Thursday, January 10th, 2008

Finally, having uhhmm’d and ahhrree’d about implementation, I’ve decided submit the 0.4 beta version of the ‘More Fields’ plugin to the Wordpress Plugins CVS server, else it might never happen.

You can find more information about the plugin here. I’m hoping to update the examples to reflect the current look of the plugin, albeit I’m still hoping for a redesign of the ‘More Fields’ admin for some future version.

You can download the plugin from Wordpress.org.

The plugin is a beta, which means it might be riddled with bugs and oddities that might sink your particular Wordpress ship. It is released under the GPL license.

As always, feedback and comments are always very much appreciated.

I’m quite exited to see this one out the door. There are another two proprietary plugins that we currently run on dagensskiva.com - one that handles the external links associated with posts, and one (sizable) ad-management system. I’m hoping that these will also be released shortly.

Taking control of Wordpress’ xml export

Friday, November 30th, 2007

I’ve been working on a plugin that uses the custom fields (post meta) to hold settings and content. To transfer the settings of the plugin from the development server to the live server (yes, we’re skipping staging, hoping to set one up soon), I thought the simplest way was to create a Wordpress xml export file, for this one post, accessible via one simple link click.

The link to the xml file looks like this (btw, the plugin is called ADMinister, which is a plugin to handle advertising, and other temproary content, not related to specific pages or posts):

<a href="<?php echo get_option('siteurl'); ?> /wp-admin/export.php?download=true&administer=true">
Download</a> Worpress xml export for one post.

And in the plugin, the following bit of code will alter the export process to only export the specified ID or IDs.

function p2m_export_administer () {
   global $post_ids;
   if ($_GET['administer'])
      $post_ids = array(get_option('p2m_ad_post_id'));
}
add_action('rss2_head', 'p2m_export_administer');

The id of the page/post is held in the option ‘p2m_ad_post_id’, and the url parameter ‘administer’ is used to signify that we want to later the behaviour of the export. The global parameter $post_ids is the array that holds the ID of what to export. Even though we’re intent on only exporting one, the parameter must remain an array.

The xml file can then be imported into another Wordpress installation. Obviously, this is rather inflexible if you want to transfer settings back and forth, but the point here is to illustrate how to better control the Wordpress xml export file.

Translating plugins - the $domain parameter

Friday, November 16th, 2007

Any half descent Wordpress plugin should be able to handle different languages. The gettext translation system that Wordpress uses is really easy to use, once one has the right tools, namely POEdit.

The function that loads the translation file is declared in WP as follows:

function load_plugin_textdomain($domain, $path = false)

Where $domain is the second parameter called in __($en_US_text, $domain) and _e($en_US_text, $domain). The difference between these two functions is that the _e() echoes the text, whereas __() just returns it. So, the $domain parameter defines the namespace within which the translation file (.mo) is valid, and this namespace must be specified for each translatable entity.

We load the .mo file in the plugin using the ‘init’ hook:

function p2m_translate(){
	load_plugin_textdomain('p2m-links', PLUGINDIR
            . '/' . dirname(plugin_basename (__FILE__)) );
}
add_action('init', 'p2m_translate');

In this example, the domain is ‘p2m-links’, which mean that translatable text should be expressed as:

__('Gobbledygook', 'p2m-links');
_e('Gobbledygook', 'p2m-links');

If no domain is specified in a plugin then Wordpress will look for translations in the .mo file contained in the wp-includes/languages directory.