Currently there is no way to change the output of the link xml. This was in part my solution to #451234 Support for extended sitemap formats (e.g. video, news, image, mobile), but could be useful in other situations too.

If we provide a hook in xmlsitemap_generate_chunk() then was can pass the element array(xml entry of a link) off to other modules to alter before creating the xml.

Comments

carinadigital’s picture

Here's a patch and an an example module adding in some static video information for video sitemaps.

jon nunan’s picture

Issue summary: View changes
StatusFileSize
new3.62 KB

Coming back to this, because the job I'm working on needed to make the sitemap like this because of our SEO team (grumbles):
https://support.google.com/webmasters/answer/2620865?hl=en

Having our sites for every region talk to each other is well outside the scope of this module, so I created my own custom solution to do it. Problem being though I was unable to output it as the method writeSitemapElement doesn't allow for attributes.

This patch adds the hook and allows writeSitemapElement to print out XML tags with attributes.

An example usage of

/**
 * Implements hook_xmlsitemap_item_extend().
 */
function CUSTOM_MODULE_xmlsitemap_item_extend($item) {
  $element = array();
  $element['#name'] = 'xhtml:link';
  $element['#attributes'] = array(
    'rel' => 'alternate',
    'hreflang' => $locale,
    'href' => $item['loc'],
  );
  $item['xhtml:link_' . $locale] = $element;
  return $item;
}

I clipped some of the example for space, mainly taking out the for loop that does it multiple times for each locale, but the result means I get an output like:

<url><loc>http://www.flightcentre.com.au/world-travel/australia</loc><lastmod>2014-04-01T03:47Z</lastmod><changefreq>yearly</changefreq>
<xhtml:link rel="alternate" hreflang="en-AU" href="http://www.mysite.com.au/world-travel/australia"/>
<xhtml:link rel="alternate" hreflang="en-NZ" href="http://www.mysite.co.nz/world-travel/australia"/></url>

Again I know the locale stuff is out of scope, this is just an example of what this hook and method rewrite allows.

udhaya kumar’s picture

StatusFileSize
new4.27 KB

Attached Xmlsitemap.patch shoud work for version 7.x-2.0-rc2
An example usage of hook_xmlsitemap_item_extend()

<?php

/*
 *
 * Implementation of hook_xmlsitemap_item_extend()
 *
 * @param $element
 * The current element array that will be turned to xml.
 *
 * @param
 * The link information from xmlsitemap. Contains useful keys, to look up other information e.g. nid
 *
 *
 * @Return the changed $element array
 * Refer - Refer https://support.google.com/webmasters/answer/183668?hl=en
 *
 */
function MODULE_NAME_xmlsitemap_item_extend($element, $link){
  // Check if we are dealing with a node
  if ($link['type'] != 'node') {
    return $element;
  }

  $node = node_load($link['id']);

  switch ($link['subtype']) {
    case 'video':
       $element['video:video']=array(
        'video:title' => 'Custom title',
        'video:description' => 'Custom Description',
        'video:thumbnail_loc' => 'Thumbnail URL',
        'video:player_loc' => 'Video player location',
      );
    break;
    
    default:
    break;
  }

return $element;
}
?>
chadedge’s picture

Version: 7.x-2.0-beta3 » 7.x-2.x-dev
StatusFileSize
new1.1 KB

Adding a base drupal_alter hook with minimal impact.
Our company need was to alter the URL's saved by the XMLwriter only, without adding extra data like "video" to the elements.
Altered the initial query (including extra columns), and added the element_alter to the drupal_alter() call.

chadedge’s picture

Priority: Normal » Minor
StatusFileSize
new1.9 KB

Updated the patch to better comply with standards (added documentation to the API). Functionally the same patch, just a notation update from my previous submission.
This patch replaces my previous.

eojthebrave’s picture

Status: Active » Needs review
StatusFileSize
new4.67 KB

Here's my version of the patch started here. This patch adds two hooks, hook_xmlsitemap_root_attributes_alter() and hook_xmlsitemap_element_alter() which allow you to alter the XML that's about to be generated an add additional information.

This doesn't necessarily solve #451234: Support for extended sitemap formats (e.g. video, news, image, mobile) but it does make it pretty easy to write your own custom module that implements a couple of hooks and includes the required data. With this patch I had no problem adding the elements to my sitemap.

The code here is mostly the same as the patches above, but it adds documentation and better adherence to the Drupal coding standards. Thanks for the ideas about how to make this work everyone.

dave reid’s picture

