I create a new content with Spanish as "Original language" and after that, I add the translation for English.

http://example.com/es/contenido-de-ejemplo (Original Language)
http://example.com/en/content-example

Both links should be included in its sitemap.xml generated by language.

Sitemap for Spanish: http://example.com/es/sitemap.xml
Sitemap for English: http://eample.com/en/sitemap.xml

http://example.com/es/contenido-de-ejemplo (Original Language) is included in its sitemap (domain/es/sitemap.xml). However its translation is not included in domain/en/sitemap.xml

Any idea how to make xmlsitemap module get all contents (originals and translations)?

Thanks!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jagundez created an issue. See original summary.

multidimension’s picture

Hello,

I have the same problem when using different domains:

https://shoppinginromania.ro/sitemap.xml
https://shoopinginromania.com/sitemap.xml

Most Articles have translations. The articles are different content types.

Best regards.

Skin’s picture

Same problem

(Original Language) is included in its sitemap (domain/es/sitemap.xml). However its translation is not included in domain/en/sitemap.xml
multidimension’s picture

After debugging the module in detail I observed this is not build to use translations at all. The reason for this is that it's using the entity id with the node type as a primary key, so even if you force a translated entity it will identify and overwrite the previous language. To handle this I did the following:

1) in xmlsitemap.module I modified the xmlsitemap_xmlsitemap_process_entity_links function to handle translations:

function xmlsitemap_xmlsitemap_process_entity_links($entity_type, array $ids) {
	
  $entities = entity_load_multiple($entity_type, $ids);
  $anonymous_user = new AnonymousUserSession();

  foreach ($entities as $entity) {
    $link_storage = \Drupal::service('xmlsitemap.link_storage');
    $link = $link_storage->create($entity);
    $link_storage->save($link);
	if($entity_type == "node" || $entity_type == "taxonomy_term")
	{
		$languages = \Drupal::languageManager()->getLanguages();
		$current_language = $entity->language()->getId();
		foreach($languages as $language){
			if($current_language != $language->getId())
			{	
			  try{
				$translation = $entity->getTranslation($language->getId());
				$link_storage = \Drupal::service('xmlsitemap.link_storage');
				$link = $link_storage->create($translation, $language->getId());
				$link_storage->save($link);
			  }catch(Exception $e){
				  //handle exceptions;
			  }
			}
		}
	}
  }
}

In src/XmlSitemapLinkStorage.php I was forced to modify the create method to handle a different id, by appending the language id as well.

 public function create(EntityInterface $entity,$is_translation = false) {
    if (!isset($entity->xmlsitemap)) {
      $entity->xmlsitemap = array();
      if ($entity->id() && $link = $this->load($entity->getEntityTypeId(), $entity->id())) {
        $entity->xmlsitemap = $link;
      }
    }

    $settings = xmlsitemap_link_bundle_load($entity->getEntityTypeId(), $entity->bundle());
    $uri = $entity->url();

    $entity->xmlsitemap += array(
	'type' => $entity->getEntityTypeId(),
	'id' => (string) $entity->id(),
	'subtype' => $entity->bundle(),
	'status' => $settings['status'],
	'status_default' => $settings['status'],
	'status_override' => 0,
	'priority' => $settings['priority'],
	'priority_default' => $settings['priority'],
	'priority_override' => 0,
	'changefreq' => isset($settings['changefreq']) ? $settings['changefreq'] : 0,
    );
	

    if (method_exists($entity, 'getChangedTime')) {
      $entity->xmlsitemap['lastmod'] = $entity->getChangedTime();
    }

    $url = $entity->url();
    // The following values must always be checked because they are volatile.
    $entity->xmlsitemap['loc'] = $uri;
    $entity->xmlsitemap['access'] = isset($url) && $entity->access('view', $this->anonymousUser);
    $language = $entity->language();
	if($is_translation == false){
		$entity->xmlsitemap['language'] = !empty($language) ? $language->getId() : LanguageInterface::LANGCODE_NOT_SPECIFIED;
	}else{
		$id = (string) $entity->id();
		$id .= '_'.$is_translation;
		$entity->xmlsitemap['id'] = $id;
		$entity->xmlsitemap['language'] = $is_translation;
	}
	
    return $entity->xmlsitemap;
  }

Please use this at your own risk, but for me it is working properly: http://shoppinginromania.ro/sitemap.xml and http://shoppinginromania.com/sitemap.xml

Lukas von Blarer’s picture

@multidimension could you please create a patch?

multidimension’s picture

I will try. I am very limited in terms of time. Also I am not sure this is the best method, but for the time being this works with existing websites. For new websites I would suggest looking into a schema update as well or adding a separate indexing as a primary key.

Himanshu5050’s picture

Patch to support for content translation as in #4

Himanshu5050’s picture

manuel.adan’s picture

For multilingual sites, simple_sitemap works perfectly. I found it after spent several hours trying to make xmlsitemap run on a multilingual site with no success.

leymannx’s picture

Assigned: jagundez » Unassigned
Priority: Normal » Major
Status: Active » Needs review
leymannx’s picture

For what I can see, nearly everything is in 8.x-1.x-dev now. Only thing missing was the $is_translation = false parameter from public function create() so that later this variable is undefined.

leymannx’s picture

leymannx’s picture

Priority: Major » Normal
Dave Reid’s picture

Do we even need the patch in #11 now?

Dave Reid’s picture

Status: Needs review » Closed (works as designed)
a.milkovsky’s picture

Our SEO expert says, that we still should generate one sitemap per language. This SEO thing is always confusing.
I will just leave my patch here. It provides a new option "Include non-existent translations".

olambert’s picture

Hello,

<<>>

We have the same kind of problems.
We have 3 domains and each domain has 2 or 3 languages (see below).
The default language is English (common to the 3 domains).
The 2 other languages are not properly indexed into Google.
I am confused with all comments and changes.
I have three questions:

1) Should we create specific sitemaps by languages?
2) Which module(s) and patch(es) would you install for this?
3) How to make a language more important for a specific country?

Thanks community !!

www.abcompany.be/fr
www.abcompany.be/nl (more important language)
www.abcompany.be/en

www.abcompany.fr/fr (more important language)
www.abcompany.fr/en

www.abcompany.nl/nl (more important language)
www.abcompany.nl/en