Closed (fixed)
Project:
Metatag
Version:
8.x-1.x-dev
Component:
Integration with other module
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
9 Aug 2017 at 18:56 UTC
Updated:
17 Aug 2026 at 13:59 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
tsplash commentedThis patch adds a new module to support the search_api. It includes a processor plugin which stores the basic metatags saved to an entity. The same principle could be applied to store other metatags if needed, but thought the basics would be a good start.
Comment #3
merilainen commentedI don't see any difference in search results after enabling the module. I suppose the processor should not be visible in the processors list because it's marked as hidden.
It would be nice to be able to boost the different properties because they are probably quite relevant for search as they are used for SEO too.
Comment #4
natemow commented@mErilainen -- I was able to add meta keywords and descriptions as new index fields after enabling the module, then set the type to fulltext and boosted as needed. Thanks for the patch @tsplash!
Comment #5
merilainen commentedYes, I realized it too that they have to be added as fields! This is perfect, everything can be boosted separately, just what I was looking for.
But the patch has some coding style issues which should be fixed. I was also getting a lot of notices for nodes which don't have any values saved for the metatag field (metatag has been enabled after content was created).
This can be easily fixed by checking if there is something to unsearialize:
Comment #6
merilainen commentedHere is an updated patch with coding style fixes and the check for values array to avoid notices while indexing.
Comment #7
damienmckennaThis is a great step forwards, thank you.
Two requests:
Thank you both.
Comment #8
merilainen commentedNot sure what is the best way to implement this. I managed to get all the tags using the metatag.manager service:
But there is no information about which fields are probably comma separated like the keywords field is for example.
Also I'm not sure if there are just too many tags which will make the Search API UI bloated. In my current setup I have mobile, open_graph and verification sub-modules enabled in addition to metatag core tags and I get 141 tags. I think most of them are improving machine readability of the content and therefore useless for search index, such as image urls, dimensions etc. Most of the tags which actually have human readable content are usually using field tokens which means they can be indexed to Search API using field properties. So some higher level decision should be done how this could be handled, I guess.
Comment #9
tsplash commentedThank you both for the feedback.
Here is an updated patch so the processor plugin is included in the base metatag module (good point there @DamienMcKenna). It also includes mErilainen's improvements (thank you for those).
@DamienMcKenna regarding you second request around dynamically identifying which tags are available, I agree with mErilainen's points. Unless the metatag api provided information on how the values are entered/stored, we will need to include some hard coded logic for many tags. Additionally as we are including this plugin in the base module, this logic could end up referring to tags which exist in the sub-modules. Also agree on the point around sheer number of available tags.
Should each submodule contain a plugin for the metatags it provides, or is this perhaps a bit overkill? For example from the tags provided by the base module, I could possibly see a need for the 'Geographical place name', 'News Keywords' and perhaps the 'Standout' metatags (which we could add) but not much else.
Comment #10
tsplash commentedComment #11
damienmckenna@tsplash: Thanks for the updated patch.
I would honestly take a step back and start over by asking some questions about this proposed functionality:
Comment #12
tsplash commentedAttached patch is an entire rewrite, which hopefully resolves the issues at hand.
Initially I had used a processor plugin to create the search_api fields dynamically as the metatag FieldType doesn't have the tags mapped as propertyDefinitions. The search_api looks at the propertyDefinitions on a field and makes them available through the UI in a nice collapsible menu. This would be perfect for the amount of tags available and resolves the UI bloating mErilainen was highlighting with the original solution.
From a bit of research other modules have solved this by defining computed properties. This patch does this is a dynamic manner, making all tags available as computed properties.
This does leave open the point around comma delimited tags, as each tag is indexed as a single value. However these could then be split with an additional processor or preprocess function. My gut feeling is that this wouldn't be the responsibility of our integration.
What do you guys think?
Comment #13
tsplash commentedCouple mistakes in the previous patch's comments, apologies.
Comment #14
merilainen commentedAs for use cases, I was about to add a hidden field for "Search result description" to get some text into the search index which would not be visible in the content entity at all. Then I remembered that several pages already had a meta title + description which Google for example displays as the summary when you see the page in the results. And then I found this issue which would solve my problem and didn't need to add another field for metadata.
Also as a special case, we have some pages which have React components which render content from external API or elasticsearch, so they don't actually have much Drupal content other than a title, so this solves also that case to get something into the search index without adding hidden fields.
Comment #15
merilainen commentedI think the new approach looks very nice. Here is a patch with some code style fixes.
Comment #17
merilainen commentedFixed patch format.
Comment #18
merilainen commentedComment #19
mpp commentedThanks for exposing the fields to Search API.
What about providing deeper integration with Search API, like excluding content from the index when the metatag
noindexis checked?Comment #20
merilainen commentedThere are other ways to exclude items and I would not want to assume that noindex should also exclude content automatically from Search API without control which might be used for internal searches, for authenticated users etc.
Comment #21
mpp commentedIn that case I'd say this is RTBC.
I do have these small remarks:
/**
+ * Cached processed value.
+ *
+ * @var string|null
+ */
+ protected $value = NULL;
=> no need to indicate null or set a variable to NULL.
+ if ($definition->getSetting('tag name') === NULL) {
=> why not use is_null()?
Comment #22
AMDandy commentedThis patch seems to have broken on the latest dev release. It worked for our needs and I look forward to it being merged so I can update metatag.
Comment #23
damienmckennaFYI the tests are currently failing because of #3043263: Missing getActiveDefinition on EntityManagerWrapper due to changes in 8.7, when Devel gets a new release we'll be able to check the tests again and see if maybe something changed somewhere.
Comment #24
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 #25
jenniferhoude commentedTried to use patch 2901039-add-support-for-search-api--16.patch. Can now see the meta tag field available in the search api fields listing. Rebuilt the index and re-indexed. But the the search results are not showing anything when searching for that keyword.
Comment #26
mpp commentedHi @jenniferaube, welcome to drupal.org. I have confirmed your account so you no longer need to enter capcha's when posting comments.
Did you add the field as a full text field?
Have a look at the search view and make sure you checked the field in list of fields to use for the fulltext filter.
Comment #27
wannesdrComment #28
wannesdrI applied the feedback from @mpp in comment #21. But I will leave the
=== NULLsince this seems the preferred way in Core. As long as the check is strict it is good.I also changed the setting
tag nametotag_name(without the space). We don't like seeing spaces in setting keys.Up next we will add a kernel test for the typedData.
Comment #30
wannesdrMissed one of the
tag namesetting keys. 🙈Comment #31
mpp commentedLooks like part of the patch is missing :-)
Comment #32
wannesdrI uploaded the wrong file.
(Guess I need coffee...)
Comment #33
borisson_I spent the last 4 hours working on this with @wannesderoy and we can't figure out how to write a kernel test for this, especially not because most of things we would be testing would be things that test the typed data layer. We could add a test to check that if we pass in a value to setValue that it gets returned from getValue.
That is again a way to test the typed data api's, and I don't think it makes sense to do that.
We manually tested that this at least exposes typed data and that seemed to be working as expected.
Based on that I'm setting this to RTBC - at least to surface the problem to @DamienMcKenna, but it might be that this is already good enough without testcoverage.
Comment #34
borisson_Retitling as well to be more explicit.
Comment #35
mpp commented#34: @wannesderoy, @borisson_, great work!
#32: @wannesderoy, Happens to the best ;-)
In fact if I had been paying some more attention in #21, I would have noticed this earlier:
+ ->setLabel(t('@label', ['@label' => $tag['label']]))
This feels wrong. I don't have an IDE at hand so I can't immediately see what class the $tag is but we should probably get the label somewhere up in the stack from calling sortedGroupsWithTags (I assume it's the plugin annotation's label?).
Comment #36
damienmckennaComment #37
damienmckennaWhile yes, test coverage for this would (in part) test the typed data system itself, it would also test how the values from Metatag are output.
I agree with mpp in #35, this doesn't feel right; at the very least it should be $this->t() instead of just t().
The spelling should be "meta tag", two separate words.
Comment #38
klmd302 commentedThank you for this patch! However I encountered a couple of issues with it that I wasn't sure how to solve.
1. If a meta tag on a node is using the default value configured at /admin/config/search/metatag, no value is indexed for that field.
2. If a meta tag contains tokens, only the token name is indexed, rather than the content it refers to.
Comment #39
damienmckenna#38 indicates that the meta tags need to be rendered prior to indexing, the Metatag field should not be just included as-is.
Comment #40
rcodinaI upload a new version of patch on #32. Changes:
$this->t()cannot be done because that method is static.Comment #41
rcodinaI upload a new patch to remove a debugging line I missed to remove.
Comment #42
rcodina@DamienMcKenna Is there a way to render metatags in a more performant way? After my patch, I think the indexing performs much worse.
Comment #43
damienmckennaIs there a better way of doing it? It's doing a lot of extra processing, and it'd only get slower as more meta tags are added by installing more submodules.
Comment #44
damienmckennaWould it be better to process all of the tags in one go rather than processing them individually?
Comment #45
rcodina@DamienMcKenna I tried a cache system approach given I need this feature ASAP and I think the approach you suggested would take me much more time.
Comment #46
rcodinaComment #47
damienmckennaLet's put this back on the "needs work" pile as it feels like it'd be a massive performance hit.
Comment #48
rcodina@DamienMcKenna With patch on #45, the performance is back to normal. With my test data, with patch on #41 it indexed on 6 minutes and with patch on #45 it indexed on 4 minutes (which is normal).
Comment #49
rcodina@DamienMcKenna You are right, there are still performance issues. I just did a performance test and these are the results:
1 minute 12 seconds (patch #32)
3 minutes 50 seconds (patch #45)
Comment #50
rcodina@DamienMcKenna Please, could you do your own performance tests? Sometimes, patch on #45 performs much faster. I don't know if there is a special method to measure performance on Search API indexing (maybe I'm doing something wrong).
On the other hand, any clue about how to modify the patch to process all of the tags in one go?
Comment #51
rcodina@DamienMcKenna I've repeated performance tests and it seems that performance is better than I thought:
My measurements on #49 were wrong because I did them on a local vagrant multisite environment and I measured times via UI indexing. Now I modified the same multisite environment to run via DDEV (Docker) and I measured times via terminal. Also, In previous analysis I didn't cleared the cache and the index before every measurement (now I do).
Before each run I do:
Time measuring command:
drush search-api-index multisite_search_indexResults:
1. 2660 elements to index (same site as #49):
patch #32, 59.28 seconds
patch #45, 1min and 1.15 seconds
2. 10266 elements to index (another site)
patch #32, 1min and 20.58 seconds
patch #45, 1min and 25.79 seconds
Comment #52
rcodinaChanges from patch on #45:
- Removed cache code on
metatag_generate_entity_metatagsmethod. This code was introduced in #45 and produces a language bug from which metatags can be rendered in another language!- Removed usage of
metatag_generate_entity_metatagsmethod to render metatags, custom code is used instead (only renders the desired metatag)Please, review this new version!
Comment #53
weekbeforenextComment #54
damienmckennaThanks April!
BTW did you mean to include the metatag_async.js file?
Comment #55
weekbeforenextOops! Tested this patch before upload.
Comment #56
rcodina@DamienMcKenna @weekbeforenext Patch #55 works fine!
Comment #57
damienmckennaI think this should follow the new API from #3302969, specifically the htmlValueAttribute attribute, to determine what element to use from the HTML tag.
Comment #58
damienmckennaI'm working on this.
Comment #59
damienmckennaI manually tested this. It appears to work well.
Suggested improvements:
* Documentation is needed for the README.md file.
* Rework to use the tag plugin's htmlValueAttribute; this is a protected attribute so maybe add a getter?
* As a separate issue, maybe add a way of getting all meta tag values in one go?
Comment #60
damienmckennaThis reworks the logic to use a new method that uses the tag's htmlValueAttribute value.
Comment #61
damienmckennaStill to do:
* Test coverage.
* Documentation is needed for the README.md file.
* Create a separate issue for improving the UI so that each meta tag doesn't have to be individually added as a separate item.
I also wonder if this would work for complex data structures, like the Schema Metatag values? It might need further testing.
Comment #62
damienmckennaI renamed the class to Drupal\metatag\TypedData\IndividualTag instead of Drupal\metatag\TypedData\Metatags to make it more clear what it's for.
Comment #63
damienmckennaComment #64
damienmckennaNow with added documentation.
I could not see how to make Search API use the "fulltext" field type for Metatag values, it defaults to "string" which is not what most people will want, see #3224311: Make string fields default to "fulltext" field type for details; I noted this in the docs.
Comment #65
damienmckennaOh yeah, the patch file.
Comment #66
damienmckennaI spun off a separate issue to look into changing the default data type to improve the UX: #3311389
Comment #68
damienmckennaI looked at the test coverage and it's a bit tricker because of the AJAX bit to load the form, so let's do the test coverage in #3311544.
Committed. Thanks everyone!
Comment #69
damienmckennaComment #71
matt_zimo commentedI'm getting this deprecation warning when I drush cr:
Deprecated: Drupal\metatag\TypedData\Metatags::__construct(): Implicitly marking parameter $parent as nullable is deprecated, the explicit nullable type must be used instead in /var/www/html/docroot/modules/contrib/metatag/src/TypedData/Metatags.php on line 31Comment #72
damienmckennaPlease open a new bug report for that. Thank you.
Comment #73
matt_zimo commentedOK. I made it here. It's my first time making a bug report here, so apologies if its formatted incorrectly.