Starting this as a support request.

If I have a global OG image tag outputting a default site image and then for my content types I have a more specific tag that uses the image in an image field.

If that image field has no image in it I get no OG image tag.

I think it would be useful in this case for the global image to override the empty value.

Now I understand maybe not everyone wants this behaviour but maybe it could be optional as I think a lot of people would want it for things like this image tag.

For a start, is this behaviour currently possible? It seems like it is not.

CommentFileSizeAuthor
#58 2044621-58.patch5.92 KBalt.dev
#55 interdiff-2044621-53-55.txt510 bytesgordon
#55 2044621-55.patch5.84 KBgordon
#52 metatag-parent_overrides-8-2044621-52.patch5.25 KBvacho
#51 metatag-parent_overrides-8-2044621-51.patch5.19 KBbgilhome
#48 metatag-parent_overrides-8-2044621-48.patch5.29 KBSutharsan
#47 interdiff_45_46.txt1.75 KBAID_UA
#46 interdiff_45_46.patch1.75 KBAID_UA
#46 metatag-parent_overrides-8-2044621-46.patch5.28 KBAID_UA
#45 interdiff_42-45.txt603 bytesalexdmccabe
#45 metatag-parent_overrides-8-2044621-45.patch4.7 KBalexdmccabe
#42 metatag-parent_overrides-8-2044621-42.patch4 KBandreyjan
#42 metatag-parent_overrides-8-2044621-42-TEST_ONLY.patch2.09 KBandreyjan
#40 metatag-parent_overrides-8-2044621-40.patch1.91 KBKasey_MK
#39 interdiff_36-39.txt526 bytesberam
#39 metatag-parent_overrides-8-2044621-39.patch1.78 KBberam
#36 metatag-parent_overrides-8-2044621-36.patch1.78 KBMichelle
#34 metatag-parent_overrides-8-2044621-34.patch1.78 KBMichelle
#32 metatag-parent_overrides-8-2044621-32.patch1.78 KBtimcosgrove
#31 metatag-parent_overrides-8-2044621-31.patch1.58 KBtimcosgrove
#30 metatag-parent_overrides-2044621-30.patch6.5 KBrooby
#27 metatag-parent_overrides-2044621-27.patch6.78 KBchishah92
#21 metatag-parent_overrides-2044621-21.patch6.48 KBrooby
#11 unset_empties-2044621-12.patch2.39 KBtomogden
#8 metatag-parent_overrides-2044621-8.patch6.48 KBmrjmd
#4 metatag-parent_overrides-2044621-4.patch6.47 KBrooby
#3 metatag-parent_overrides-2044621-3.patch6.47 KBrooby
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

DamienMcKenna’s picture

Version: 7.x-1.0-beta7 » 7.x-1.x-dev
Category: support » feature

This is one of the difficulties of using Token - the logic checks to see if fields are empty before applying the token rather than after. This is something I need to look into.

rooby’s picture

Thinking out load a little here.

At a quick look it seems like one problem is the metatag_config_load_with_defaults() function, which does a union of the config arrays, starting with the most specific and ending with the global.

This union means that you are basically going to get the entirety of the most specific config all the time because the config array is almost the same between instances. Values left empty in the more specific instance will override a non-empty value in the global one.

On top of that, what metatag_config_load_with_defaults() returns is a single array of raw values so if those values end up empty after token replacement you don't have the parent value available to use.

Seeing as the metadata config is cached, it could be feasible to load the parent configs into the cache as well as just the specific instance config and then use them after token replacement as required.

Either that or metatag_config_load_with_defaults() could return an array of config arrays, from specific to global, instead of just the most specific.

Then maybe before hook_metatag_metatags_view_alter() is invoked in metatag_metatags_view() there could be a check for empty values where it falls back to the parent and tries getElement() again.

Seems it might sometimes be desirable to have empty values though and not fall back to the parent. In which case maybe the global fields should be left empty? or else the alternative is to have a setting for each metatag to specify whether or not the parent can override an empty value.

rooby’s picture

Status: Active » Needs review
FileSize
6.47 KB

