diff --git a/composer.json b/composer.json index 5259d06a..2d43eabc 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ } }, "require": { - "statamic/cms": "^6.10", + "statamic/cms": "^6.19", "pixelfear/composer-dist-plugin": "^0.1.6", "spatie/simple-excel": "^3.9" }, diff --git a/src/Cascade.php b/src/Cascade.php index 0e718598..0908dba6 100644 --- a/src/Cascade.php +++ b/src/Cascade.php @@ -654,7 +654,7 @@ protected function jsonLd() return [ '@type' => 'ListItem', 'position' => $index + 1, - 'name' => $crumb->value('title'), + 'name' => $crumb->title, 'item' => $crumb->absoluteUrl(), ]; })->all(), diff --git a/tests/CascadeTest.php b/tests/CascadeTest.php index ae440172..979bfe34 100644 --- a/tests/CascadeTest.php +++ b/tests/CascadeTest.php @@ -522,4 +522,91 @@ public function it_generates_json_ld_breadcrumbs() '{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"http://cool-runnings.com"},{"@type":"ListItem","position":2,"name":"\'Dance Like No One is Watching\' Is Bad Advice","item":"http://cool-runnings.com/dance"}]}', ], $data['json_ld']->all()); } + + #[Test] + public function it_generates_json_ld_breadcrumbs_for_entry() + { + Collection::findByHandle('articles')->routes('articles/{slug}')->save(); + + $siteDefaults = SiteDefaults::in('default')->set([ + 'json_ld_breadcrumbs' => true, + ]); + + $this->get('/articles/dance'); + + $data = (new Cascade) + ->with($siteDefaults->all()) + ->get(); + + $breadcrumbs = collect($data['json_ld'])->first(fn ($snippet) => str_contains($snippet, 'BreadcrumbList')); + $breadcrumbs = json_decode($breadcrumbs, true); + + $this->assertEquals('BreadcrumbList', $breadcrumbs['@type']); + $this->assertCount(3, $breadcrumbs['itemListElement']); + + $this->assertEquals([ + '@type' => 'ListItem', + 'position' => 1, + 'name' => 'Home', + 'item' => 'http://cool-runnings.com', + ], $breadcrumbs['itemListElement'][0]); + + $this->assertEquals([ + '@type' => 'ListItem', + 'position' => 2, + 'name' => 'Articles', + 'item' => 'http://cool-runnings.com/articles', + ], $breadcrumbs['itemListElement'][1]); + + $this->assertEquals([ + '@type' => 'ListItem', + 'position' => 3, + 'name' => "'Dance Like No One is Watching' Is Bad Advice", + 'item' => 'http://cool-runnings.com/articles/dance', + ], $breadcrumbs['itemListElement'][2]); + } + + #[Test] + public function it_generates_json_ld_breadcrumbs_for_taxonomy_term() + { + $siteDefaults = SiteDefaults::in('default')->set([ + 'json_ld_breadcrumbs' => true, + ]); + + $this->files->makeDirectory(resource_path('views/topics'), force: true); + $this->files->put(resource_path('views/topics/index.antlers.html'), ''); + + $this->get('/topics/sneakers'); + + $data = (new Cascade) + ->with($siteDefaults->all()) + ->get(); + + $breadcrumbs = collect($data['json_ld'])->first(fn ($snippet) => str_contains($snippet, 'BreadcrumbList')); + $breadcrumbs = json_decode($breadcrumbs, true); + + $this->assertEquals('BreadcrumbList', $breadcrumbs['@type']); + $this->assertCount(3, $breadcrumbs['itemListElement']); + + $this->assertEquals([ + '@type' => 'ListItem', + 'position' => 1, + 'name' => 'Home', + 'item' => 'http://cool-runnings.com', + ], $breadcrumbs['itemListElement'][0]); + + $this->assertEquals([ + '@type' => 'ListItem', + 'position' => 2, + 'name' => 'Topics', + 'item' => 'http://cool-runnings.com/topics', + ], $breadcrumbs['itemListElement'][1]); + + $this->assertEquals([ + '@type' => 'ListItem', + 'position' => 3, + 'name' => 'Sneakers', + 'item' => 'http://cool-runnings.com/topics/sneakers', + ], $breadcrumbs['itemListElement'][2]); + } } diff --git a/tests/Localized/CascadeTest.php b/tests/Localized/CascadeTest.php index 797b18e5..476f2c05 100644 --- a/tests/Localized/CascadeTest.php +++ b/tests/Localized/CascadeTest.php @@ -67,4 +67,27 @@ public function it_generates_seo_cascade_for_canonical_url_and_handles_duplicate 'it' => 'http://corse-fantastiche.it', ], collect($data['alternate_locales'])->pluck('url', 'hreflang')->all()); } + + #[Test] + public function it_generates_json_ld_breadcrumbs_for_entry_using_title_from_origin() + { + $siteDefaults = SiteDefaults::in('french')->set([ + 'json_ld_breadcrumbs' => true, + ]); + + $this->get('http://cool-runnings.com/fr/about'); + + $data = (new Cascade) + ->with($siteDefaults->all()) + ->get(); + + $breadcrumbs = collect($data['json_ld'])->first(fn ($snippet) => str_contains($snippet, 'BreadcrumbList')); + $breadcrumbs = json_decode($breadcrumbs, true); + + $this->assertEquals('BreadcrumbList', $breadcrumbs['@type']); + + $lastItem = end($breadcrumbs['itemListElement']); + $this->assertEquals('About', $lastItem['name']); + $this->assertEquals('http://cool-runnings.com/fr/about', $lastItem['item']); + } }