There should be an option to append a BreadcrumbList
as defined on schema.org to each page reflecting the current breadcrumb trail.
The structured data should be added in JSON-LD like recommended from Google here.
We should only add structured data for content which is being shown on the page we add it to as defined in Google's structured data guidelines. And therefore should append it only when the breadcrumb block is displayed on the page.
TODOs:
* Add code to attach current breadcrumb as JSON-LD to every page.
* Add tests.
* Update README.
* Update module description / feature list on drupal.org.
Initial issue description:
It should be possible to use Structured data, from schema.org standard. This should also be available when the module is active and the block is not.
Comment | File | Size | Author |
---|---|---|---|
#40 | breadcrumb.jpg | 27.77 KB | skouf |
#37 | structured-data_2799067_37_D7.patch | 3.88 KB | leymannx |
#34 | structured-data_2799067_34.patch | 8.77 KB | leymannx |
|
Comments
Comment #2
Greg BoggsAre you thinking you'd like the markup in JSON-LD, RDFa, Microdata, or all 3? I'd be happy to add several Twig files to the module if someone is interested in doing the work
Comment #3
dscoop CreditAttribution: dscoop as a volunteer and at Cooper Webdesign commentedI was thinking about JSON-LD only. Would be really nice to have. Also looks so much better in Google search.
I was not thinking about doing this in the template itself, but adding a hook for the module, where JSON-LD was added to the header, if an option to the module was enabled. That way we could have JSON-LD breadcrumbs enabled without being able to see the actual breadcrumb on nodes.
Comment #4
Greg BoggsDoing that might be a violation of Google Webmaster guidelines, so I would consider just printing the breadcrumb because they claim to validate the json-LD against your HTML to confirm that you're not feeding them cloaked content.
Having said that, if you want to do it, there's a few routes, but all of them need work to port them from D7 to D8.
https://www.drupal.org/project/jsonld
https://www.drupal.org/project/schemaorg
https://www.drupal.org/project/schema
Finally, we could add the json to easy_breadcrumb, but we'll need to make sure it plays nicely with the above modules once they are ported.
~G
Comment #5
dscoop CreditAttribution: dscoop as a volunteer and at Cooper Webdesign commentedI assume that this module only print valid paths, so we shouldnt worry about violation of Google Webmaster guidelines.
I am testing this page at the moment:
https://www.cooper.dk/cases/tveast
Structured data-test can be found here:
https://search.google.com/structured-data/testing-tool/u/0/?hl=da#url=ht...
Comment #6
Greg BoggsLooks like a great test so far. Feel free to send me a Pull Request on Github: https://github.com/Greg-Boggs/easy_breadcrumb, or a patch here. ;)
~G
Comment #7
Greg BoggsAny updates on this feature?
Comment #8
sunward CreditAttribution: sunward commentedsubscribe
Comment #9
Greg BoggsBump.
Comment #10
kurtismccartney CreditAttribution: kurtismccartney commentedI've got a preffered operating format. please mind the truncation of the "easy" part throughout the tested segment.
Anyone know how to get the span wrappers on the inside and outside of the anchor, then getting these elements in the live code.
Comment #11
kurtismccartney CreditAttribution: kurtismccartney commentedNote. Last element needed is the recode of the anchor tag.
Comment #12
Greg BoggsPerhaps it would be easier to program, and easier to read, while still being equally useful if we add the structured data as json-ld format instead of inline with the HTML?
Happy to accept the feature in any (of the formats of course).
Comment #13
kurtismccartney CreditAttribution: kurtismccartney commentedOf course. Very amusing change, and would have preferred the JSON solution as well.
Trying to balance 2016 Greg "Doing that might be a violation of Google Webmaster guidelines" and 2017 Greg "easier to read, while still being equally useful if we add the structured data as JSON-LD format" with a bit of determination. If I could get a hard coded version working with that link wrapper then it would be much easier to consider adding a No SCHEMA, JSON-LD or RDF toggle in options.
My Drupal module experience is a bit behind on D7. I'm just a little stumped when it comes to deconstructing this:
l($content, $it['url'], array('attributes' => array('class' => $it['class'])));
So that it can output this:
<a href="/" class="breadcrumb_segment breadcrumb_segment-front" property="item" typeof="WebPage"><span property="name">Home</span></a>
Comment #14
kurtismccartney CreditAttribution: kurtismccartney commentedContinuing to do things in a very loud and complicated fashion. Apologies for people fond of big long classes. Here is a new base for anyone poking around with RDFa:
Comment #15
Greg BoggsI was pretty new to structured data when I made the first post.
Ideally, we'd be able to provide options. But, I meant to communicate, that you're welcome to ignore my thoughts from last year if it turns out to be difficult to replicate the HTML you want directly. I think any of the 3 approaches is most likely a solid way to go.
~Greg
Comment #16
Greg BoggsComment #17
tatarbjComment #18
leymannxLittle late to the party, but here comes a first working draft.
1. I added a new tab to the module's config which is called "Structured Data". There you can enable having the current breadcrumb added as structured data in JSON-LD to the HTML head (referencing Google's tutorial on structured data for breadcrumbs). This setting works independently from having the breadcrumbs block placed on the page or not.
2. I implemented
hook_page_attachments
from where I called\Drupal::service('easy_breadcrumb.breadcrumb')->build($route_match);
to get the current breadcrumb, build the JSON from it and have it added to the HTML head when the aforementioned setting is activated.Certain things I'd like to have discussed:
1. Calling
\Drupal::service('easy_breadcrumb.breadcrumb')->build($route_match);
in the hook gives me the links without taking the Easy Breadcrumb settings into account. For example I configured Easy Breadcrumb to have no home link printed on the front page. Which works just fine for the breadcrumb block. But\Drupal::service('easy_breadcrumb.breadcrumb')->build($route_match);
still gives me the link and therefore will be printed as structured data. Is this a desirable thing to have? Or how can I have\Drupal::service('easy_breadcrumb.breadcrumb')->build($route_match);
respect the Easy Breadcrumb config?2. There was this requirement to have structured data work independently from the block – which is a good idea(!) – so I decided to have it added as
<script type="application/ld+json">
directly to the HTML head usinghook_page_attachments
or is there any better place to have that added?3. I added
'#cache' => ['contexts' => ['url.path']],
for having this piece of markup considered for caching per URL. But I don't know if this is necessary or if it will be taken into account at all.4. Should we move part of the code from inside the hook into a dedicated class or maybe even add a new method inside the
EasyBreadcrumbBuilder.php
?TODOs:
- Add tests
- Update README
- Update module description here on drupal.org
Comment #19
leymannxAdded patch.
Comment #20
leymannxMaybe we should rename the default "Settings" page to "Block settings" or something similar?
Comment #21
leymannxComment #22
Greg BoggsGreat stuff!
1. You're the first person to call Easy Breadcrumb outside of the build. This sounds like a bug that needs to be fixed!
2. I'd prefer to use a service/event architecture so it's the same as the rest of the module. But, we can start from the hook and improve later.
3. Cache should already be handled by the builder with no need for you to add extra settings, but do tell me if you experience cache trouble.
4. I'd love to use a Class just so someone else might be able to extend your work later the same way you were able to call >build rather than the D7 way of adding hooks to our hooks.
5. I have no strong opinions here. Anyone else?
~G
Comment #23
Greg BoggsCan you post LD output in a code block so I Can validate? I know I could download the patch, etc, but I don't have a working D8 site set up. So, having the output from your test site would be super handy.
~G
Comment #24
leymannxI will respond more detailed later or maybe even send an updated patch. I'll also try to get an opinion about this whole structured data breadcrumb thing from an SEO expert to be included here.
The markup currently looks like following.
1. Front page
2. Sub page
3. Sub sub page
Comment #25
Greg BoggsLooks good.
Comment #26
leymannxUhkay, found out some things now. First and most important thing is stated in Googles guidelines to structured data.
Which means we actually must print the structured breadcrumb data only when there really are breadcrumbs visible on the page. That's changing the specs quite a bit. Which also makes it necessary to get the same output (out of the build or from somewhere else) for the JSON-LD as the actual breadcrumb block is getting.
This makes me think that we probably are better off placing the JSON-LD directly in the block and not in the
<head>
.Comment #27
leymannxOkay, next try.
1. Since the structured data is bound to the block (only add structured data for content which is being shown on the page you add it to) I removed the extra settings form and append the checkbox to enable structured data to the existing settings form (under the advanced section).
2. From the same reason I now use
hook_block_view_BASE_BLOCK_ID_alter
to attach the structured data directly to the block's$build
(when the block appears on the page), from where it bubbles up into the HTML head. No block on the page, no structured data on the page.3. I added a new
class EasyBreadcrumbStructuredDataJsonLd
class and a new service for that class, and therefore a new update hook to have the caches flushed explicitly (an empty update hook seemed to be not enough) for the service to be picked up correctly.4. I removed the superfluous cache context from the JSON attachment.
TODOs
-
Drupal calls should be avoided in the new class, use dependency injection instead- Add tests
- Update README
- Update module description here on drupal.org
Comment #28
leymannxI'd be more than happy if someone could assist in the dependency injection and adding tests task.
Comment #29
leymannxOopsie, newly added class file was missing.
Comment #30
leymannxForgot to mention: The build method returns the links absolutely fine. I forgot that I head the breadcrumb block hidden from the front page per block visibility settings instead of Easy Breadcrumb settings. So no bug in there. :)
Comment #31
leymannxComment #32
leymannxComment #33
leymannxGosh, don't know how this is possible. I've submitted an outdated comment form and now can't unhide the uploaded patches. Reuploading last patch from #29.
Comment #34
leymannxSooooo, I made the
EasyBreadcrumbStructuredDataJsonLd.php
class use dependency injection now.Last bigger task left now is to add tests for checking if the structured data can be found in the markup/head or not. And I really need help on this one. Maybe theoretically first.
I think we should create some nested nodes (or can this be done just with routes?), with paths like
/hello
and/hello/world
. Maybe just aHelloWordController.php
that takes its title ("Hello" or "World") from path arguments? And then assert the structured data exists on the page or not, depending on the currentadd_structured_data_json_ld
setting? We could also check if the structured data exists on the page depending onhome_segment_keep
orhide_single_home_item
setting. What do you think? Has anyone of us some experience with writing these kind of tests?Comment #35
leymannxComment #36
Summit CreditAttribution: Summit commentedHi, Is this adding of structured data also possible for Drupal 7 please?
Thanks a lot in advance for your reply!
greetings, Martijn
Comment #37
leymannxPatch for D7.
Comment #38
skouf CreditAttribution: skouf commentedHello
I have Drupal 8 and I installed the patch structured-data_2799067_34.patch.
I checked the checkbox inside the easybreadcrumb module to enable structured datas, emptied my cache, but ht code remain unchanged.
What am I missing ?
Thanks
Comment #39
leymannxYou need to place the breadcrumb block on the page. And it should print breadcrumbs. No block with breadcrumbs, no structured data.
Comment #40
skouf CreditAttribution: skouf commentedThanks for your reply :)
I have my breadcrumb already on my page.html.twig ({{ page.breadcrumb }})
My block System breadcrumb is enabled on the admin block page
Still no structured data :(
Comment #41
leymannxPlease check your HTML
<head>
for<script type="application/ld+json">
.Comment #42
skouf CreditAttribution: skouf commentedYes I can see that :
{ "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{ "@type": "ListItem", "position": "1", "name": "Accueil", "item": "http://site-url.com/fr" },{ "@type": "ListItem", "position": "2", "name": "Groupe", "item": "http://site-url.com/fr/page" }]}But tags are not added inside the breadcrumb HTML
Comment #43
leymannxAs mentioned in #27 I used
hook_block_view_alter
to attach the structured data to the block build from where it then bubbles up into the HTML<head>
. It would have been no good idea to put the markup into the block template. Since people override templates. And I think it also was difficult if not impossible to simply append a unfiltered<script>
tag to the block's markup.Comment #44
leymannxLast comment updated to match the accomplished progress.
Comment #45
skouf CreditAttribution: skouf commentedThanks for your help
So I have to create sort of javascript function to put each element of your hook inside the correct tags ?
Comment #46
leymannxYou don't have to do anything. You already have everything. Structured data in the HTML head. Google will appreciate that and soon you'll see the result on Google's SERPs.
Comment #48
Greg BoggsThanks!
Comment #49
leymannx🎉 How cool is that?
Greg, do you get notified about my comment on GitLab? https://git.drupalcode.org/project/easy_breadcrumb/-/commit/1b68813ee9cd...
(Just asking, as this is the first time I commented code on the Drupal GitLab and don't know if this triggers something or not.)
Comment #50
Greg BoggsNope! Comments on Gitlab seem to go nowhere. We were also missing the submitter for the LD setting. So, I rewrote the form submission for settings to be dynamic.
It looks like the current page crumb is also missing from the LD which is in the example provided by Google:
https://developers.google.com/search/docs/data-types/breadcrumb#json-ld
Comment #51
Greg BoggsFeel free to review again. I updated the code a bit and pushed it all to the dev branch.