Metatag only works if you've added a custom tag on the source.

Created on 17 April 2024, 12 months ago
Updated 18 April 2024, 12 months ago

Problem/Motivation

I think this is a problem with compatibility with Metatag 2.0+, given this issue:
https://www.drupal.org/project/metatag/issues/3413201 πŸ› Field metatag empty on graphql Active

There the maintainer explains that the "field_metatag" field will only have values in it if you've customized your values somehow. He encourages the reporter to use the "metatag" field instead of the "field_metatag". Meanwhile, this module only supports the "Metatag (Metatag field only) (Entity Share)" field enhancer on the "field_metatag" field. For me, a lot of my "field_metatag" fields are "null" so things like the Server site's canonical url are not passed to the Client site (it falls back to [node:url] which points to the client site).

Steps to reproduce

1. Use Metatag 2.0.0, Entity Share 3.0.0, and JsonAPI Extras 3.24.0 (these are the lastest releases right now)
2. Enable "Metatag (Metatag field only) (Entity Share)" field enhancer on the Entity Share Server
3. Create a node (in my example the bundle is type="person"). Do not customize the metatags in any way, just use what's provided.
4. Visit the jsonapi url, like /jsonapi/node/person/[UUID]
5. See that the value of "field_metatags" is NULL even though there are values in the "metatag" attribute.
6. Incidentally, see that the Canonical URL when pulling in the person is set to the Client domain, not the Server domain.

Proposed resolution

I'm planning on writing a custom ImportProcessor to pull the metatag field values from the "metatag" attribute instead of the "field_metatag" attribute for myself. I don't know if this is the best way to solve the issue though -- perhaps it would be better to make the existing "Metatag (Metatag field only) (Entity Share)" field enhancer field work with the "metatag" field? That second option would require some kind of update hook though, likely.

Remaining tasks

Decide on approach
Create/apply patch

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Active

Version

3.0

Component

Entity Share Server

Created by

πŸ‡ΊπŸ‡ΈUnited States mariacha1

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

Comments & Activities

  • Issue created by @mariacha1
  • πŸ‡ΊπŸ‡ΈUnited States mariacha1

    This isn't a robust-enough solution to be a patch, but here's the ImportProcessor I'm using in my custom module if it's useful for other people:

    <?php
    
    declare(strict_types=1);
    
    namespace Drupal\mymodule\Plugin\EntityShareClient\Processor;
    
    use Drupal\Core\Form\FormStateInterface;
    use Drupal\Core\Plugin\PluginFormInterface;
    use Drupal\entity_share_client\ImportProcessor\ImportProcessorPluginBase;
    use Drupal\entity_share_client\RuntimeImportContext;
    use Symfony\Component\DependencyInjection\ContainerInterface;
    
    /**
     * Import book structure.
     *
     * @todo This can be deprecated if
     * https://www.drupal.org/project/entity_share/issues/3441672 is fixed.
     *
     * @ImportProcessor(
     *   id = "metatag_importer",
     *   label = @Translation("Use Server Canonical link"),
     *   description = @Translation("Get the Canonical url from the Metatag attribute on the Server."),
     *   stages = {
     *     "prepare_importable_entity_data" = 20,
     *   },
     *   locked = false,
     * )
     */
    class MetatagImporter extends ImportProcessorPluginBase implements PluginFormInterface {
    
      /**
       * The entity type manager.
       *
       * @var \Drupal\Core\Entity\EntityFieldManagerInterface
       */
      protected $entityFieldManager;
    
      /**
       * {@inheritdoc}
       */
      public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
        $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
        $instance->entityFieldManager = $container->get('entity_field.manager');
        return $instance;
      }
    
      /**
       * {@inheritdoc}
       */
      public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
        return $form;
      }
    
      /**
       * {@inheritdoc}
       */
      public function prepareImportableEntityData(RuntimeImportContext $runtime_import_context, array &$entity_json_data): void {
        if (isset($entity_json_data['attributes']['metatag'])) {
          // Find out if there's a Metatag type field on the node.
          $parsed_type = explode('--', $entity_json_data['type']);
          $entity_type_id = $parsed_type[0];
          $entity_bundle = $parsed_type[1];
          $entity_fields = $this->entityFieldManager->getFieldDefinitions($entity_type_id, $entity_bundle);
          $metatag_field = NULL;
    
          foreach ($entity_fields as $id => $field) {
            if ($field->getType() === 'metatag') {
              $metatag_field = $id;
            }
          }
          if ($metatag_field && $entity_json_data['attributes'][$metatag_field] === NULL) {
            foreach ($entity_json_data['attributes']['metatag'] as $value) {
              if (isset($value['attributes']['rel']) &&  $value['attributes']['rel'] === 'canonical') {
                $entity_json_data['attributes'][$metatag_field] = [
                  'value' => [
                    'canonical_url' => $value['attributes']['href'],
                  ],
                ];
              }
            }
          }
        }
      }
    
    }
    
    

    This would be enabled as a plugin called "Use Server Canonical link" at the import config level under `/admin/config/services/entity_share/import_config`.

Production build 0.71.5 2024