Here is a proof of concept that adds the ability to make each individual metatag allow overrides at the instance level.

If a metatag is set to allow overrides and is left empty or token replacements render it empty, then it will check the parent instance for a metatag.

If the parent is also empty and also allows overrides the process continues.

It could probably do with a bit of refactoring and it doesn't take into acount the fact that the allow override setting is useless on the global instance, but it shows a possible solution.

What do you think?

rooby’s picture

Issue summary: View changes

Adding extra info.

rooby’s picture

Issue summary: View changes
FileSize
6.47 KB

This version applies to latest dev and fixes a couple of warning messages that were coming from the code in the old version.

Status: Needs review » Needs work

The last submitted patch, 4: metatag-parent_overrides-2044621-4.patch, failed testing.

jeffdiecks’s picture

Issue tags: +Needs reroll
mrjmd’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll +SprintWeekend2015
FileSize
6.48 KB

Reroll attached.

Status: Needs review » Needs work

The last submitted patch, 8: metatag-parent_overrides-2044621-8.patch, failed testing.

tomogden’s picture

I think an "override" is not strong enough. If a saved default field is emptied, one would expect it should no longer have any effect.

From what I can see, Metatag already does the following:
1) If a node's metatag field is not filled in, that tag is not saved, and the tag inherits from the parent defaults. I think this is already the case.
2) If a saved default field is not filled in, that tag is not saved, and the tag inherits from the parent default.

Thus, it should logically follow (but does not):
3) If a previously saved field is emptied, that tag should be dropped from the default record, and it should revert back to the above behavior.

To me, not following Rule 3 is a bug.

Seems it might sometimes be desirable to have empty values though and not fall back to the parent. In which case maybe the global fields should be left empty? or else the alternative is to have a setting for each metatag to specify whether or not the parent can override an empty value.

While it may be desirable to have defaults overriden by a NULL value, this should be the exception, not the rule. Thus, if there IS an override control, it should be to override inherited text with a NULL value. But my guess is it's not too common to want to empty or reduce your metatags. Usually people go overboard in the other direction.

tomogden’s picture

Title: Allow parent config to override empty values of more specific config » Metatag forms save empty field values which block default inheritance.
Category: Feature request » Bug report
Status: Needs work » Needs review
FileSize
2.39 KB

I am submitting a patch that does the following two things:

  1. Prevents Metadata from saving empty fields.
  2. Prevents empty field values previously saved in the database from blocking parent configurations.

While this meets the functional requirements to prevent the unexpected behavior, it does not improve the UX, which can still confuse users. For that, I would propose THREE new things:

  1. Adding an [empty] token (or something like it).
  2. Filling the fields' 'default_value' with that configuration's saved values (imagine that), instead of the aggregated parent values.
  3. Placing the aggregated parent values into the fields' 'placeholder' so that they display in gray and are replaced when clicking into the field.

These should remove all the ambiguity currently confusing users. I think I also see a number of related issues posted which may be likewise resolved.

Then we can talk about deprecating the shell game operation in Metadata where the aggregated parent values are deleted from each field just before they are saved.

rooby’s picture

Can you clarify whether your patch is intended to replace the original patch here or if it is to go with it?

If the former then it should go in a new issue because that is not what this issue is actually about.

If the latter I will try to find some time to review it and roll it all into a single patch.

rooby’s picture

Oh I just also noticed your change of issue title.

I will try your patch and see if it fixes my original issue but I think yours is a different issue.

DamienMcKenna’s picture

