Problem/Motivation

Drupal Canvas has some basic built-in integration features with Metatag. Canvas also does not support various advanced form structures and thus has errors trying to save an Canvas page when metatag is actually enabled. However Canvas has test coverage to ensure it works with Metatag and the basic fields it provides end up in metatags.

Steps to reproduce

  1. Install xb-demo.
  2. Install Metatag.
  3. Form will show up fine, with the tokens popup possible to open, etc. Until stuff is entered into the metatag group

  4. When stuff is entered into the metatag group, an error about the Robots fields shows in the page

  5. Page cannot be saved due to Robots error.

I believe these problems are not due to Metatag but Canvas' limited capability of handling certain form fields.

For reference these are the metatag related bits in Canvas that I found:

  • CanvasPageForm creates the seo_settings form group which is NOT conditional to metatag module existing. It adds the description and image base fields to this group. Those fields exist as base fields on the page entity regardless of metatag module being there or not.
  • THEN there is a entityBaseFieldInfo in Drupal\experience_builder\Hook::PageHooks that conditionally creates the metatags base field if metatag module is installed. Sets it as provided by metatag module.
  • CanvasPageForm moves $form['metatags']['widget'][0]['basic']['title'] into the seo settings group but does not do any other wiring between the image and description and metatag data (I assume metatag module does this built-in)
  • Finally Drupal\Tests\experience_builder\Kernel\Entity::PageMetatagIntegrationTest tests that with metatag enabled values entered in the title, description and image do show up in the meta fields. It also theoretically tests that the form can be saved without violations, but that is not actually the case based on the above demonstration.

Proposed resolution

As basic metatag features work and Canvas even has a test for them, I suggest as a stop-gap to disable the more advanced features of Metatag in Canvas and let it deal with the basic meta information for now. When Canvas becomes more capable, the more advanced forms could be resurrected.

Remaining tasks

User interface changes

API changes

Data model changes

Issue fork metatag-3531991

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Issue fork canvas-3531991

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

gábor hojtsy created an issue. See original summary.

gábor hojtsy’s picture

Added screenshot.

gábor hojtsy’s picture

Issue summary: View changes

Added more info on which bits are metatag code in XB.

damienmckenna’s picture

Status: Active » Needs review

I wonder would removing the field from the advanced section resolve the problem instead? That's an option on the field widget.

catch’s picture

Why not fix this in experience builder?

gábor hojtsy’s picture

Status: Needs review » Needs work

@catch: I think its also fine to do something along these lines in XB. As said this is a stop-gap.

@damienmckenna: XB adds the metatags field as a base field, and it is set as internal but also configurable (see code snippet below) :D I don't think there is a way to actually configure this, it does not show up on admin/reports/fields and also XB does not have a way to edit the fields on XB entities (by design I think).

Does metatag need the field to be present to pull from the description and image base fields for metadata? The only thing that XB pulls out of this for its own SEO settings is $form['metatags']['widget'][0]['basic']['title'].

I think "out of the advanced section" in code terms if sidebar FALSE? When I tried that it merely made the metatag fields show up above the SEO settings section. Same problem with robots field then though :)

  #[Hook('entity_base_field_info')]
  public function entityBaseFieldInfo(EntityTypeInterface $entity_type): array {
    $fields = [];
    if ($entity_type->id() === Page::ENTITY_TYPE_ID) {
      if ($this->moduleHandler->moduleExists('metatag')) {
        $fields['metatags'] = BaseFieldDefinition::create('metatag')
          ->setLabel(new TranslatableMarkup('Metatags'))
          ->setDescription(new TranslatableMarkup('The meta tags for the entity.'))
          ->setTranslatable(\TRUE)
          ->setDisplayOptions('form', [
            'type' => 'metatag_firehose',
            'settings' => ['sidebar' => \TRUE, 'use_details' => \TRUE],
          ])
          ->setDisplayConfigurable('form', \TRUE)
          ->setDefaultValue(Json::encode([
            'title' => '[xb_page:title] | [site:name]',
            'description' => '[xb_page:description]',
            'canonical_url' => '[xb_page:url]',
            // @see https://stackoverflow.com/a/19274942
            'image_src' => '[xb_page:image:entity:field_media_image:entity:url]',
          ]))
          ->setInternal(\TRUE)
          ->setProvider('metatag');
      }
    }
    return $fields;
  }

Does XB really need the metatags field on the entity for metatag to work? The easiest would be to not even have the field on :)

gábor hojtsy’s picture

StatusFileSize
new129.31 KB

This is with sidebar FALSE :)

damienmckenna’s picture

XB shouldn't be doing weight things like that via hook_entity_base_field_info, it should just add the field via Field API.

catch’s picture

