diff --git a/docs/_data/partials/hyde-pages-api/hyde-page-methods.md b/docs/_data/partials/hyde-pages-api/hyde-page-methods.md index 8c4c9a1c88c..bb6922fd9cd 100644 --- a/docs/_data/partials/hyde-pages-api/hyde-page-methods.md +++ b/docs/_data/partials/hyde-pages-api/hyde-page-methods.md @@ -1,7 +1,7 @@
- + #### `make()` @@ -289,7 +289,9 @@ $page->navigationMenuGroup(): string #### `getCanonicalUrl()` -No description provided. +Get the canonical URL for the page to use in the `` tag. + +It can be explicitly set in the front matter using the `canonicalUrl` key, otherwise it will be generated based on the site URL and the output path, unless there is no configured base URL, leading to this returning null. ```php $page->getCanonicalUrl(): string diff --git a/packages/framework/src/Pages/Concerns/HydePage.php b/packages/framework/src/Pages/Concerns/HydePage.php index fb741358be9..08a730ea5fa 100644 --- a/packages/framework/src/Pages/Concerns/HydePage.php +++ b/packages/framework/src/Pages/Concerns/HydePage.php @@ -397,6 +397,13 @@ public function navigationMenuGroup(): ?string return $this->navigation->group; } + /** + * Get the canonical URL for the page to use in the `` tag. + * + * It can be explicitly set in the front matter using the `canonicalUrl` key, + * otherwise it will be generated based on the site URL and the output path, + * unless there is no configured base URL, leading to this returning null. + */ public function getCanonicalUrl(): ?string { /** @var ?string $value */ diff --git a/packages/framework/tests/Unit/Pages/BladePageUnitTest.php b/packages/framework/tests/Unit/Pages/BladePageUnitTest.php index fe1834b067a..14cec200c52 100644 --- a/packages/framework/tests/Unit/Pages/BladePageUnitTest.php +++ b/packages/framework/tests/Unit/Pages/BladePageUnitTest.php @@ -179,4 +179,21 @@ public function testMatter() { $this->assertInstanceOf(FrontMatter::class, (new BladePage('foo'))->matter()); } + + public function testGetCanonicalUrl() + { + $page = new BladePage('foo'); + $this->assertNull($page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com']); + + $this->assertSame('https://example.com/foo.html', $page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com', 'hyde.pretty_urls' => true]); + + $this->assertSame('https://example.com/foo', $page->getCanonicalUrl()); + + $page = new BladePage('foo', ['canonicalUrl' => 'foo']); + $this->assertSame('foo', $page->getCanonicalUrl()); + } } diff --git a/packages/framework/tests/Unit/Pages/DocumentationPageUnitTest.php b/packages/framework/tests/Unit/Pages/DocumentationPageUnitTest.php index 4017fcf60e7..53aa35a73c5 100644 --- a/packages/framework/tests/Unit/Pages/DocumentationPageUnitTest.php +++ b/packages/framework/tests/Unit/Pages/DocumentationPageUnitTest.php @@ -202,4 +202,21 @@ public function testSave() $this->assertFileExists('_docs/foo.md'); Filesystem::unlink('_docs/foo.md'); } + + public function testGetCanonicalUrl() + { + $page = new DocumentationPage('foo'); + $this->assertNull($page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com']); + + $this->assertSame('https://example.com/docs/foo.html', $page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com', 'hyde.pretty_urls' => true]); + + $this->assertSame('https://example.com/docs/foo', $page->getCanonicalUrl()); + + $page = new DocumentationPage('foo', ['canonicalUrl' => 'foo']); + $this->assertSame('foo', $page->getCanonicalUrl()); + } } diff --git a/packages/framework/tests/Unit/Pages/HtmlPageUnitTest.php b/packages/framework/tests/Unit/Pages/HtmlPageUnitTest.php index f5f299fd81c..4603f5942bd 100644 --- a/packages/framework/tests/Unit/Pages/HtmlPageUnitTest.php +++ b/packages/framework/tests/Unit/Pages/HtmlPageUnitTest.php @@ -217,4 +217,21 @@ public function testMatter() { $this->assertInstanceOf(FrontMatter::class, (new HtmlPage('404'))->matter()); } + + public function testGetCanonicalUrl() + { + $page = new HtmlPage('foo'); + $this->assertNull($page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com']); + + $this->assertSame('https://example.com/foo.html', $page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com', 'hyde.pretty_urls' => true]); + + $this->assertSame('https://example.com/foo', $page->getCanonicalUrl()); + + $page = new HtmlPage('foo', ['canonicalUrl' => 'foo']); + $this->assertSame('foo', $page->getCanonicalUrl()); + } } diff --git a/packages/framework/tests/Unit/Pages/InMemoryPageUnitTest.php b/packages/framework/tests/Unit/Pages/InMemoryPageUnitTest.php index b2a9c2e6f54..acfb0da0ed2 100644 --- a/packages/framework/tests/Unit/Pages/InMemoryPageUnitTest.php +++ b/packages/framework/tests/Unit/Pages/InMemoryPageUnitTest.php @@ -221,4 +221,21 @@ public function testMatter() { $this->assertInstanceOf(FrontMatter::class, (new InMemoryPage('404'))->matter()); } + + public function testGetCanonicalUrl() + { + $page = new InMemoryPage('foo'); + $this->assertNull($page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com']); + + $this->assertSame('https://example.com/foo.html', $page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com', 'hyde.pretty_urls' => true]); + + $this->assertSame('https://example.com/foo', $page->getCanonicalUrl()); + + $page = new InMemoryPage('foo', ['canonicalUrl' => 'foo']); + $this->assertSame('foo', $page->getCanonicalUrl()); + } } diff --git a/packages/framework/tests/Unit/Pages/MarkdownPageUnitTest.php b/packages/framework/tests/Unit/Pages/MarkdownPageUnitTest.php index 42a51565760..1c45d0181b5 100644 --- a/packages/framework/tests/Unit/Pages/MarkdownPageUnitTest.php +++ b/packages/framework/tests/Unit/Pages/MarkdownPageUnitTest.php @@ -230,4 +230,21 @@ public function testSave() $this->assertFileExists('_pages/foo.md'); Filesystem::unlink('_pages/foo.md'); } + + public function testGetCanonicalUrl() + { + $page = new MarkdownPage('foo'); + $this->assertNull($page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com']); + + $this->assertSame('https://example.com/foo.html', $page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com', 'hyde.pretty_urls' => true]); + + $this->assertSame('https://example.com/foo', $page->getCanonicalUrl()); + + $page = new MarkdownPage('foo', ['canonicalUrl' => 'foo']); + $this->assertSame('foo', $page->getCanonicalUrl()); + } } diff --git a/packages/framework/tests/Unit/Pages/MarkdownPostUnitTest.php b/packages/framework/tests/Unit/Pages/MarkdownPostUnitTest.php index 4ed8dfbec2d..7768d9c2d2d 100644 --- a/packages/framework/tests/Unit/Pages/MarkdownPostUnitTest.php +++ b/packages/framework/tests/Unit/Pages/MarkdownPostUnitTest.php @@ -230,4 +230,21 @@ public function testSave() $this->assertFileExists('_posts/foo.md'); Filesystem::unlink('_posts/foo.md'); } + + public function testGetCanonicalUrl() + { + $page = new MarkdownPost('foo'); + $this->assertNull($page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com']); + + $this->assertSame('https://example.com/posts/foo.html', $page->getCanonicalUrl()); + + self::mockConfig(['hyde.url' => 'https://example.com', 'hyde.pretty_urls' => true]); + + $this->assertSame('https://example.com/posts/foo', $page->getCanonicalUrl()); + + $page = new MarkdownPost('foo', ['canonicalUrl' => 'foo']); + $this->assertSame('foo', $page->getCanonicalUrl()); + } } diff --git a/packages/testing/src/Common/BaseHydePageUnitTest.php b/packages/testing/src/Common/BaseHydePageUnitTest.php index 73d97c162e4..645ef738efa 100644 --- a/packages/testing/src/Common/BaseHydePageUnitTest.php +++ b/packages/testing/src/Common/BaseHydePageUnitTest.php @@ -113,4 +113,6 @@ abstract public function testCompile(); abstract public function testMatter(); abstract public function testOutputPath(); + + abstract public function testGetCanonicalUrl(); }