How can I exclude specific nodes from the sitemap programmatically?

Created on 15 May 2022, over 2 years ago
Updated 27 November 2023, 12 months ago

Problem/Motivation

I have configured a content type (Article) to automatically be included on the sitemap.

However, there are a few nodes that I want to exclude from the sitemap programmatically (because I am importing nodes using the Feeds module).

Based on this post , I tried the following code in hook_node_presave():

      $generator = \Drupal::service('simple_sitemap.generator');
      $generator->entityManager()->setEntityInstanceSettings('node', $node->id(), ['index' => false]);

However, when I open the node edit page, the node is still set to be indexed. What more do I need to do to exclude the node from the sitemap?

💬 Support request
Status

Fixed

Version

4.1

Component

Documentation

Created by

🇯🇵Japan ptmkenny

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇨🇦Canada phjou Vancouver 🇨🇦 🇪🇺

    Go the same issue as #11, I had to use a form alter to achieve it.

    In my case I had a field_enable_redirect, but you can change to use whatever custom behavior you need.

    function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
        if ($form_state->getFormObject() instanceof EntityFormInterface) {
            $entity = $form_state->getFormObject()->getEntity();
    
            if ($entity instanceof ContentEntityInterface && !$entity->isNew() && $entity->hasField('field_enable_redirect')) {
                $form['actions']['submit']['#validate'][] = '::validateForm';
                $form['actions']['submit']['#validate'][] = 'admin_helper_redirect_form_validate';
            }
        }
    }
    
    function mymodule_redirect_form_validate(&$form, FormStateInterface $form_state) {
        $entity = $form_state->getFormObject()->getEntity();
    
        if ($entity instanceof ContentEntityInterface && !$entity->isNew() && $entity->hasField('field_enable_redirect')) {
            $field_enable_redirect = $form_state->getValue('field_enable_redirect');
    
            // Change the value of the sitemap index setting when there is a
            // redirect.
            if ($field_enable_redirect['value'] == 1) {
                $sitemap_index = $form_state->getValue('simple_sitemap');
                $sitemap_index['default']['index'] = 0;
                $form_state->setValue('simple_sitemap', $sitemap_index);
            }
        }
    }
    
    
  • 🇫🇷France JulienVey

    The issue described in #11 is due to the module simple_sitemap overwritting the variant with the value of the form_state. Basically the node gets excluded in your hook_entity_presave() and then gets included again in the EntityFormHandler.php of the module.

    #14 does the trick, but it means your node will be excluded two times : one in the EntityFormHandler.php and one in your hook_entity_presave().

    One solution is to unset the value :)
    The function of @phjou then becomes :

    /**
     * Exclude from sitemap when there is a redirection.
     */
    function mymodule_redirect_form_validate(&$form, FormStateInterface $form_state) {
        $entity = $form_state->getFormObject()->getEntity();
    
        if ($entity instanceof ContentEntityInterface && !$entity->isNew() && $entity->hasField('field_enable_redirect')) {
            // Exclusion will be processed in precreate function.
            // Clear the value so that it does not get overwritten by simple_sitemap module.
            if ($form_state->getValue('field_enable_redirect')['value']) {
                $form_state->unsetValue('field_enable_redirect')
            }
        }
    }
    
Production build 0.71.5 2024