Project: Metatag » Experience Builder
Version: 2.1.x-dev » 0.x-dev
Category: Task » Bug report

I think this should be fixed in experience builder, the whole 'hardcoded metatags field' in hook_base_field_info() seems wrong as @Damien points out.

Additionally it's not obvious whether that field will be removed correctly if metatag is uninstalled so there may be deeper issues going on than just a broken form alter.

gábor hojtsy’s picture

Let me repeat the key question: Does metatag [module] need the [full metatag] field to be present to pull from the description and image base fields for metadata?

wim leers’s picture

Component: User interface » Page
Assigned: Unassigned » mglaman

Matt built this integration, asking him to analyze and propose next steps.

mglaman’s picture

XB crashed before due to the firehose widget. Our team uses this hook:

/**
 * Implements hook_form_FORM_ID_alter().
 */
function OURMODULE_form_xb_page_form_alter(array &$form, FormStateInterface $form_state): void {
  $form['metatags']['widget'][0]['#type'] = 'container';
  $form['metatags']['widget'][0]['basic']['#type'] = 'container';
  $form['metatags']['widget'][0]['basic']['description']['#access'] = FALSE;
  $form['metatags']['widget'][0]['basic']['abstract']['#access'] = FALSE;
  $form['metatags']['widget'][0]['basic']['keywords']['#access'] = FALSE;
  $form['metatags']['widget'][0]['preamble']['#access'] = FALSE;
  $form['metatags']['widget'][0]['tokens']['#access'] = FALSE;
  $form['metatags']['widget'][0]['intro_text']['#access'] = FALSE;
  $form['metatags']['widget'][0]['image_help']['#access'] = FALSE;
}
gábor hojtsy’s picture

StatusFileSize
new66.95 KB

@mglaman: with that alter the basic elements go away as expected, the closeable metatags section becomes a non-closeable Advanced but the robots checkboxes are still there and therefore lead to the error described. Is that the full extent of the alter you use? All these fields are still present with that alter hook from #13 which I doubt you all expose to users @mglaman :) I'm using metatag 2.1.1.

gábor hojtsy’s picture

Adding related issue in #3526130: \Drupal\experience_builder\ClientDataToEntityConverter::setEntityFields doesn't work with booleans outside of boolean field that may cause the checkbox to not work. Even if that would work I think "metatag" working fine is not quite leaving every single field as-is in the sidebar, so lacking further product direction I think leaving all but the XB base field provided (image / description) SEO stuff out for now would be much better. Otherwise (even if the checkboxes then work fine) enabling metatag throws this massive amount of form elements, most of which are quite confusing and super advanced.

That said, until the checkboxes get fixed we do need a workaround that keeps metatag working IMHO.

damienmckenna’s picture

Does metatag [module] need the [full metatag] field to be present to pull from the description and image base fields for metadata?

No, Metatag can just use tokens in a global configuration to generate meta tags for content entities based upon those few fields, so removing the Metatag field for now would probably be the best bet.

gábor hojtsy’s picture

@damienmckenna: are these mappings possible to reproduce in a global config somehow? I think the reason for the field is to use these mappings for xb metadata (unless explicit settings otherwise).

          ->setDefaultValue(Json::encode([
            'title' => '[xb_page:title] | [site:name]',
            'description' => '[xb_page:description]',
            'canonical_url' => '[xb_page:url]',
            // @see https://stackoverflow.com/a/19274942
            'image_src' => '[xb_page:image:entity:field_media_image:entity:url]',
          ]))
damienmckenna’s picture

The idea with Metatag is to define defaults for each entity type at the global level using tokens to pull in values from the entities. Take a look at Configuration → Search and metadata → Metatag, and customize the configuration for each entity type. You can also override the entity type configuration on a per bundle basis via the "Add default meta tags" page, so that e.g. different content types could have slightly different values based upon the fields available. In theory this should cover most scenarios, especially if you have a few fields on the entity type/bundle for a summary/description and a thumbnail image. IMHO most sites don't need the Metatag field on content types, they should leverage the defaults, fields and tokens.

Also, if you add the Token OR module you can have either-or logic within each token, useful for setting a failover default if a field isn't filled in.

gábor hojtsy’s picture

Status: Needs work » Needs review

Had a zoom meeting with Lauri where I showed him the current state. XB has an opinion on what basic SEO fields should be shown and implements all of them as base fields (except the SEO title). So the metatag field is mostly used to wire in the token replacements as shown above in #17. I understand this could be in global config for this entity type. Lauri told me that keeping the field would still be better as it would give the option to create a custom, simpler widget for more complicated SEO settings in the future. I think the field could still be added then, but my aim is to solve metatags not working with XB, not to argue about architecture :)

