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.
Comment | File | Size | Author |
---|---|---|---|
#58 | 2044621-58.patch | 5.92 KB | alt.dev |
| |||
#55 | interdiff-2044621-53-55.txt | 510 bytes | gordon |
#55 | 2044621-55.patch | 5.84 KB | gordon |
#52 | metatag-parent_overrides-8-2044621-52.patch | 5.25 KB | vacho |
#51 | metatag-parent_overrides-8-2044621-51.patch | 5.19 KB | bgilhome |
Comments
Comment #1
DamienMcKennaThis 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.
Comment #2
rooby CreditAttribution: rooby commentedThinking 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.
Comment #3
rooby CreditAttribution: rooby commentedHere 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?
Comment #3.0
rooby CreditAttribution: rooby commentedAdding extra info.
Comment #4
rooby CreditAttribution: rooby commentedThis version applies to latest dev and fixes a couple of warning messages that were coming from the code in the old version.
Comment #7
jeffdiecks CreditAttribution: jeffdiecks commentedComment #8
mrjmd CreditAttribution: mrjmd commentedReroll attached.
Comment #10
tomogden CreditAttribution: tomogden commentedI 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.
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.
Comment #11
tomogden CreditAttribution: tomogden commentedI am submitting a patch that does the following two things:
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:
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.
Comment #12
rooby CreditAttribution: rooby commentedCan 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.
Comment #13
rooby CreditAttribution: rooby commentedOh 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.
Comment #14
DamienMcKennaHere'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).
Comment #15
rooby CreditAttribution: rooby commentedMy 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.
Comment #16
DamienMcKennaThis would be a definite change in the current architecture so would require some sort of backwards compatibility to not skew existing sites.
Comment #17
rooby CreditAttribution: rooby commentedWell 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.
Comment #18
DamienMcKennaClosed a duplicate: #2536104: Defaults and IF [token] empty then [token]
Comment #19
rooby CreditAttribution: rooby commentedSetting back to needs review based on #17.
Comment #20
rooby CreditAttribution: rooby commentedActually my initial patch needs a reroll.
Comment #21
rooby CreditAttribution: rooby commentedHere is the reroll.
Comment #23
DamienMcKennaThe tests need to be updated.
Comment #24
rooby CreditAttribution: rooby commentedWill do.
Comment #25
joelcollinsdc CreditAttribution: joelcollinsdc commentedDoesn't apply against 1.13 or 1.x-dev
Comment #26
chishah92 CreditAttribution: chishah92 at Blisstering Solutions commentedComment #27
chishah92 CreditAttribution: chishah92 at Blisstering Solutions commentedRerolled the Patch
Thanks!
~Chirag
Comment #29
mvcComment #30
rooby CreditAttribution: rooby commentedHere is a re-roll for latest dev. Still needs tests.
Comment #31
timcosgrove CreditAttribution: timcosgrove at Pinterest commentedIn 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.
Comment #32
timcosgrove CreditAttribution: timcosgrove at Pinterest commentedAfter 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.
Comment #33
gg4 CreditAttribution: gg4 commentedComment #34
MichelleI tested the patch in #32 with the following:
The patch applied but was offset a bit so I uploaded a new one with no other changes.
Comment #36
MichelleI 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.
Comment #38
DamienMcKennaSeems this needs a bit of work, thanks for rerolling it Michelle.
Comment #39
beram CreditAttribution: beram as a volunteer and at Ekino commentedThere 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.
Comment #40
Kasey_MK CreditAttribution: Kasey_MK commentedUpdating the patch in #39, which worked for me until I updated to Drupal 8.7.7 and Metatag 1.10.0
Comment #41
anacolautti CreditAttribution: anacolautti commentedThank you very much Kasey_MK!!!
Comment #42
andreyjan CreditAttribution: andreyjan at FFW commentedAdding the failing test and the test with the fix patches.
Comment #43
justcaldwellPerhaps 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:
Comment #44
justcaldwellAfter 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.
Comment #45
alexdmccabeUpdated the patch to work with metatag_page_manager.
Other sub-modules may need updating, too.
Comment #46
AID_UA CreditAttribution: AID_UA at DevBranch commentedDisabled empty values overriding on routes other than canonical (for e.g. on editing pages).
Overriding works only on the frontend.
Comment #47
AID_UA CreditAttribution: AID_UA at DevBranch commentedFIxed the interdiff filename.
Comment #48
Sutharsan CreditAttribution: Sutharsan at LimoenGroen commentedRerolling patch #46
@AID_UA, what problem does your change fix? The description that you provide only describes the solution.
Comment #49
balis_m CreditAttribution: balis_m commentedPatch from #48 works well.
Comment #50
kim.pepperComment #51
bgilhome CreditAttribution: bgilhome commentedIn 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.
Comment #52
vacho CreditAttribution: vacho at Skilld commentedPatch #48 rerolled.
I cant reroll the Patches for #51,0 also was rerolled for another issue.
Comment #54
bburgPatch 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.
Comment #55
gordon CreditAttribution: gordon at Heydon Consulting for Department of Customer Service, NSW commentedHere is a small PHP 8.1 fix. Basically strpos() no longer accepts NULL as the haystack (parameter 1)
Comment #56
ckngTested patch #55, works well.
Comment #57
dgsiegel CreditAttribution: dgsiegel commentedPatch #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:
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.Comment #58
alt.dev CreditAttribution: alt.dev at DevBranch, Drupal Ukraine Community, Evolving Web commentedI 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.