2013年8月份写了一篇博文《Drupal网站多语言版的站点地图自动转换》,是修改xmlsitemap.page.inc程序来实现多种语言网站的sitemap,这是多种语言网站提供对应的多种sitemap,博文中提到Google推荐的另外一种办法《通过站点地图指明备选语言网页》(英文版Use a sitemap to indicate alternate language pages, Multilingual and multinational site annotations in Sitemaps ,注意目前需要翻墙访问),是多种语言网站提供一个sitemap,而这个sitemap中为每个url指定多种语言的替换链接。我们此前一直使用的前面一种办法,但这样存在搜索引擎不断爬取很多种语言的sitemap占用带宽的问题以及没有在sitemap中指明多语言网址之间的对应关系,昨天换了后面一种办法来试一试。
具体办法是修改Drupal的xmlsitemap模块的xmlsitemap.xmlsitemap.inc这个文件:
public function getRootAttributes() { $attributes['xmlns'] = 'http://www.sitemaps.org/schemas/sitemap/0.9'; $attributes['xmlns:xhtml'] = 'http://www.w3.org/1999/xhtml';//jamesqi 2016-2-19 if (variable_get('xmlsitemap_developer_mode', 0)) {
以及
$xml_content = str_replace(array(" <", ">\n"), array("<", ">"), $xml_content); //jamesqi 2016-2-18 //insert start $line = $xml_content; global $base_url; //print substr($line,0,strlen($base_url)+23)."\n"; if (substr($line,0,strlen($base_url)+23) !== "<loc>$base_url/sitemap.xml?page=") { $loc_start = strpos($line,'<loc>')+5; $loc_end = strpos($line,'</loc>')-1; $loc_url = substr($line, $loc_start, $loc_end-$loc_start+1); $add_url = substr($loc_url, strlen($base_url)); $languages = language_list('enabled'); $languages_array = $languages[1]; $language_default = language_default($property = 'language'); $xhtml_link = ''; foreach ($languages_array as $key => $value) { $lang_code = $key; if ($lang_code != $language_default) { $lang_url = "$base_url/$lang_code$add_url"; } else { $lang_url = "$base_url$add_url"; } $xhtml_link .= "\n\t<xhtml:link rel=\"alternate\" hreflang=\"$lang_code\" href=\"$lang_url\" />"; } $xml_content = str_replace('</loc>',"</loc>$xhtml_link\n",$xml_content); } //insert end $this->writeRaw($xml_content);
这样生成的sitemapindex例子没有变化,而urlset例子中按照规范添加了xmlns:xhtml="http://www.w3.org/1999/xhtml"以及各种语言的<xhtml:link rel="alternate" hreflang="af" href="http://sale.mingluji.com/af/node/2628" />,摘录如下:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="//sale.mingluji.com/sitemap.xsl"?> <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"> <url><loc>http://sale.mingluji.com/node/2628</loc> <xhtml:link rel="alternate" hreflang="af" href="http://sale.mingluji.com/af/node/2628" /> <xhtml:link rel="alternate" hreflang="sq" href="http://sale.mingluji.com/sq/node/2628" /> <xhtml:link rel="alternate" hreflang="ar" href="http://sale.mingluji.com/ar/node/2628" /> <xhtml:link rel="alternate" hreflang="hy" href="http://sale.mingluji.com/hy/node/2628" /> <xhtml:link rel="alternate" hreflang="az" href="http://sale.mingluji.com/az/node/2628" /> <xhtml:link rel="alternate" hreflang="bg" href="http://sale.mingluji.com/bg/node/2628" /> <xhtml:link rel="alternate" hreflang="ca" href="http://sale.mingluji.com/ca/node/2628" /> <xhtml:link rel="alternate" hreflang="zh-hans" href="http://sale.mingluji.com/zh-hans/node/2628" /> <xhtml:link rel="alternate" hreflang="zh-hant" href="http://sale.mingluji.com/zh-hant/node/2628" /> <xhtml:link rel="alternate" hreflang="hr" href="http://sale.mingluji.com/hr/node/2628" /> <xhtml:link rel="alternate" hreflang="cs" href="http://sale.mingluji.com/cs/node/2628" /> <xhtml:link rel="alternate" hreflang="da" href="http://sale.mingluji.com/da/node/2628" /> <xhtml:link rel="alternate" hreflang="nl" href="http://sale.mingluji.com/nl/node/2628" /> <xhtml:link rel="alternate" hreflang="en" href="http://sale.mingluji.com/node/2628" /> <xhtml:link rel="alternate" hreflang="eo" href="http://sale.mingluji.com/eo/node/2628" /> <xhtml:link rel="alternate" hreflang="et" href="http://sale.mingluji.com/et/node/2628" /> <xhtml:link rel="alternate" hreflang="fi" href="http://sale.mingluji.com/fi/node/2628" /> <xhtml:link rel="alternate" hreflang="fr" href="http://sale.mingluji.com/fr/node/2628" /> <xhtml:link rel="alternate" hreflang="gl" href="http://sale.mingluji.com/gl/node/2628" /> <xhtml:link rel="alternate" hreflang="ka" href="http://sale.mingluji.com/ka/node/2628" /> <xhtml:link rel="alternate" hreflang="de" href="http://sale.mingluji.com/de/node/2628" /> <xhtml:link rel="alternate" hreflang="el" href="http://sale.mingluji.com/el/node/2628" /> <xhtml:link rel="alternate" hreflang="hu" href="http://sale.mingluji.com/hu/node/2628" /> <xhtml:link rel="alternate" hreflang="is" href="http://sale.mingluji.com/is/node/2628" /> <xhtml:link rel="alternate" hreflang="ga" href="http://sale.mingluji.com/ga/node/2628" /> <xhtml:link rel="alternate" hreflang="it" href="http://sale.mingluji.com/it/node/2628" /> <xhtml:link rel="alternate" hreflang="ja" href="http://sale.mingluji.com/ja/node/2628" /> <xhtml:link rel="alternate" hreflang="ko" href="http://sale.mingluji.com/ko/node/2628" /> <xhtml:link rel="alternate" hreflang="lv" href="http://sale.mingluji.com/lv/node/2628" /> <xhtml:link rel="alternate" hreflang="lt" href="http://sale.mingluji.com/lt/node/2628" /> <xhtml:link rel="alternate" hreflang="mk" href="http://sale.mingluji.com/mk/node/2628" /> <xhtml:link rel="alternate" hreflang="ms" href="http://sale.mingluji.com/ms/node/2628" /> <xhtml:link rel="alternate" hreflang="mt" href="http://sale.mingluji.com/mt/node/2628" /> <xhtml:link rel="alternate" hreflang="fa" href="http://sale.mingluji.com/fa/node/2628" /> <xhtml:link rel="alternate" hreflang="pl" href="http://sale.mingluji.com/pl/node/2628" /> <xhtml:link rel="alternate" hreflang="pt-pt" href="http://sale.mingluji.com/pt-pt/node/2628" /> <xhtml:link rel="alternate" hreflang="ro" href="http://sale.mingluji.com/ro/node/2628" /> <xhtml:link rel="alternate" hreflang="ru" href="http://sale.mingluji.com/ru/node/2628" /> <xhtml:link rel="alternate" hreflang="sr" href="http://sale.mingluji.com/sr/node/2628" /> <xhtml:link rel="alternate" hreflang="sk" href="http://sale.mingluji.com/sk/node/2628" /> <xhtml:link rel="alternate" hreflang="sl" href="http://sale.mingluji.com/sl/node/2628" /> <xhtml:link rel="alternate" hreflang="es" href="http://sale.mingluji.com/es/node/2628" /> <xhtml:link rel="alternate" hreflang="sw" href="http://sale.mingluji.com/sw/node/2628" /> <xhtml:link rel="alternate" hreflang="sv" href="http://sale.mingluji.com/sv/node/2628" /> <xhtml:link rel="alternate" hreflang="th" href="http://sale.mingluji.com/th/node/2628" /> <xhtml:link rel="alternate" hreflang="tr" href="http://sale.mingluji.com/tr/node/2628" /> <xhtml:link rel="alternate" hreflang="uk" href="http://sale.mingluji.com/uk/node/2628" /> <xhtml:link rel="alternate" hreflang="vi" href="http://sale.mingluji.com/vi/node/2628" /> <xhtml:link rel="alternate" hreflang="cy" href="http://sale.mingluji.com/cy/node/2628" /> <lastmod>2016-01-13T03:23Z</lastmod><changefreq>monthly</changefreq></url> ......
注意:
- xmlns:xhtml="http://www.w3.org/1999/xhtml" 这个一定要加,否则Google Webmaster Tools中会有报错:Unbound XML namespace prefix. The XML Sitemap cannot be parsed because it contains one or more unbound namespace prefixes. For example, this error is generated when <xhtml:link> is found in a Sitemap without prior xmlns:xhtml="http://www.w3.org/1999/xhtml";
- 另外,默认英语的网站也要作为一项xhtml:link加入。
相关配套工作:
- 修改Drupal网站中sitemap设置,把Number of links in each sitemap page改为1000(乘以50种语言就可能让尺寸达到5万个页面的大小,具体修改命令:drush vset xmlsitemap_chunk_size '1000',更多变量:xmlsitemap_prefetch_aliases=1、xmlsitemap_batch_limit=100、xmlsitemap_minimum_lifetime=86400等),以便重新生成的sitemap文件不大于10M(sitemap的规范是不超过5万页面和10M文件大小);
- 在页面中多语言网站之间用rel="alternate" hreflang="x"链接起来的办法以前就实施了,现在也不用变,sitemap和页面中都指明对应关系;
- 修改robots.txt,去掉以前的每种语言一个sitemap的链接,只保留默认语言的一个;
- 在Google Webmaster Tools中删除以前批量提交的每种语言一个sitemap,只保留默认语言的一个;
- 修改.htaccess文件,让以前其它语言的sitemap访问301重定向到默认的sitemap;
RewriteCond %{REQUEST_URI} ^\/(.+)\/sitemap\.xml(.*)$
RewriteRule ^(.*)$ /sitemap.xml%2 [L,R=301]
这个办法已经在一个站点尝试,等观察一段时间,没有问题再推广到更多的站点。
2016年3月22日补充:以上办法可以实现,但因为保存的sitemap文件每个都是以前的大约50倍,会导致占用硬盘空间非常大,于是考虑用以前的方式,不修改xmlsitemap.xmlsitemap.inc而是修改xmlsitemap.pages.inc来实现:
while (!feof($fd)) { //jamesqi 2016-3-22//print fread($fd, 1024*16); // modify start $line_input = fgets($fd); if ($line_input == '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'."\n") { $line_output = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">'."\n"; } elseif (substr($line_input,0,10) == '<url><loc>') { $loc_start = strpos($line_input,'<loc>')+5; $loc_end = strpos($line_input,'</loc>')-1; $loc_url = substr($line_input, $loc_start, $loc_end-$loc_start+1); global $base_url; $add_url = substr($loc_url, strlen($base_url)); $languages = language_list('enabled'); $languages_array = $languages[1]; $language_default = language_default($property = 'language'); $xhtml_link = ''; foreach ($languages_array as $key => $value) { $lang_code = $key; if ($lang_code != $language_default) { $lang_url = "$base_url/$lang_code$add_url"; } else { $lang_url = "$base_url$add_url"; } $xhtml_link .= "\n\t<xhtml:link rel=\"alternate\" hreflang=\"$lang_code\" href=\"$lang_url\" />"; } $line_output = str_replace('</loc>',"</loc>$xhtml_link\n",$line_input); } else { $line_output = $line_input; } print "$line_output"; // modify end } fclose($fd);
这样生成在硬盘上的.xml文件就与以前总的尺寸差不多,只是在输出的时候加上50种语言的网址。
另外,如果要关闭cron期间生成xmlsitemap,可以运行drush vset xmlsitemap_disable_cron_regeneration '1'。
如果在大数据量站点生成网站地图的时候遇到报错,可以参考这篇博文《Drupal生成xml sitemap过程中报错的解决》。
评论