diff --git a/src/Pages/Concerns/HydePage.php b/src/Pages/Concerns/HydePage.php index fb741358..08a730ea 100644 --- a/src/Pages/Concerns/HydePage.php +++ b/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/tests/Unit/Pages/BladePageUnitTest.php b/tests/Unit/Pages/BladePageUnitTest.php index fe1834b0..14cec200 100644 --- a/tests/Unit/Pages/BladePageUnitTest.php +++ b/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/tests/Unit/Pages/DocumentationPageUnitTest.php b/tests/Unit/Pages/DocumentationPageUnitTest.php index 4017fcf6..53aa35a7 100644 --- a/tests/Unit/Pages/DocumentationPageUnitTest.php +++ b/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/tests/Unit/Pages/HtmlPageUnitTest.php b/tests/Unit/Pages/HtmlPageUnitTest.php index f5f299fd..4603f594 100644 --- a/tests/Unit/Pages/HtmlPageUnitTest.php +++ b/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/tests/Unit/Pages/InMemoryPageUnitTest.php b/tests/Unit/Pages/InMemoryPageUnitTest.php index b2a9c2e6..acfb0da0 100644 --- a/tests/Unit/Pages/InMemoryPageUnitTest.php +++ b/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/tests/Unit/Pages/MarkdownPageUnitTest.php b/tests/Unit/Pages/MarkdownPageUnitTest.php index 42a51565..1c45d018 100644 --- a/tests/Unit/Pages/MarkdownPageUnitTest.php +++ b/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/tests/Unit/Pages/MarkdownPostUnitTest.php b/tests/Unit/Pages/MarkdownPostUnitTest.php index 4ed8dfbe..7768d9c2 100644 --- a/tests/Unit/Pages/MarkdownPostUnitTest.php +++ b/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()); + } }