Status: Needs review » Needs work
  1. +++ b/xmlsitemap.xmlsitemap.inc
    @@ -73,6 +73,9 @@ class XMLSitemapWriter extends XMLWriter {
    +    drupal_alter('xmlsitemap_root_attributes', $attributes);
    

    We should probably be passing in $this->sitemap as an argument here, or possibly just $this. This way modules that want to add attributes can do so if they only apply to a specific sitemap context.

  2. +++ b/xmlsitemap.xmlsitemap.inc
    @@ -173,6 +176,9 @@ class XMLSitemapIndexWriter extends XMLSitemapWriter {
    +    drupal_alter('xmlsitemap_root_attributes', $attributes);
    

    Same here.

dave reid’s picture

Status: Needs work » Needs review
StatusFileSize
new4.92 KB

Revised patch that ensure the sitemap object is passed through everywhere.

  • Dave Reid committed 571e79a on 7.x-2.x
    Issue #1370474 by carinadigital, chadedge, Dave Reid, Jon Nunan,...
dave reid’s picture

Version: 7.x-2.x-dev » 8.x-1.x-dev
Status: Needs review » Patch (to be ported)

Committed #8 to 7.x-2.x.

udhaya kumar’s picture

StatusFileSize
new4.34 KB

Attached Xmlsitemap.patch shoud work for version 7.x-2.0-rc2. Added hook xmlsitemap_item_element_alter and xmlsitemap_more_attributes. By implementing the hooks mentioned above in custom module, we should be able to extend xmlsitemap for image and video.

To extend image sitemap.

/*
 *
 * Implementation of hook_xmlsitemap_item_element_alter()
 *
 * @param $element
 * The current link array that will be turned to xml.
 *
 * @param
 * The link information from xmlsitemap. Contains useful keys, to look up other information e.g. nid
 * Refer - https://support.google.com/webmasters/answer/178636?hl=en
 *
 */
function MODULE_NAME_xmlsitemap_item_element_alter(&$element, $link) {
  switch ($link['subtype']) {
    case 'image':
      $node = node_load($link['id']);
      $element['image:image']['image:loc'] = url(file_create_url($node->field_image_name['und'][0]['uri']));
      $element['image:image']['image:title'] = t($node->title);
      if($node->field_caption['und'][0]['value']) {
        $element['image:image']['image:caption'] = t(($node->field_caption_name['und'][0]['value']));
      }
    break;

    default:
    break;
  }
}

/*
 * Implementation of hook xmlsitemap_more_attributes()
 * returns array() of sitemap main attributes.
*/
function MODULE_NAME_xmlsitemap_more_attributes() {
  $attributes['xmlns:image'] = 'http://www.google.com/schemas/sitemap-image/1.1';
  return $attributes;
}
pobster’s picture

Just providing a little extra here ... We required the ability to "drop" the element from the sitemap if its not aliased.

pobster’s picture

I then simply used;

// In a "hook_xmlsitemap_element_alter()".
if ($link['type'] == 'node' && strpos($link['loc'], 'node/') === 0) {
  $element = array();
}
Martin.’s picture

#8
// @todo Should this be moved to XMLSitemapWritier::writeSitemapElement()?

Yes, because I want to alter the operation when this element is added on xmlsitemap.xmlsitemap.inc file line 210. I would create a bacth but $link and $sitemap varaibles are not available inside writeSitemapElement() and changing the hook arguments would be an API change and this is probably not what we want.

$this->writeSitemapElement('sitemap', $element);

So maybe creating a new hook inside writeSitemapElement() would help ? Or making the hook dependant on the $name argument which is sent to writeSitemapElement as first parameter.

The reason behind this is that I need to change the new "chunk", "page" (call it whatever you want) element creation. Atm this is not possible cause the alter hook is not initialized.

EDIT:
It would also help if the hook is moved there and the default implementation is like this:

hook_xmlsitemap_element_alter(&$element, $link = '', $sitemap = '')

Instead of

hook_xmlsitemap_element_alter(&$element, $link, $sitemap)

This way it is still backward compatible but for those of us who want to alter other elements, it is then possible to use this hook every time an element is actually processed. (The $sitemap variable is also in $this actually, so it can be sent in the hook if needed.)

Martin.’s picture

StatusFileSize
new785 bytes

Forgot to mention earlier that this is for drupal 7
I created new patch which invokes the hook_xmlsitemap_element when generateXML is executed and before the element is sent to writeSitemapElement() It sends in empty link array on sitemap object from $this

evanjenkins’s picture

Needed to add hook_xmlsitemap_element_alter for D8.

WidgetsBurritos’s picture

Status: Patch (to be ported) » Needs review
StatusFileSize
new1.63 KB
new605 bytes

Based on @evanjenkins's patch in #16, I've also added in the change made by @pobster in #13.

WidgetsBurritos’s picture

One more patch here. The D7 patch exposed `type` and `subtype` to the hook, so I've added that here as well.

m4olivei’s picture

Thanks for the patch! Just one note, the D8 patch is missing hook_xmlsitemap_root_attributes_alter.

dave reid’s picture

StatusFileSize
new8.48 KB
new8.21 KB

We need to move the discussion about supporting hook_element_alter() being able to skip the current link to a new feature request, this issue should be focused on ensuring that the Drupal 8 version supports the same functionality as the Drupal 7 version.

Revised patch which adds the missing hook_xmlsitemap_root_attributes_alter(), hook documentation, and small fixes.

dave reid’s picture

@pobster: I think you still might be able to accomplish what you need just by using hook_xmlsitemap_link_alter(), and that way you avoid that link getting selected by the sitemap generation entirely, which would be better for performance. I don't see a need to support this additional feature in this patch.

/**
 * Implements hook_xmlsitemap_link_alter().
 *
 * Mark un-aliased nodes as unaccessible in the sitemap.
 */
function mymodule_xmlsitemap_link_alter(array &$link) {
  if ($link['type'] == 'node' && $link['access'] && strpos($link['loc'], 'node/') === 0) {
    $link['access'] = FALSE;
  }
}
dave reid’s picture

StatusFileSize
new9.12 KB

Fixing some coding standards.

  • Dave Reid committed e614903 on 8.x-1.x
    Issue #1370474 by Dave Reid, WidgetsBurritos, Udhaya Kumar, chadedge,...
dave reid’s picture

Status: Needs review » Fixed

Tested and committed #22 to 8.x-1.x.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.