Status: Needs review » Closed (won't fix)

Here's a problem - how is Metatag supposed to know if you are trying to reset a value to its default or you just don't want to output a specific meta tag?

I'm closing this in favor of #1798984: Improve meta tag form to clearly distinguish between overriding or reverting the default value (D9).

rooby’s picture

Title: Metatag forms save empty field values which block default inheritance. » Allow parent config to override empty values of more specific config
Status: Closed (won't fix) » Needs review

My original intention for this issue got a little hijacked.
Since I got no reply from my last question I'm reverting the title.

My proposal was that if there is something entered into a child metatag field and then after token replacement that value is empty (no field value), then if the override option is selected for that specific meta tag it will try using the parent one.

My interface put a checkbox for every metatag so you could specifically enable the parent override at the tag level. Admittedly the UI could use a little love but I didn't want to spend too much time yet in case there's no chance of it being committed. I could make it nicer.

I most commonly use this patch for images so that I can set facebook og images to an image field and default to a generic site image if there is none for the given node.
Seems to work fine.

#8 is the last iteration of this patch. I will test shortly to see if it needs a reroll but if you still want to close this feel free, although I think it will be hard for me to write an add-on module to achieve this.

DamienMcKenna’s picture

Category: Bug report » Feature request
Status: Needs review » Needs work

This would be a definite change in the current architecture so would require some sort of backwards compatibility to not skew existing sites.

rooby’s picture

Well the default settings result in the status quo. It's only once you start checking the check boxes that functionality starts to differ, so this should not affect existing sites.

DamienMcKenna’s picture

rooby’s picture

Status: Needs work » Needs review

Setting back to needs review based on #17.

rooby’s picture

Status: Needs review » Needs work

Actually my initial patch needs a reroll.

rooby’s picture

Status: Needs work » Needs review
FileSize
6.48 KB

Here is the reroll.

Status: Needs review » Needs work

The last submitted patch, 21: metatag-parent_overrides-2044621-21.patch, failed testing.

DamienMcKenna’s picture

The tests need to be updated.

rooby’s picture

Will do.

joelcollinsdc’s picture

Issue tags: +Needs reroll

Doesn't apply against 1.13 or 1.x-dev

chishah92’s picture

Assigned: Unassigned » chishah92
chishah92’s picture

Status: Needs work » Needs review
FileSize
6.78 KB

Rerolled the Patch

Thanks!
~Chirag

Status: Needs review » Needs work

The last submitted patch, 27: metatag-parent_overrides-2044621-27.patch, failed testing.

mvc’s picture

rooby’s picture

Here is a re-roll for latest dev. Still needs tests.

timcosgrove’s picture

In https://www.drupal.org/project/metatag/issues/2850537#comment-12139609, jts86 (https://www.drupal.org/u/jts86) provided a simple patch that takes care of this for 8.x-1.x.

That patch no longer applies, but the code in it seems to do what is required here, i.e. allow a parent metatag to render if a token returns empty.

Since this works for some use cases, I rerolled it against 8.x-1.x and am posting it here.

timcosgrove’s picture

After using the above for a bit, I found that it's problematic to attempt to do token replacements on a new entity without IDs as some entity-based tokens expect them and don't check for them. I've updated the patch with an isNew() check.

Emphasizing that this is not intended as a solution to the larger problem here, but it does potentially grant the ability to let parent tokens take over if child tokens return empty.

gg4’s picture

Version: 7.x-1.x-dev » 8.x-1.x-dev
Assigned: chishah92 » Unassigned
Michelle’s picture

Status: Needs work » Needs review
FileSize
1.78 KB

I tested the patch in #32 with the following:

  • On admin/config/search/metatag/global set the "Description" basic tag to a string.
  • On admin/config/search/metatag/node set the "Description" basic tag to [node:body]
  • Added a node and included text in the body.
  • Checked the metatags and saw the text from the body.
  • Added a node and did _not_ include text in the body.
  • Checked the metatags and the "Description" tag was not present.
  • Applied the patch.
  • Refreshed the second node and saw the "Description" tag now had the string from the global setting.
  • Edited the node and added body text.
  • Checked the metatags and saw "Description" now had the new body text.
  • Edited again and removed the body text.
  • Checked the metatags and saw it was back to the global string.

The patch applied but was offset a bit so I uploaded a new one with no other changes.

Status: Needs review » Needs work

The last submitted patch, 34: metatag-parent_overrides-8-2044621-34.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Michelle’s picture

Status: Needs work » Needs review
FileSize
1.78 KB

I applied the coder fix patch above but it added a . a the end of a commented out line of code that isn't even part of this patch so I removed that. This patch includes the other fix.

Status: Needs review » Needs work

The last submitted patch, 36: metatag-parent_overrides-8-2044621-36.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

DamienMcKenna’s picture

Seems this needs a bit of work, thanks for rerolling it Michelle.

beram’s picture

There was an issue with last patches. It did not take into account the tags from the bundle.

Attach a patch and interdiff to fix this.

I'll try to take care of the tests soon.

Kasey_MK’s picture

Updating the patch in #39, which worked for me until I updated to Drupal 8.7.7 and Metatag 1.10.0

anacolautti’s picture

Thank you very much Kasey_MK!!!

andreyjan’s picture

Adding the failing test and the test with the fix patches.

justcaldwell’s picture

Perhaps this is by design, but I just wanted to point out that the behavior in 1.10.0 (with patch #42 applied) has changed slightly from the previous expected results as described in comment #36. What I'm observing is easiest to explain with steps to reproduce:

  • On admin/config/search/metatag/global set the "Description" basic tag to a string.
  • On admin/config/search/metatag/node set the "Description" basic tag to [node:body]
  • Add a node without a body value.
  • Checked the metatags and "Description" is set to the default string value as expected.
  • Edit the node and add a value for body.
  • Checked the metatags and "Description" is still set to the default string. I would expect it to get set to the body value.
  • Add a second node with a value for body.
  • Checked the metatags and "Description" is set to the body value as expected.
  • Edit the second node and remove body value.
  • Checked the metatags and "Description" is null. I would expect it to revert to the default string.
justcaldwell’s picture

After some debugging, I see that the new behavior is due to #3045460: MetatagFirehose::formElement() should pass current entity explicitly to metatag_get_default_tags(). If I remove the explicit entity value introduced in that change, I get the behavior I expect.

So it seems the new behavior is maybe by design, but -- at least for my use case -- not desired/expected.

alexdmccabe’s picture

Updated the patch to work with metatag_page_manager.

Other sub-modules may need updating, too.

AID_UA’s picture

Disabled empty values overriding on routes other than canonical (for e.g. on editing pages).
Overriding works only on the frontend.

AID_UA’s picture

FileSize
1.75 KB

FIxed the interdiff filename.

Sutharsan’s picture

Rerolling patch #46

@AID_UA, what problem does your change fix? The description that you provide only describes the solution.

balis_m’s picture

Patch from #48 works well.

kim.pepper’s picture

Issue tags: +#pnx-sprint
bgilhome’s picture

In case anyone uses the patch at https://www.drupal.org/project/metatag/issues/2949963#comment-13929876, here's a re-roll of the patch here at #48 after the patch https://www.drupal.org/project/metatag/issues/2949963#comment-13929876a is applied.

vacho’s picture

Patch #48 rerolled.

I cant reroll the Patches for #51,0 also was rerolled for another issue.

Status: Needs review » Needs work

The last submitted patch, 52: metatag-parent_overrides-8-2044621-52.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

bburg’s picture

Patch in #52 does not apply cleanly to the 1.30 release.

Edit: I'm dumb, of course that's meant for the 8.x+ version.

gordon’s picture

Here is a small PHP 8.1 fix. Basically strpos() no longer accepts NULL as the haystack (parameter 1)

ckng’s picture

Status: Needs work » Needs review

Tested patch #55, works well.

dgsiegel’s picture

Patch #55 does not seem to work with a headless approach. Metatags will be saved in the computed field. In a normal approach, where Drupal is rendering the output, the patch overwrites empty tags with global defaults:

// Merge with global defaults.
if (strpos($route_name, 'canonical') !== FALSE) {
  $metatags->overwriteTags(metatag_filter_empty_tokens($entity_metatags->get('tags'), $entity));
}

However when saving to the computed field, the route is not canonical and so global defaults are left untouched. When accessing JSON:API, only the computed field gets accessed and no merge can happen at that time.

alt.dev’s picture

I confirm that the patch doesn't work with the JSON:API module.

I updated the latest patch and added the fix for the computed field.