Port the meta tag length trimming system from D7 to D8.

Issue fork metatag-2958193

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

DamienMcKenna created an issue. See original summary.

damienmckenna’s picture

damienmckenna’s picture

For anyone who needs a temporary solution, try this:

/**
 * Implements hook_page_attachments_alter().
 */
function mysite_page_attachments_alter(array &$attachments) {
  // Trim all meta tags to a max of 300 characters.
  if (!empty($attachments['#attached']['html_head'])) {
    // Adjust this as needed.
    $max_length = 300;
    foreach ($attachments['#attached']['html_head'] as &$tag) {
      // Only process meta tags with a 'content' attribute, that way it will
      // exclude LINK tags or meta tags which do not have a "content" value.
      if (isset($tag[0]['#tag']) && $tag[0]['#tag'] == 'meta') {
        if (isset($tag[0]['#attributes']['content'])) {
          if (!is_string($tag[0]['#attributes']['content'])) {
            $tag[0]['#attributes']['content'] = (string) $tag[0]['#attributes']['content'];
          }
          if (strlen($tag[0]['#attributes']['content']) > $max_length) {
            // Trim the string three characters shorter than the max so that
            // there is room for the elipses.
            $string = wordwrap($tag[0]['#attributes']['content'], ($max_length - 3));
            $string = explode("\n", $string);
            $tag[0]['#attributes']['content'] = $string[0] . '...';
          }
        }
      }
    }
  }
}
zenimagine’s picture

@DamienMcKenna In which file should you place the code ? thank you

eugenechechel’s picture

@zenimagine in your module file

zenimagine’s picture

thank you but I do not have the level to create a custom module. I will wait for a patch

damienmckenna’s picture

FYI wordwrap() will break UTF8 code, use Unicode::substr() instead.

nikhileshpaul’s picture

Thanks for the code Damien. I haven't tried your code yet, but wouldn't wordwrap() just wrap the string instead of trimming it. I'm using a combination of substr() and trim() BTW.

damienmckenna’s picture

The explode() line breaks the paragraph up into separate lines, and then the $string[0] variable uses the first line. It's a little messy, but it works.

zenimagine’s picture

@DamienMcKenna The comment code #3 is to be placed in the theme or in a custom module ?

damienmckenna’s picture

If you check the hook_page_attachments_alter() you'll see it's listed in theme.api.php, which means it can be in either a module or a theme.

zenimagine’s picture

@DamienMcKenna Thank you, it's great it works. Since the time I'm bored by the length of the description with SEO

anybody’s picture

Still an important feature for the UI. This was wonderfully simple in D7. Thank you @DamienMcKenna for the workaround!

alison’s picture

I came here from #3102875 and then #3106609 which are also, and I didn't want to continue on those closed threads, but I realize this might be out of scope here, so, well, sorry about that! I just wanted to find out (without starting another issue):
Is it true that the enforcement of max length 255 chars on description/abstract fields was introduced in 1.11, or?

Thank you!

rkelbel48’s picture

Is this request still a possibility as it would be ideal to not have to use a hook and for this functionality to be within the module. Just wondering if anyone was able to take another look at this issue/request?

zenimagine’s picture

This demand has been around for years and it is a serious problem for natural referencing. It's really crazy that this module continues to evolve without having solved this major problem. This is the basis of natural referencing. How is it possible not to solve such a problem? It is necessary to pass by the code so that this module is usable without pouring the referencing of the site.

zenimagine’s picture

I wonder if Wordpress is not a more serious project than Drupal.

zenimagine’s picture

In 2030 the problem will not be solved, yet it is the basis of this module and of referencing. Why is it primarily normal?

damienmckenna’s picture

@zenimagine: Slagging off the many contributors to this because of something you feel should be fixed is not a good way of getting people to contribute towards solving that problem. Maybe contribute in a positive way towards the solution yourself, or if you can't maybe organize funding for it, would be a more productive use of your time.

anybody’s picture

StatusFileSize
new79.71 KB

This is the old Drupal 7 settings form (expected functionality):
deserved behaviour
(German)

Should we discuss which fields to handle?
And I guess it would make sense to put those settings on a separate page, not together with the current entity type settings?

Grevil made their first commit to this issue’s fork.

anybody’s picture

Our team member Joshua will have a look at this soon and add a first implementation as MR.
@DamienMcKenna your chance to add some further specifications or have a look at the questions in my last reply (sorry I added them later on by edit).

So he knows how to start :) Looking very much forward to this small but helpful improvement.

damienmckenna’s picture

@Anybody: Thank you, that's pretty wonderful that your company is sponsoring the work!

The D7 version shows how it should work - the new options should go onto the settings page, and should be a global setting per meta tag rather than managed in the field settings.

anybody’s picture

Thank you @DamienMcKenna! :)

We were discussing how to structure the schema for the new settings and came up with this extension to metatag.settings.schema.yml:

metatag.settings:
  type: config_object
  label: 'Metatag settings'
  mapping:
    entity_type_groups:
      type: sequence
      label: 'Metatag groups that apply to each entity type'
      sequence:
        type: sequence
        label: 'Entity type'
        sequence:
          type: sequence
          label: 'Bundle'
          sequence:
            type: string
            label: 'Group'
    tag_trim_method:
      type: integer
      label: 'Trim method for trimmable tags.'
    tag_trim_maxlength:
      type: sequence
      label: 'Tag-specific maximum length'
      sequence:
        type: integer
        label: 'Tag maximum length in characters'

This way limits can be dynamically added per tag type.

