Compatibility package example
This tutorial shows how to build a compatibility package for a WordPress theme. We’ll go through WPML’s compatibility package for ThemeHybrid, explaining how to make it fully multilingual without touching one line of the theme’s code.
Objectives – what we’re trying to implement
Multilingual themes have three important features:
- Users can switch between languages.
- All the page elements are displayed in the correct language.
- All links go to contents in the correct language.
WPML’s compatibility packages implement all these basic features. In addition, compatibility packages also add configuration options, which users can use to customize language support in the theme.
Language elements for ThemeHybrid
Language selector in the header
WPML’s language switcher can be enabled as sidebar widget, and can also be added directly to the theme. Most compatibility packages will add custom-styled language selectors to match the theme’s look. Let’s see how to add a drop-down language switcher to Hybrid’s header.
Hybrid’s header.php (in the theme folder) includes several function calls that we can use. We’ll use the hybrid_before_header hook, as it allows adding a floating element before the rest of the header (but inside body container).
This call will add our language selector before Hybrid’s header HTML:
add_action('hybrid_before_header',array(&$this,'language_selector_header'));
The compatibility package we’re writing for Hybrid is an extension of WPML’s base package class, so we can use existing code for common tasks. language_selector_header adds a drop-down language selector.
Next, we’ll add a GUI option that allows users to enable or disable this header language switcher.
WPML allows compatibility packages to add controls in its language setup screen (WPML->Languages). This means that users will be able to choose which language elements to display in Hybrid theme from WPML’s own setup page.
To do this, we’ll add a checkbox using this call:
$this->add_option_checkbox( ICL_PLUGIN_FOLDER . '/menu/languages.php',
__('Site header horizontal language selector','my_package_textdomain'),
'header_language_selector',
__('Language selector options', 'my_package_textdomain'), 'checked');
Once we’ve added the GUI checkbox, we want to use its value to enable/disable the header language switcher. We can access the value of the checkbox via the classes’ settings array:
if($this->settings['header_language_selector']) {
add_action('hybrid_before_header',array(&$this,'language_selector_header'));
}
Footer language selector
Besides a drop-down language switcher in the header, we’ll also add a horizontal list of languages to the footer.
Language list in footer
We’ll add checkboxes with GUI options that control the footer language switcher. We’ll let users choose to show/hide the footer language switcher and what to do for languages without translation.
$this->add_option_checkbox( ICL_PLUGIN_FOLDER . '/menu/languages.php',
__('Site footer horizontal language selector', 'my_package_textdomain'),
'footer_language_selector',
__('Language selector options', 'my_package_textdomain'), 'checked' );
$this->add_option_checkbox( ICL_PLUGIN_FOLDER . '/menu/languages.php',
__('Skip missing languages for the footer languages', 'my_package_textdomain'),
'footer_skip_languages', __('More options'), 'checked');
$this->add_option_checkbox( ICL_PLUGIN_FOLDER . '/menu/languages.php',
__('Load CSS for footer language selector', 'my_package_textdomain'),
'footer_load_css', __('More options'), 'checked');
if($this->settings['footer_language_selector']){
add_action('hybrid_after_footer',array(&$this,'language_selector_footer'));
if($this->settings['footer_load_css']) {
$this->load_css('css/selector-footer.css');
}
}
This post is available in…
We can also let visitors see in what other languages pages and posts are written by adding a language switcher to the end of posts. This will add a sentence that looks like this:
Links to alternative languages for a post
First, we add the GUI elements for enabling/disabling this option:
$this->add_option_checkbox( ICL_PLUGIN_FOLDER . '/menu/languages.php',
__("Show 'this post is also available' at the bottom of the post.", 'sitepress'),
'post_languages', __('Language selector options'), 'checked');
$this->add_option_select( ICL_PLUGIN_FOLDER . '/menu/languages.php',
__("'this post is also available' position:", 'sitepress'),
'post_available_position',
array( 'top' => __('Above post', 'sitepress'), 'bottom' => __('Bellow post', 'sitepress') ),
__('Language selector options'), 'bottom');
Then, we’ll use the the_content WordPress hook to add this sentence at the end of each post:
if($this->settings['post_languages']) {
add_filter('the_content', array($this, 'add_post_available'));
}
Home-page link
We’re almost done. One more thing, easily forgotten, is the link to the home page. When themes run in a single language, they often use a hard-coded value for the home page URL.
When running multilingual, there’s a different URL per language. It’s important to adjust the theme’s home page URL according to the active language and not just send visitors to the home page in the default language.
Different themes have different approaches for displaying the Home link. fortunately, Hybrid has a the hybrid_site_title filter which contains the Home link.
add_filter('hybrid_site_title',array(&$this,'filter_home_link'));
This function filters the home URL and returns the right value for the current language.
Some (many) themes don’t include such handy hooks and are tricky to handle. For example, we needed to do some digging up to find how to adjust the home URL for the Thematic theme framework.
To adjust the Home link in the menu we used the wp_page_menu filter and added our filter_home_link function to it as well:
add_filter('wp_page_menu',array(&$this,'filter_home_link'));
Styling WPML’s language elements
WPML’s default styling may not be right for each theme, so we’ll add our own styling to the compatibility package.
The package’s CSS needs to load after all other WPML’s CSS files have already loaded, so that it take precedence and is not overridden by the default formatting.
To do this, use the load_css call. This call will make sure that the packages CSS is loaded at the right time. We’ve seen it in this tutorial in several places, where styling elements load their CSS files.
In our package for ‘Hybrid’ theme, we added options for loading CSS, so theme coders can supply their own CSS from theme, also added options for skipping empty languages.
...
if($this->settings['footer_load_css']) {
$this->load_css('css/selector-footer.css');
}

English
This is pretty silly…you’ve got to make this easier than what it is for language switching. I’ve been working on integrating it into my site for hours and haven’t gotten the CSS to change at all. You’re use of !important should be separated out to another stylesheet that ships with the plugin with instructions that if someone is using this with a larger site perhaps multiuser…that they should use that. Otherwise, CSS should be gathered from the theme it is displayed in.
Right now, trying to hack apart my functions file is pretty silly. I ended up not using your drop down and just using static links.
Like I said, this is pretty silly when you can just make static links appear much better than your built in sidebar.
Have a look at WPML’s API, where it says ‘Disabling WPML’s CSS and JS files’. If you don’t like them, you can tell WPML not to load its CSS and JS and then, you can supply your own.
Apart from that, you can use some pre-built functions included in WPML for building custom functions for language switchers:
http://wpml.org/?page_id=1789
Still trying to find out where to put this:
$this->add_option_checkbox( ICL_PLUGIN_FOLDER . '/menu/languages.php', __("Show 'this post is also available' at the bottom of the post.", 'sitepress'), 'post_languages', __('Language selector options'), 'checked');Trying to add a ‘this is also available in language’ because the drop down doesn’t work well for me.
However, I’m not sure which file I’m supposed to be editing and the paragraph doesn’t tell me.
[...] http://wpml.org/documentation/support/wpml-compatibility-packages/tutorial-creating-a-compatibility-... [...]