Schema Markup (JSON-LD) breadcrumbs

Hey,

Recently I started with Kirby and I really like it!
I am a starting developer and therefore I have to learn a lot. I have already searched the forum if I could find an answer for my problem, but I had no success.

Maybe you can help me:

I want to make my breadcrumbs as a JSON-LD markup. I have already the follow code:

<script type="application/ld+json">
{
  "@context": "http://schema.org/", 
  "@type": "BreadcrumbList", 
  "itemListElement": [
        <?php foreach($site->breadcrumb() as $crumb): ?>
    { 
      "@type": "ListItem", 
      "position": "1", 
      "item": { 
        "@id": "<?= $crumb->url() ?>", 
        "name": "<?= $crumb->title() ?>" 
      } 
    },

        <?php endforeach ?>

  ]
}
</script>

It works. But I want to count the positions as well. Do you have an idea how to do this?

At last I need to seperate the items with a comma (except the last one). How can I do this?

Thanks!
Porto

Welcome :slight_smile:

I did it like this… you have to add 1 because the index will start at 0 because thats where PHP starts counting from, but the schema position needs to start at 1. You can use last() to handle the no comma on the last entry.

<script type="application/ld+json">
{
 "@context": "http://schema.org",
 "@type": "BreadcrumbList",
 "itemListElement":
 [
   <?php
   foreach ($site->breadcrumb() as $crumb):
   $index = $site->breadcrumb()->indexOf($crumb);
   $depth = $index + 1;
   ?>
  {
   "@type": "ListItem",
   "position": <?= $depth ?>,
   "item":
   {
    "name": "<?= $crumb->title() ?>",
    "@id": "<?= $crumb->url() ?>"
    }
    <?php if($crumb->is($site->breadcrumb()->last())): ?>}<?php else: ?>},<?php endif ?>
  <?php endforeach ?>
 ]
}
</script>
1 Like

Wow, that’s fast!
You helped me a lot :grinning:

After endless puzzling, sometimes you need some help to find the solution.

Thank you very much!!!

No worries. I cleaned it up a little… its a little more readable and less repeaty…

<script type="application/ld+json">
{
 "@context": "http://schema.org",
 "@type": "BreadcrumbList",
 "itemListElement":
 [
   <?php
   $crumbs = $site->breadcrumb();
   foreach ($crumbs as $crumb):
     $index = $crumbs->indexOf($crumb);
     $depth = $index + 1;
     $last = $crumb->is($crumbs->last()) ? '}' : '},';
   ?>
  {
   "@type": "ListItem",
   "position": <?= $depth ?>,
   "item":
   {
    "name": "<?= $crumb->title() ?>",
    "@id": "<?= $crumb->url() ?>"
    }
    <?= $last ?>
  <?php endforeach ?>
 ]
}
</script>
2 Likes

A probably better way of doing it, would be to create your complete array in PHP, then to json_encode().

<?php

$itemListElement = [];
foreach($site->children() as $page) {
  $itemListElement[] = [
    '@type' => 'listItem',
    'position' => $page->indexOf($pages) + 1,
    'item' => [
      'name' => $page->title()->value(),
      '@id' => $page->url()
    ]
  ];
}

$schema = [
  "@context" => "http://schema.org",
  "@type" => "BreadcrumbList",
  "itemListElement" => $itemListElement
];


?>
<script>
<?= json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT |  JSON_UNESCAPED_UNICODE); ?>
</script>

Cleaner, less error prone, no problem with the last comma, and you can keep your logic in the controller.

You might also consider the JSON generator:

3 Likes

Thank you all for your help! It was very helpful :slight_smile:

Sorry to dig up this old thread, but i’ve just used the example from @texnixe (which was an improved version of mine, so kinda my fault) and realised a problem with the logic. The Position key denotes the position in the site, which is not necessarily the position in the index. For some of my pages i’m getting a position of 7, when actually it should be 4. Heres an example from google…

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [{
    "@type": "ListItem",
    "position": 1,
    "name": "Books",
    "item": "https://example.com/books"
  },{
    "@type": "ListItem",
    "position": 2,
    "name": "Authors",
    "item": "https://example.com/books/authors"
  },{
    "@type": "ListItem",
    "position": 3,
    "name": "Ann Leckie",
    "item": "https://example.com/books/authors/annleckie"
  },{
    "@type": "ListItem",
    "position": 4,
    "name": "Ancillary Justice",
    "item": "https://example.com/books/authors/ancillaryjustice"
  }]
}

How can i get the pages depth in the site?

Some time ago I wrote to this question at https://forum.getkirby.com/t/meta-tags-plugin/6802/10

Answered my own question…

<?php

$itemListElement = [];

foreach($site->breadcrumb() as $crumb) {

$index = $site->breadcrumb()->indexOf($crumb);
$depth = $index + 1;

  $itemListElement[] = [
    '@type' => 'listItem',
    'position' => $depth,
    'item' => [
      'name' => $crumb->title()->value(),
      '@id' => $crumb->url()
    ]
  ];
}

$schema = [
  "@context" => "http://schema.org",
  "@type" => "BreadcrumbList",
  "itemListElement" => $itemListElement
];


?>
<script type="application/ld+json">
<?= json_encode($schema, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT |  JSON_UNESCAPED_UNICODE); ?>
</script>

2 Likes