I'm not yet sure here, if this flexible implementation is perfect, but we'll see.

The tag classes (like Drupal\metatag\Plugin\metatag\Tag\Title) will be extended by a new attribute "trimmable" and boolean annotation, which defines, if a tag is trimmable and listed to be trimmable thereby. This is for example true for Title and Description (and similar from contrib).

If no maxlength is entered, there will be no trimming so that existing sites won't be affected. I guess for install we could set typical defaults.

MetaNameBase will implement the trimming in the output() method.

Feedback welcome. Implementation is in progress.

@Grevil could you please assign this issue to yourself?

grevil’s picture

Component: User interface » Features integration
Assigned: Unassigned » grevil
grevil’s picture

Component: Features integration » Code
grevil’s picture

Hey everybody! This is Josh, I would like to present everybody our approach of implementing trimming options to the metatag options form. Following, you can see a Chacklist for whats currently implemented :

- [x] Implemented methods and add settings to trim a metatag on a given value, before a word on the given value, after a word on the given value
- [x] Added a trimmable option for further metatag module additions
- [x] Added trimmable to "description" and "length" metatags
- [x] Implemented a metatag maxlength option for every 'MetaNameBase' type where 'trimmable' = TRUE
- [] Write Tests

If there are any questions or additions, feel free to add them, I'm still farely new to Drupal module development, so any suggestions would be appreciated! :)

anybody’s picture

Status: Active » Needs review

8.x-1.x is the fork to review. I guess @Grevil committed into the wrong branch from the fork.

anybody’s picture

Assigned: grevil » Unassigned

Thank you @Grevil!! :) Looking forward to the tests tomorrow, then hope for many reviews to get this important feature back to Drupal 8 / 9.

damienmckenna’s picture

Status: Needs review » Needs work

This is great, I really appreciate you for working on this!

One item I would recommend is that the trim method feels like it's unnecessary, it would be better to just trim everything the same way so there's less confusion with the new functionality.

anybody’s picture

Hi @DamienMcKenna,

thank you very much for your super fast feedback! We discussed that before and I think the option makes sense (with a typical default) as you may discuss which trimming way is right for the page.

These are the options:

      '#options' => [
        'truncate_after' => t('Trim the Meta Tag value after the word on the given character position'),
        'truncate' => t('Trim the Meta Tag value exactly on the given character position (maybe within a word)'),
        'truncate_before' => t('Trim the Meta Tag value before the word on the given character position'),
      ],

(TODO @Grevil please change the titles accordingly and better use a string index instead of a number, I think. Like in the example above.)

At least option "0" or "2" shouldn't be hardcoded, I would say.

Some perhaps would like to have some further characters after the limit, others cut off before... cutting within the word is surely an edge-case. Would you make a hard decision here @DamienMcKenna? What would be your choice?

In the end, of course, you as maintainer decide, but I think it's an improvement to the hard D7 logics I would have loved to exist before.

anybody’s picture

@DamienMcKenna as we're no native English speakers, is "trim" okay here or better use "truncate" instead everywhere?

damienmckenna’s picture

I guess I don't see the benefit of trimming different meta tags with different logic, it seems overkill.

One minor thing about the merge request - three are a number of changes where someone's text editor removed the last period in sentences contained in comments, those changes should be reverted.

anybody’s picture

One minor thing about the merge request - three are a number of changes where someone's text editor removed the last period in sentences contained in comments, those changes should be reverted.

Thanks, yes that's already on @Grevils radar.

I guess I don't see the benefit of trimming different meta tags with different logic, it seems overkill.

No no, the option is global. Only one setting. Sorry for the confusion.
Only the number of chars is per tag.

@Grevil will post a screenshot of the Admin UI.

grevil’s picture

StatusFileSize
new20.35 KB

@DamienMcKenna sry for the confusion. As @Anybody said, the trimming options are global for every tag. There are only metatag specific options for the length. See the screenshot where the description and title metatag have an added trimmable value.

FYI: The periods should be added again in the last merge. If for some reason they are not, they will be added later together with the Tests.

grevil’s picture

Status: Needs work » Needs review
grevil’s picture

Ok, everything should be finalised now. If there are any questions or some Tests / Functions need to be moved / reworked, please let me know @DamienMcKenna :)

damienmckenna’s picture

Status: Needs review » Needs work
Parent issue: » #3203686: Plan for Metatag 8.x-1.17

I went through this again and it is excellent work, thank you!

The only minor items are some coding standards fixes that need to be made - check the testbot output for details. Otherwise, this is ready to go.

anybody’s picture

Whao, thank you so much, Damien! We're really happy and proud of your compliments!

@Grevil will fix the coding standards very soon :)

grevil’s picture

On it!

grevil’s picture

Status: Needs work » Needs review

Alright, fixed all Drupal coding standard issues.

@DamienMcKenna, note that there are in general a lot of deprecated testing methods used in the metatag tests outside of the trimming test methods!

damienmckenna’s picture

@Grevil: Excellent, thank you. And yes, I know there are a lot of deprecated code in the tests, we'll work on updating it soon.

  • DamienMcKenna committed 0137a12 on 8.x-1.x authored by Grevil
    Issue #2958193 by Grevil, Anybody, DamienMcKenna, nikhileshpaul:...
damienmckenna’s picture

Status: Needs review » Fixed

Committed! Thanks to everyone for helping with this, especially Grevil for putting together the code changes.

damienmckenna’s picture

Title: Automatically trim meta tag lengths (D8) » Automatically trim meta tag lengths (D9)

Status: Fixed » Closed (fixed)

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