A multilingual sitemap with Google XML sitemap and ZdMultiLang

This site attempts to be bilingual, using the plugin ZdMultilang. This plugin manages the translation of various elements of WordPress (posts, links …) and covers 90% of translation needs. But like most of multilingual plugins, it does not support more sophisticated needs, like adding translated posts in sitemap.xml, for example.
THE plugin for the generation of this file is Google XML Sitemaps. I propose to you a modification of this plugin to take into account the information managed by ZdMultilang.
The goal is to list all posts into the sitemap.xml file, regardless of their language.


It is preferable, even mandatory to test these changes before installing them on your blog, to see if they work, and if they have any impact on the blog.

The proposed changes have been tested with

  • ZdMultiLang 1.2.4
  • Google XML SiteMaps 3.1.5

This kind of hack, has some disadvantages:

  • You will have to test its behavior for each ZdMultiLangupdate,
  • You will have also to modify the plugin Google XML Sitemaps, for each update.

To summarize, this hack will forbid all automatic update for these two plugins.

The hack

All changes occur in the file sitemap-core.php of the plugin Google XML Sitemaps. This file is usually stored in the directory wp-content/plugins/google-sitemap-generator.

At the bottom of the loop En bas de la boucle parcourant les articles, aux alentours de la ligne 1970, placez la ligne suivante:

global $ZdmlCache;
if ( function_exists('zd_multilang_set_locale') && isset($ZdmlCache) )
	zdmultilang_add_posts(&$this, $permalink, $post, $isPage, $cf_pages, $cf_posts, $prio);

Then, on top of the file, before the line if (!function_exists('file_get_contents')), you put the following PHP:

function zdmultilang_add_posts($object, $permalink, $post, $isPage, $cf_pages, $cf_posts,$prio) {
	global $wp_rewrite;
	global $ZdmlCache;
	foreach ($ZdmlCache['Languages'] as $lang_permalink => $lang_id) {
		if ($lang_id != $ZdmlCache['DefLang']) {
			// Get the list of translated posts
			$posts_list = explode(',', $ZdmlCache['TranslatedPosts'][$lang_id]);
			// Is the current post translated?
			if (array_search($post->ID, $posts_list) !== FALSE ) {
				// Add the language permalink according the rewriting rules
				if ( $lang_permalink != '' ) {
					if ($wp_rewrite->using_permalinks()) {
						$url = get_bloginfo('url');
						$end = substr($permalink,strlen($url));
						$permalink = $url.'/'.$lang_permalink.$end;
					else {
						$permalink .= '&lang='.$lang_permalink;
				// Add translated post to the XML file
				$object->AddUrl($permalink,$object->GetTimestampFromMySql(($post->post_modified_gmt && $post->post_modified_gmt!='0000-00-00 00:00:00'?$object->post_modified_gmt:$post->post_date_gmt)),($isPage?$cf_pages:$cf_posts),$prio);
			} // End of post translated
		} // End of not default language
	} // End of foreach language
} // End of zdmultilang_add_posts

That’s all.

Le code source des modifications
Titre: Le code source des modifications (459 clics)
Légende: Le code source des modifications
Nom du fichier: xml_sitemap_zdmultilang.txt
Taille: 2 KB

The modification doesn’t generate additional requests to the database, because we use the « cache » of ZdMultiLang.
The following image shows the result:


We can see the french posts, and their translation when exist.