So attaching a few lines of added code that alters out the metatag section of the form at the existing place where it moves the SEO title field. This works for me, although I don't have the SEO title field somehow in metatag 2.1.1 that I have, so not sure if that would be affected by the #access even though it is moved out of the group. I think for this stop-gap issue that is the remaining question.

gábor hojtsy changed the visibility of the branch 3531991-experience-builder-has to hidden.

damienmckenna’s picture

Lauri told me that keeping the field would still be better as it would give the option to create a custom, simpler widget for more complicated SEO settings in the future.

I originally planned to build a new widget for making it possible to customize which meta tags were shown on the edit form, but realized it was pointless when you could just add regular fields and then use tokens to output the tags as necessary.

I don't believe there's any benefit to the Metatag field as it is currently implemented, it feels like it was added as a misunderstanding of how & why it works; my recommendation would be to remove it and just use tokens in the global configurations.

gábor hojtsy’s picture

Status: Needs review » Needs work

I understand that @damienmckenna. I don't have an opinion either way, so I personally leave considering that to @lauriii and/or other code owners in this area of XB :) My main aim is to make metatag and XB work peacefully together, I don't have architectural opinions about this, trying to help with whatever is needed :)

gábor hojtsy’s picture

The remaining fails are around #edit-seo-settings #edit-metatags-0-basic-title of course. I still did not find where this one comes from metatag, but access false-ing the parent does make this inaccessible apparently.

Would be good to get a clear answer from the XB team whether the field should stay and further altering should be put into place (as in #13 but that does not list all the items, see #14) or the field should be removed (which does sound like would be the cleaner solution IMHO).

gábor hojtsy’s picture

StatusFileSize
new2.29 KB

Re #13, basically this was missing in my MR compared to #13. I don't think this should be committed as-is but this does make metatag work with XB and not emit any scary widgets :)

      $form['metatags']['widget'][0]['advanced']['#access'] = FALSE;

Also adding the current diff file for composer patching purposes.

damienmckenna’s picture

I opened #3544662: Remove custom Metatag implementation which would be my recommendation instead of continuing to hack around the current issues.

gábor hojtsy’s picture

Project: Experience Builder » Drupal Canvas
Version: 0.x-dev » 1.x-dev

Moving to Canvas.

gábor hojtsy’s picture

Title: Experience builder has limited built-in metatag features, disable advanced form fields there as initial stop-gap » Drupal Canvas has limited built-in metatag features, disable advanced form fields there as initial stop-gap
Issue summary: View changes

Also update title and issue summary.

gábor hojtsy’s picture

StatusFileSize
new2.3 KB

Patch for Canvas for composer patching. I merely do this to maintain xb-demo, not to take sides in what is the best solution.

lauriii’s picture

StatusFileSize
new90.39 KB

I originally planned to build a new widget for making it possible to customize which meta tags were shown on the edit form, but realized it was pointless when you could just add regular fields and then use tokens to output the tags as necessary.

The point is not necessarily to configure which fields are available but to allow user to choose which metatags they want to provide. This is relevant specifically for pages because they contain unstructured data and the different metatags needed might vary page by page.

Other benefit is that metatag is also specific to the actual HTML that get printed vs fields which would be an abstraction away from the HTML tags. This would make it challenging to implement preview for metatags like we have here:

gábor hojtsy changed the visibility of the branch 0.x to hidden.

gábor hojtsy changed the visibility of the branch 3531991-experience-builder-has to hidden.

gábor hojtsy’s picture

Status: Needs work » Needs review
gábor hojtsy’s picture

Neither the phpstan nor the playwright fails are related to this issue, so I think the (basic) MR is ready for review :) If we want to keep the widget in a selective form, we'll need to start from a more strict place, because the lots of advanced elements are too much that appear without this patch :)

wim leers changed the visibility of the branch 1.x to hidden.

wim leers’s picture

Assigned: mglaman » Unassigned
Status: Needs review » Reviewed & tested by the community

Per @lauriii: he's been working closely with @pameeela, @mglaman and others, and this is the best middle ground for now.

wim leers’s picture

These were loose ends introduced by #3487077: Page has Metatag integration. The MR here does not make things worse.

wim leers’s picture

Title: Drupal Canvas has limited built-in metatag features, disable advanced form fields there as initial stop-gap » `Page` has limited built-in metatag features, disable advanced form fields there as initial stop-gap
Assigned: Unassigned » lauriii
Status: Reviewed & tested by the community » Patch (to be ported)

Per #37, @lauriii will provide the necessary background information as to why this is the appropriate middle ground right now.

catch’s picture

wim leers’s picture

@catch Lauri indicated that that issue was a no-go, that this one should be merged, which is what I alluded to in #37. I don't have more detail than that either. @lauriii was going to post that. 👍