Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Come up with a solution to allow the finalized Metatag meta data to be exposable via JSON API, et al.
Comment | File | Size | Author |
---|---|---|---|
#186 | metatag-n2945817-186.patch | 18.41 KB | robertom |
#179 | metatag-n2945817-179.interdiff.txt | 4.05 KB | DamienMcKenna |
#179 | metatag-n2945817-179.patch | 19.74 KB | DamienMcKenna |
#176 | metatag-n2945817-176.patch | 19.71 KB | DamienMcKenna |
#172 | metatag-n2945817-171.patch | 22.05 KB | DamienMcKenna |
|
Issue fork metatag-2945817
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:
- 2945817-data-type-support changes, plain diff MR !4
Comments
Comment #2
rutel95Comment #3
rutel95Comment #5
rutel95Comment #6
rutel95Change for jsonapi for 8.12
Comment #7
DamienMcKennaComment #9
DamienMcKennaYour IDE creates unusual patches, so I've recreated it.
Comment #10
DamienMcKennaComment #11
DamienMcKennaWould love to have someone with knowledge of JSON API test this.
Comment #12
phenaproximaUnfortunately, it yelled at me when I tried to install Drupal or rebuild the container on an already-installed site.
I'm not sure why the hell this is happening, because everything seems in order:
Comment #13
garphy CreditAttribution: garphy at ICI LA LUNE commentedReroll seems needed.
Comment #14
garphy CreditAttribution: garphy at ICI LA LUNE commentedPatch in #9 had the MetatagJsonApiNormalizer wrongly located (in "Normalizer" instead of "src/Normalizer").
Comment #15
ebeyrent CreditAttribution: ebeyrent at SciShield commentedThe interface for FieldItemNormalizerValue doesn't match what's here.
The interface for FieldNormalizerValue doesn't match what's here.
Comment #16
DamienMcKennaNeeds some changes per #15.
Comment #17
DamienMcKennaWhat is the "jsonapi_normalizer_do_not_use_removal_imminent" bit for?
Comment #18
GRO CreditAttribution: GRO commentedUpdated arguments passed to `FieldItemNormalizerValue` and `FieldNormalizerValue`.
I've followed the approach implemented here \Drupal\jsonapi\Normalizer\FieldNormalizer::normalize
@DamienMcKenna I only briefly looked at `jsonapi_normalizer_do_not_use_removal_imminent` and couldn't see an example of how to implement it.
Comment #19
GRO CreditAttribution: GRO commentedComment #20
amietpatial CreditAttribution: amietpatial as a volunteer and at gai Technologies Pvt Ltd for gai Technologies Pvt Ltd commented#18 Patch applied successfully and works fine
Comment #21
gargsuchi CreditAttribution: gargsuchi at Salsa Digital for Department of Premier and Cabinet - Victoria, Australia commentedPath reviewed - works as per the requirement.
Comment #22
simeBased on my test of the patch, the endpoint is displaying internal data that look like machine names and don't correlate to valid markup. I think this data needs some more normalisation.
What is "canonical_url"? Should it be a "meta" or a "link" tag. What is the the correct attribute to apply the value to? Now ask these questions for each of 100+ meta tags.
Comment #23
phenaproximaSorry to do this, but I would also argue that we should not be using the
jsonapi_normalizer_do_not_use_removal_imminent
service tag, because "do not use" is right there in the name of the tag. That tag is not an API; it's a temporary hack in JSON API, and it's going to be removed (at some point in the near future). Although the most recent patch does indeed stop the bleeding, we should try to find a better way to fix this in Metatag. I suggest we contact the JSON API maintainers and ask them what the best course of action here might be.Comment #24
simeSome code to ponder - this is how we solve it in absence of a better way. The last patch doesn't allow us to do this.
Our backend code already overrides `JsonApiDocumentTopLevelNormalizer` for other purposes, bear i mind this this class is deprecated, override at your own risk.
Frontend code is a simple handling of a drupal render array. I think it is input to the vue-meta plugin, but you get the idea. Thanks to Dan Laush.
Comment #25
joshua.boltz CreditAttribution: joshua.boltz commentedI have tried both the patches with no success with the following setup:
Drupal 8.5.3
Metatag 8.x-1.5
JSONAPI 8.x-1.18
After updating JSON API module to latest 8.x-1.22, which supposedly fixes the issues outlined in this issue:
https://www.drupal.org/project/jsonapi/issues/2888157
When I attempt to view the JSON API endpoint, I get this error:
If i remove the patch from this issue that adds the metatag support, I no longer get the error, but of course, I also no longer have the metatags output into the JSON API endpoint.
Things I've tried:
* Downgrading JSON API to earlier versions before 1.22 but after 1.18
* Using latest dev release of Metatag
* Seeing if any combo of the above works to both 1) work with no error 2) adds metatags to JSON API
* Tried both #14 and #18 patches
Comment #26
DamienMcKennaAnd this is why we add tests.
@joshua.boltz: thanks for the details.
Comment #27
robpowell@joshua.boltz and I did some troubleshooting. We determined that this patch works with jsonapi 8.x-1.21 and not with 8.x-1.22. The issue is that the context array in MetatagJsonApiNormalizer::normalize() does not have the key 'cacheable_metadata'. In JsonAPI .22, 'cacheable_metadata' was removed:
#2948666 is the ticket in which the key was removed and it has a lot of useful information around why that decision was made.
We determined that there was a change in jsonapi/src/Normalizer/JsonApiDocumentTopLevelNormalizer.php that no longer populated the context with the needed key.
Below are two screenshots from PHP storm show the stack trace and values in the context array.
JsonApiDocumentTopLevelNormalizer_22
JsonApiDocumentTopLevelNormalizer_21
I think the next step is determining how to get the required CacheableDependencyInterface for jsonapi/src/Normalizer/Value/FieldItemNormalizerValue.php.
Comment #28
robpowellAlright, I am going to push this back to needs work. After reviewing jsonapi, I think I found the right way to instantiate FieldItemNormalizerValue().
We still need a solution for #23, if someone could explain what we are doing in the service provider that would be helpful.
Comment #29
robpowellComment #30
robpowellNeeds work for #23
Comment #31
robpowellComment #32
gabesulliceHi all! I'm incredibly glad to see y'all trying to operate w/ JSON API :)
I think you're heading down the wrong rabbit hole (but you should be forgiven for it, the "right" way is not at all obvious).
Your normalizers should be operating on the TypedData level, not the field level. If they work that way, they will work for JSON API, GraphQL and REST without customization for any of them.
What does that mean though?
An entity like a tree, you have an entity object at the top, fields on that entity, every field is a list of field item, and a field item is composed of field properties (which must be TypedData properties). Finally, the value is stored on that property level.
Right now, your normalizers are working on the field item list level because that's the level they "support":
Drupal, JSON API and GraphQL already have standard normalizers for the entity and field list and field item levels. You don't need to override those. What all those existing normalizers do is just call
$serializer->normalize()
the the next layer down. You want to do your normalizers at the lowest possible level to have the most possible compatibility with any kind of normalization.Does that help?
Comment #33
slucero@gabesullice is exactly right in #32 about working within the Typed Data API instead. This will offer the most flexibility across the entire Drupal ecosystem since that API is a much lower level driver for many others built on top of it.
Another red flag I spotted worth noting was the return of a non-primitive value in the
normalize()
method. That breaks the interface definition for the normalizers which assume a simple value will be returned that can be passed directly into the encoder for writing out. I vaguely recall seeing an issue related to this same issue in other normalizers within jsonapi as well, so that may be a separate effort to address if it was something you were following by example. Either way though, @gabesullice's recommendation to use$serializer->normalize()
should resolve that issue since it allows any non-primitive values that still need to be handled to pass through the whole serialization system again and receive their own specific treatment.One excellent article to review that might help wrap your head around the overall serialization process and what is happing is this one: Drupal Serialization Step-by-Step.
Nice work so far everybody! There's a lot of movement in this space, so it's hard to hit the moving target.
Comment #34
gabesulliceThis is exactly why we introduced the
jsonapi_normalizer_do_not_use_removal_imminent
service tag and made all normalizers internal.We cordoned everything off above the TypeData level so that we could isolate our own wrong implementation and then refactor and do it "right". That process is not complete.
As of JSON API 2.x. It is impossible to add normalizers via this method.
You'll need to implement your normalizers on the TypedData level as I explained above and use the
normalizer
service tag, notjsonapi_normalizer_do_not_use_removal_imminent
tag.Comment #35
neclimdulI talked with Gabe and think I follow what he's laying down. I had to get this "fixed" since it completely breaks default_content's exports so I tossed together this quick patch. No tests and I only really tested it didn't break _other_ imports so not even really manually tested but it but I think gets things going in the right direction.
Comment #36
gabesulliceFWIW, I haven't looked at the new patch.
Just setting this so we get a test run.
Comment #37
-enzo- CreditAttribution: -enzo- at weKnow Inc for Department of Premier and Cabinet - Victoria, Australia commentedAfter a video session with @gabesullice, I did some changes to try to enable the normalizer with JSON 2.x
The problem I see is that the meta tags itself are not processes, and are not rendered in JSON API response.
Please if someone could test and let me know if the problem is related to Metatag logic or JSON API implementation logic., would be appreciated.
Comment #39
yobottehg CreditAttribution: yobottehg commented@-enzo- and @gabesullice i think the problem here is that metatag does not actually save the data in this field but only the overwrites.
So the actual output is calculated out of all defaults and the overwrites on rendering. And this does not happen here.
I think we will need to change the meta tag field to something like a computed field which does this and not render the metatags only in
metatag_get_tags_from_route
.Does this make sense?
Comment #40
DamienMcKennaI guess there are several issues here and they overlap in ways people don't quite understand:
The question that must be asked before additional work is done is: what's the actual goal of this functionality? Is the intention to show the overridden values when there is a Metatag field present on the entity, or is the intention to show all of the rendered meta tags for the entity? These are two very different goals.
Comment #41
gabesulliceAhhh, thanks @DamienMcKenna! I did not really look into what was actually going on in Metatag module. I was just trying to show how one has to implement normalizers for JSON API to use them.
To answer your question, I think the answer is a mix of both.
The current field should be a computed field which accepts new values so that metatags can be altered via an API. However, this should be a low priority done in a different issue. For now, I think the field needs to be marked internal so that it is not normalized by any web services.
In its place, I think the most important step is to add another computed field which shows all of the rendered meta tags for the entity so that decoupled applications can make use of them in a read-only capacity. This should be the highest priority of this issue.
Do others agree?
Comment #42
Wim Leers#39:
+1000
But based on what @DamienMcKenna wrote in #40, it sounds like we need a separate computed field to store not the override, but always computes the end result, or the existing field should be made to not only allow storing values, but also compute the value in case it has no stored value (which @gabesullice suggested in #41).
The architecture described in #40 makes sense given Drupal's history (and Metatag's), but it makes it impossible to use in decoupled use cases. In other words: Metatag is not yet API-First.
Comment #43
DamienMcKennaNo, because the field is not required in order to output meta tags for an entity, and I don't want to make it required.
True.
I'd be happy to hear ideas on how to make this work.
Comment #44
Wim LeersRight, the Metatag module is "entity-centric" if you will, and not "field-centric". But all entity data is modeled as fields. So the only way to add data to entities consistently, and in a way that is API-First, is to add a field.
I completely understand you don't want to require Metatag users to go and add a particular field to every entity type though! It also wouldn't make sense in the Field UI.
What if we add a computed field automatically through
hook_entity_(base|bundle)_field_info()
, for those entity types/bundles that have Metatag enabled?Comment #45
DamienMcKennaThat would be just fine!
One question is how we would control which entities would support this? Are there reasonable ways to identify which entities should be supported, to avoid unnecessary processing on entities where it makes no sense, e.g. blocks, paragraphs, etc?
Comment #46
Wim LeersAny fieldable entity type could support this.
Blocks aren't fieldable (
BlockContent
is,Block
isn't).Paragraph
is an interesting one. I guess I'd blacklistParagraph
for now, because it's such a special snowflake. I don't know the architectural details ofParagraph
well enough to make a recommendation for that.Comment #47
DamienMcKennaI guess the question should have been asked in reverse - how would we make sure the extra field is only added to entities where it's wanted so it doesn't show up in places that isn't necessary? In D7 there was a settings page to control the list of entities which were supported, unless you have other ideas we could just do that again.
Comment #48
Wim Leersno_ui = TRUE
just likeChangedItem
and other field types have. Or did you mean something else?Comment #49
DamienMcKennaI wasn't aware of that. Neato.
Comment #50
Wim Leers😃
Comment #51
Wim Leers@DamienMcKenna is currently in this week's API-First Initiative call. He brought up this issue, and asked for examples that do something like #44–#50.
I found that the "path" field is super close to what Metatag needs! 🎉 See
path_entity_base_field_info()
and\Drupal\path\Plugin\Field\FieldType\PathItem
. If you have the need for bundle-specific field definitions, you may want to look at https://www.drupal.org/node/2982512 too (8.7 only, so you may want to backport some of that).@e0ipso warned that there were some problems with JSON:API+
path
fields. I responded that I'm 90% certain this is due to language-specific path aliases and a core bug: #2511968: Path field should fall back to language neutral aliases (also makes this happen for the form widget!). I doubt (hope!) that Metatag is not like path aliases in this respect.Comment #52
yobottehg CreditAttribution: yobottehg commentedThis is definately more complicated then it looks on the first sight but i think this is the correct direction.
I got stuck at the following this:
There is no way to "just get the current entity overwrites" without running into circular references because of the computed field and the way metatag "renders" the metatags.
For the output i added JSON::encode to get "some" output which currently is the default entity definitions which is "something".
For a clean json output i think the field definitions are not working here or we need to add an additional field with own
propertyDefinitions
because for the jsonapi output we definately want this to be a multi value field and the keys need to differ from the current render elements.The html output rendering stopped working like this with the following error:
The jsonapi output works so ;)
Leaving this on "needs work"
Comment #53
yobottehg CreditAttribution: yobottehg commentedOkay here the mentioned different approach. It works like this but i think it's not really nice.
This will output the meta tags like the following:
Will leave for review if this approach is whats wanted here.
Comment #55
yobottehg CreditAttribution: yobottehg commentedThis should hopefully resolve the coding standards and notices.
Comment #56
DamienMcKenna@yobottehg: I really appreciate you taking the time to work on this, hopefully someone will get to review it soon.
At a cursory glance I feel like this will only work for certain meta tags, ones which specifically use the "name" and "content" attributes, but it seems like a reasonable starting point.
Comment #57
s_leu CreditAttribution: s_leu at Station commentedPatch in #55 works for basic tags that have a name and a content attribute (tested in a decoupled project using jsonapi).
Comment #58
s_leu CreditAttribution: s_leu at Station commentedAdding a patch that supports all metatags, regardless of their attribute keys. Wasn't exactly sure about the datatype for the property definition, so I used "any" for now.
Comment #59
yobottehg CreditAttribution: yobottehg commentedThe patch in #58 works nicely. Thanks @s_leu!
I'm also unsure about the datatype but perhaps someone else can review this.
I realized that this is seen as a base field which will be computed also for entity references which are not included in the response. That means if you query a node which has 5 terms attached which are not included you always get all metatags for them. I'm asking myself how expansive this is in regards to computing power.
I think we should limit the rendering of the metatags to the main entity which is queried and perhaps @Wim Leers knows a mechanism for that inside jsonapi?
Also i would like to get some feedback on the naming of the field which is not the final one i guess?
Leaving this on NR for other people to chime in.
Comment #60
Wim LeersThanks for working on this, @yobottehg! 👏
JSON:API doesn't do anything special; it only maps Entity/Field/Typed Data to https://jsonapi.org/format/'s data structures. If you say it doesn't work quite as expected, then the same problem will be true in core REST and GraphQL.
Why would the referenced entity objects be instantiated? Only when the referenced entities are instantiated would their base fields be constructed, and hence this computed base field's computations get executed.
Should use the
CARDINALITY_UNLIMITED
constant. Fixed.Why
any
?Why can this both be
NULL
and the PHP-serialized empty array?This
0
needs to match the index in$this->list
.Test coverage for the various edge cases would be super valuable here.
Comment #61
superbiche CreditAttribution: superbiche as a volunteer commentedI'm using this patch in a D8 "factory" site feeding content to a huge amount of Nuxt/Vuejs SSR websites.
It saved my bacon, until I configure Metatag to use tokens related to the node URL: MetatagNormalizedFieldItemList doesn't check if the entity exists (has an ID), which breaks the add node form (I guess it'll be the same for any entity as in https://www.drupal.org/project/metatag/issues/2947493).
This patch just adds the check for the ID, so when the node is added, Metatag doesn't try to generate this URL related stuff.
Comment #62
sonnyktPatch #61 works with both Metatag 8.x-1.7 and 8.x-1.x dev on JSON:API 8.x-2.0.
Comment #63
yobottehg CreditAttribution: yobottehg commentedI can also confirm patch #61 works perfectly on one site in production.
Comment #64
marc.groth CreditAttribution: marc.groth commentedYep I can also confirm that it is working for me (same versions as #62).
Just thought I'd add a quick comment in case anybody else gets a bit confused initially... For JSONAPI the meta tag data is not output as part of the field data. Instead there is a new 'metatag_normalized' key within 'attributes' (which is within 'data') that has all of the relevant information.
Comment #65
DamienMcKennaThis is why I think we should have test coverage to document what the output should look like.
Comment #66
Wim LeersAgreed.
still exists.Comment #67
Wim LeersSee
\Drupal\Tests\datetime\Functional\EntityResource\EntityTest\EntityTestDateonlyTest
for an example of a generic REST test for a particular field type (the date field in this case).Comment #68
axle_foley00 CreditAttribution: axle_foley00 commentedThanks @Wim-Leers, I will try to write an initial test for this issue this week.
Comment #69
axle_foley00 CreditAttribution: axle_foley00 commentedI made an initial attempt at the test, however, I was getting some failures in my local dev environment. I'm posting here to get a little feedback as well as to see what the testbot reports.
Comment #70
DamienMcKennaFYI the branch tests aren't working because the Devel module needs a new release due to API changes in core: #3042739: Fix tests on Metatag 8.x-1.x branch
Comment #71
DamienMcKennaI changed the default tests to work against 8.6.x (#3042739: Fix tests on Metatag 8.x-1.x branch), so lets see what the testbot says.
Comment #73
gabesulliceThanks for writing that test @axle_foley00, good start!
I think we can just drop this static, TBH.
We'll also need to add the uncomputed
metatag
field here too since they're both gonna be on the normalized entity.Running the tests locally, it looks like we need to override the expected cache contexts and tags to take into consideration the metatag field's cacheability.
The attached interdiff does that and also addresses #60.4 plus some other minor things.
Setting to NR for tests.
Comment #75
ainarend CreditAttribution: ainarend at ADM Interactive commentedJust wanted to +1 to the patch in #61 as it solves the gap in using jsonapi and metatag. Can't help out with the tests unfortunately.
And one OT documentation notice for people using Metatag and Jsonapi, and might face an issue why their metatags work when using the node detail view but not in jsonapi request:
If you have configured Metatags in Drupal to use the Global settings and using the current_page options in tokens, then they will not work for entities being requested via jsonapi, as current_page then is actually the jsonapi endpoint.
So for example when you have for the title tag something like this: [current_page:title] under the Global config, this needs to be moved under Content and the token should be entity aware, so something like this: [node:title].
But other than that, thanks for the patch and the module! Looking forward to the patch being committed and removing another rock from making the API first Drupal truly great! :)
Comment #76
DamienMcKennaOut of interest, does #2901039: Add a TypedData plugin to support Search API help with this effort in any way?
Comment #77
bgrobertson CreditAttribution: bgrobertson at Mediacurrent commentedApologies in advance if this is not the right issue to bring this up in :)
We are using the patch #61, which works great for the normal title / meta description fields. I noticed however that when used in conjunction with the Schema.org Metatag module, we end up with some type errors when we build in gatsby.
Looking at the JSON API output, my best guess at what is going on is that most "content" values are strings, but some of the Schema.org "content" values are objects. For example here is the output for the datePublished Schema.org metatag:
And here is the output for the schema.org author tag:
I don't have a proposed solution for this, but wanted to raise it here in case someone comes across a similar issue.
Comment #78
hitesh.koliRunning on Drupal core 8.7.4. The patch `2945817-73.patch` works for me. Fixes issue with `metatag_normalized` in the JSON API and fixes the error which keeps happening on node save or term save.
Comment #79
GrimreaperFirst, thanks to all the contributors working on this issue.
For the record, inspired from patch in comment 73. I have made a new field enhancer for JSON:API in comment #3060702-18: Compatibility with Metatag Fields to be able to deploy metatags using Entity share module.
Does this field enhancer should be in Entity share or in JSON:API Extras or in Metatag?
Comment #80
garphy CreditAttribution: garphy at ICI LA LUNE commented@Grimreaper,
My thoughts :
If this enhancer is of any use when not using Entity share (which is what I understant), I think that it should NOT leave in Entity share.
Then chosing between putting that in JSON:API Extras or Metatag is just a matter of where it allows to more properly handle the code dependencies of the enhancer (which surely references classes from JSON:API Extras and maybe some code from Metatag).
Comment #81
GrimreaperThanks @garphy for the feedback.
I will ping back when it will be ok for at least Entity Share usage.
Comment #82
GrimreaperHello,
As said in my previous comment, I will ping back when ok for Entity share.
Here is the commit: https://git.drupalcode.org/project/entity_share/commit/63f7282
And the following issue for tests #3089844: Tests: Metatag field.
Comment #83
fadonascimento CreditAttribution: fadonascimento at CI&T for CI&T commentedHi guys, I applied the patch #61 in my project and works very well, thanks @superbiche.
Comment #84
DamienMcKennaAnyone want to take a try at finishing the tests?
Comment #85
faysal.turjoHi guys, I applied the patch #61 in my project but throwing the following error.
LogicException: The controller result claims to be providing relevant cache metadata, but leaked metadata was detected. Please ensure you are not rendering content too early. Returned object class: Drupal\jsonapi\ResourceResponse. in Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext() (line 154 of /var/www/html/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php).
Comment #86
faysal.turjoComment #87
vaibhavjainRe-Rolling patch #73, as it does not apply to latest dev.
Comment #88
AndyF CreditAttribution: AndyF at Fabb commentedDrupal\Core\TypedData\ComputedItemListTrait
caches the first computed value, so this means if the value's computed before the entity's saved (eg. on validate) it will be cached as empty. I don't think we can use this trait as-is because there are different metatags for a new vs saved entity (eg. the entity's canonical URL is available).As I understand it this is trying to write to the old/existing computed metatag field, which I don't think is supported. Use metatag configuration entities and/or a field of type metatag.
I've had a go at getting the tests to run green: I've updated the new computed field to recompute once the entity is saved and added some metatag config at the global and entity type level. (I did also try to add a field of type metatag, but I got a failure in
\Drupal\Tests\rest\Functional\EntityResource\EntityResourceTestBase::testGet()
connected with bc_primitives_as_strings. I'm posting this simpler patch first to get testbot onside.) Feedback welcome, thanks!Btw it occurred to me that there's not much documentation around the difference between the two computed fields (
metatag
andmetatag_normalized
). AFAICT at the moment at least they both only exist for serialization?Comment #90
AndyF CreditAttribution: AndyF at Fabb commentedThe test was assuming no base path: I'm not sure if it would be better to return absolute URLs, but I've modified it to add the base path. Also codesniffer fixes. Thanks!
Comment #92
AndyF CreditAttribution: AndyF at Fabb commentedThe new test passes, but my changes have introduced a raft of new failures in other tests (: They seem to be connected with trying to generate metatags from an unsaved entity; looks like that's not a safe thing to allow in general, so the new patch doesn't generate the metatags in
computeValue
until the entity's saved.Comment #93
AndyF CreditAttribution: AndyF at Fabb commentedHere's an update which adds a field of type metatag to the entity. I've had to dynamically alter the expected normalization based on the value of
serialization.settings.bc_primitives_as_strings
: I don't really know anything about that setting so would welcome review/feedback. Thanks!Comment #94
wstocker CreditAttribution: wstocker at Mediacurrent commentedI was looking to expose metatags per node on my JSON:API endpoint.
Endpoint uri: jsonapi/node/landing/[id]
Patch #93 worked for Drupal core 8.8.7.
Comment #95
DamienMcKennaComment #96
VikSabo CreditAttribution: VikSabo commentedFirst, thanks to all that are working on this issue. I have applied patch #93 for Drupal core 8.8.7 and looks like we aren't able to retrieve node fields using tokens, for example, [node:field_name], is there a way we can add this option as well? Thanks in advanced.
Comment #97
achapI can't replicate #93. Tokens on node fields are working fine. However, it appears that this patch does not offer the opportunity to alter the metatags once they are generated. Shouldn't one of the hooks in metatag.api.php be called after the tags have been generated?
Comment #98
natedouglas CreditAttribution: natedouglas as a volunteer commentedI'm seeing #96 as well. Token output seems to be solid when I request _format=json versions of the content in question, but not set when I request it through JSON:API. I'm not sure why I'm seeing #96 and @achap isn't. I'm pressed for time but I might be able to look into this and find the root cause.
EDIT: After setting the value of the 'abstract' field to a non-token value and saving, the fields started showing up in the JSON:API response.
Comment #99
dmitry.korhovPatch #93 works well:
Comment #100
DamienMcKenna@dmitry: Did you clear the site's caches after applying the patch? What version of core are you using? What sort of page request resulted in that error?
Comment #101
dmitry.korhov@damienmckenna,
Updated my comment.
Seems that something is wrong with applying patch not through composer patches. PhpStorm + "Apply Patch from Clipboard" did not apply patch correctly. Probably it can be related to git tree of metatag module.
Version used: Drupal Core 8.9.5 + Metatag 1.14.
Comment #102
mglamanSo, I know there is the two computed field approach. What I was wondering:
Why can't MetatagEntityFieldItemList return a value in ::computeValue, and the field property be a new DataType plugin that can have a lower-level normalized attached? The problem with \Drupal\metatag\Normalizer\MetatagNormalizer is that it targets the field level and not the data property level. If we adjusted things a bit, this could "just work" if we computed the value and allowed the normalized to target the field property.
I've done this in Commerce API several times with custom dynamic computed fields.
For instance:
Address
I'll read over again. It was hard to grok since this started with JSON:API 1.x, then 2.x then JSON:API in Drupal core.
Comment #104
mglamanHere is my take on #93, refactored to modify the existing computed field instead of adding another one.
The interdiff is here: https://git.drupalcode.org/project/metatag/-/merge_requests/4/diffs?comm...
I guess my changes introduce backwards compatibility problems for anyone relying on REST.module whereas #93 provided a more compatible fix. But I think we can be honest that most folks are not using HAL or the default JSON encoding. And, the BC is just that the shape of the JSON changed, to something more usable.
Comment #106
mglamanPushed a fix to my changes: https://git.drupalcode.org/project/metatag/-/merge_requests/4/diffs?comm.... DrupalCI is running against the MR
Comment #108
mglamanAfter using this patch I realized our entities were throwing leaked metadata on `update`.
Comment #109
mglamanWorkaround to execute in a render context pushed.
Comment #110
DamienMcKennaOne test failure left.
Comment #111
dan2k3k4 CreditAttribution: dan2k3k4 at Amazee Labs commentedFailure seems to come from https://git.drupalcode.org/project/metatag/-/merge_requests/4/diffs?comm... ?
Comment #112
GRO CreditAttribution: GRO commentedRe-roll of @mglaman's patch in #104 to capture updates to the base branch (8.x-1.x)
To avoid pushing the merge and potentially breaking anyone's builds I decided not to request push access to the MR branch but can update once properly tested.
Comment #113
wombatbuddy CreditAttribution: wombatbuddy commentedPatch #93 also works well for Drupal 9.1.5.
Comment #114
rakesh.gectcrFixing the test errors.
Comment #115
rakesh.gectcrComment #117
DamienMcKennaI think #114 lost some changes..
Am looking into this.
Comment #118
DamienMcKennaThis fixes some of the tests.
Comment #120
DamienMcKennaThe last test failure comes from EntityResourceTestBase::testGet() where $this->getExpectedCacheTags() and $response->getHeader('X-Drupal-Cache-Tags')[0] are different, the former having "config:system.site" which the latter does not.
Comment #121
DamienMcKennaComment #122
adrienco88 CreditAttribution: adrienco88 commentedHi everybody,
I use Drupal decoupled as backend CMS and I'm trying to change the canonical URL. In the metatag settings (/admin/config/search/metatag) I set the canonical for content (articles) to be [node:url:path] since the frontend is on another domain. While doing this, if I open an article in drupal, the canonical URL is ok, but the metatag normalized returns the full absolute URL and it seems that it doesn't take in account the Tokens used in the Metatag settings page.
Any ideas how I can fix this or any workarounds available? (I'm using the #93 patch, but I also tested #118 with the same results)
Best Regards,
Adrian
Comment #123
DamienMcKenna@adrienco88: Please open a separate issue for us to help you with that support request. Thank you.
Comment #124
osmanThe latest patch (#118) doesn't work for me, but #93 works flawlessly.
+1 for patch on #93
Using Drupal 9.2.8, and a combination of few JSON:API contrib modules, including the jsonapi_include which alters the output of JSON to include referenced entities.
metatag_normalized
includes all meta tags for the entity; the ones defined on the entity directly, and also the inherited tags from the defaults as well.One tiny issue I noticed, and didn't find a reference to it in the comments above is the
TITLE
tag rendering:IMHO, considering the
<title>
tag is the only exception among the rest of meta tags (<meta />
, or<link />
tags), defining an exception in the consumer app might be a much simpler solution than "fixing" the output of it here.Comment #125
DamienMcKennaReroll.
Comment #126
DamienMcKennaLet's see if this fixes MetatagSerializationTest.
Comment #129
DamienMcKennaSo #126 fixes one of the tests (yay!), but someone else broke. :facepalm:
Comment #130
DamienMcKennaI reran the tests on #126 and now it shows just the one failure related to cache contexts, which I was expecting.
So how do we get the cache contexts to have the "config:system.site" item?
Comment #131
DamienMcKennaMy mistake, it's the cache tags :-\
Comment #132
yovincere-roll @GRO's patch in #122 to capture updates to the base branch (8.x-1.x) (1.7) , works with Drupal9.2.10
Comment #133
paulsheldrake CreditAttribution: paulsheldrake at Kanopi Studios commentedThe patch in #132 works for me in Drupal 9.3
Comment #134
DamienMcKennaRerolled #126.
Comment #135
DamienMcKennaComment #137
DamienMcKennaThis reverts the original Normalizer classes and marks them deprecated; we don't want to break the APIs.
Comment #139
DamienMcKennaBack to this problem again:
Comment #140
DamienMcKennaFrom a technical perspective are there any problems keeping the older normalizers? While they might be redundant with the new formatters, sites are using them already and I don't want to break them. Thank you.
Comment #141
DamienMcKennaIf getExpectedCacheTags() is not overridden then it fails with this:
Comment #142
DamienMcKennaThe getExpectedCacheTags() override comes from #73 where gabesullice was trying to trying resolves problems with meta data in the tests. Does the fact that it's failing mean that there's a problem elsewhere in Metatag, that something else needs to be changed to add the cache tag elsewhere, or that the changes Gabe added need to be handled a different way?
Comment #143
DamienMcKennaSome minor coding standards improvements.
Comment #145
mrweiner CreditAttribution: mrweiner commentedUpdating #143 to ensure that it invoked hook_metatags_alter(). The interdiff is messy for some reason so I'm not including it, but it's just adding the following to the computed field:
Comment #146
mrweiner CreditAttribution: mrweiner commentedDidn't upload the patch, whoops.
EDIT: Hmm, something isn't right. Will need to upload a new one.
Comment #147
mrweiner CreditAttribution: mrweiner commentedAlright this one should work.
Comment #148
Mykola Dolynskyi@mrweiner stange but patch 147 does not invoke
Drupal::service('module_handler')->alter('metatags
and does not expose hreflang at all via drupal/jsonapi_extras module (metatag field not empty).with patch 73 it exposes hreflang via drupal/jsonapi_extras module but not invokes alter() too
Comment #149
mayurngondhkarRe-rolled for 8.x-1.20
Comment #150
mayurngondhkarComment #151
mayurngondhkarRe-roll for (8.x-1.20)
Comment #152
mayurngondhkarRe-roll for (8.x-1.20)
Comment #153
abelass CreditAttribution: abelass commentedPatch doesn't seem to work with v 8.x-1.22 anymore
Comment #154
daniel.rolls@flightcentre.com.au CreditAttribution: daniel.rolls@flightcentre.com.au at Flight Centre Travel Group commentedRe-rolling this for latest dev (applies for 8.x-1.22 as well).
No changes, just resolved conflict since
src/Normalizer/MetatagNormalizer.php
was updated in https://git.drupalcode.org/project/metatag/-/commit/b54dffd?page=2 as part of API updates for Drupal 10, and is removed in this patch.Comment #155
nielsaers CreditAttribution: nielsaers at Dropsolid for Dropsolid commentedPatch from 154 works for me on 8.x-1.22
Comment #156
slydevil CreditAttribution: slydevil commentedPatch from 154 works for me as well.
Comment #157
robertom CreditAttribution: robertom at bmeme commentedPatch 154 works well, but the part for altering metatags introduced in patch 147 is missing.
Attached the modified patch and the interdiff
Comment #158
Mykola Dolynskyi@robertom invokation of metatags_alter(array &$metatags, array &$context) still not happening when called from JSON API endpoint. MetatagEntityFieldItemList ::valueNeedsRecomputing() and MetatagEntityFieldItemList ::computeValue() are not invoked too.UPD: found there was base_field_override on metatag field + patch was not applied correctly. Seem now all working, checking. Dunno how to delete comment
So #157 seems works, I like it.
Comment #160
Rajeshreeputrarebased.
Comment #162
DamienMcKenna(hiding the old patches)
Comment #163
DamienMcKennaComment #164
DamienMcKennaFixing one of the test failures.
Comment #166
DamienMcKennaBack to one test failure, the same issue reported in #73 - the cache context problems.
Comment #167
DamienMcKennaWorking on the last test failure.
Comment #168
DamienMcKennaDoes this help?
Comment #169
DamienMcKennaComment #171
DamienMcKennaIn #3362522 I fixed the meta tag output so it's reliable, so now we can adjust the test coverage here.
Comment #172
DamienMcKennaComment #173
DamienMcKennaBehold - the tests pass! Finally!
Would anyone care to give this a quick review? I think we can get it into the new release now.
Comment #174
DamienMcKennaComment #175
apmsooner CreditAttribution: apmsooner commentedPatch at #172 applies fine and works as intended for me.
Comment #176
DamienMcKennaJust to see what happens with the tests - let's mark the old classes as deprecated, rather than just removing them. Yes, this might blow up, overflow the bathtub and eat the key lime chocolate mousse my wife just made, but I'd like to properly deprecate-then-remove the classes if possible.
Comment #177
mglamanSeeing this sentence made me laugh and made my day.
Also, seeing this patch comes close. Deprecation sounds great, just in case someone is relying on them in quirky ways.
Comment #179
DamienMcKennaReworking the test coverage so they're compatible with the legacy output.
Comment #182
DamienMcKennaIt has been a long, long, long time coming.
A huge and heartfelt Thank You!!! to everyone who worked on this over the years, who helped give us directions, answer questions, and pointed out bugs in the approach.
It's a little annoying to realize that had I just done #3362522 a few years ago this could have been committed ages ago, because at least some of the tests past 2020 were because the meta tags were out rendered in a reliable fashion. But hindsight is always 2020.
Anyway, I am truly grateful and appreciate you all.
Committed #172 to the 2.0.x branch and the removed APIs will be deprecated in #3362760: Deprecate normalization plugins. Thank you all.
Comment #183
DamienMcKennaI've deprecated the APIs in #3362760 and we have a change notice for all of this.
If there are any further changes people can think of that might make this better, especially regarding documentation, please create follow-up issues or send me a message.
Again, thank you all.
Comment #185
robertom CreditAttribution: robertom at bmeme commentedRerolled #179 for 8.x-1.x
Comment #186
robertom CreditAttribution: robertom at bmeme commentedSorry, wrong patch name...
Rerolled #179 for 8.x-1.x