Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor page metadata to use front matter schemas #365

Merged
merged 35 commits into from
Aug 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9e37fba
Add PHPDoc
caendesilva Aug 7, 2022
dd71aa9
Use mocks instead of making new classes
caendesilva Aug 7, 2022
9135ff7
Add canonicalUrl property to page schema
caendesilva Aug 7, 2022
96c5f57
Construct canonicalUrl property
caendesilva Aug 7, 2022
69af2c1
Apply fixes from StyleCI
StyleCIBot Aug 7, 2022
000c3df
Test covers PageSchema
caendesilva Aug 7, 2022
5917471
Page must be made after configuration is changed
caendesilva Aug 7, 2022
6f2f461
Use canonicalUrl property instead of getter
caendesilva Aug 7, 2022
06145be
Remove getters only used in tests
caendesilva Aug 7, 2022
51c651d
Check if not empty instead of is set
caendesilva Aug 7, 2022
dcef1ae
Test custom canonical link can be set in front matter
caendesilva Aug 7, 2022
7f6c1f4
Inline setup method
caendesilva Aug 7, 2022
7b46b86
Inline helper method
caendesilva Aug 7, 2022
acfdded
Remove self-referencing link
caendesilva Aug 7, 2022
9babe8f
Merge unit test into main feature test
caendesilva Aug 7, 2022
93f0d0c
Use more granular tests
caendesilva Aug 7, 2022
a117ff4
Always add title metadata when a title is set
caendesilva Aug 7, 2022
4be50cc
Use the Meta facade
caendesilva Aug 7, 2022
0957136
Escape output to ensure tags are valid
caendesilva Aug 7, 2022
b45aef5
Remove trailing slash from meta tags
caendesilva Aug 7, 2022
40ab6c7
Normalize expected attribute order
caendesilva Aug 7, 2022
a649e24
Merge unit tests into feature test
caendesilva Aug 7, 2022
d1c7f0c
Normalize expected link format
caendesilva Aug 7, 2022
525fd22
Create new Meta::link() helper
caendesilva Aug 7, 2022
5481f3e
Use the new Meta::link helper
caendesilva Aug 7, 2022
81d80f9
Apply fixes from StyleCI
StyleCIBot Aug 7, 2022
c93a9ad
Check if not empty
caendesilva Aug 7, 2022
87ee16e
Move up assignment to group similar ones
caendesilva Aug 7, 2022
8e9bf6b
Mark method as internal
caendesilva Aug 7, 2022
3b75932
Apply fixes from StyleCI
StyleCIBot Aug 7, 2022
e40e157
Move global page metadata to Meta class
caendesilva Aug 7, 2022
f3d8cee
Merge branch 'front-matter-schemas' of github.com:hydephp/develop int…
caendesilva Aug 7, 2022
f3e75c8
Apply fixes from StyleCI
StyleCIBot Aug 7, 2022
45c21b9
Update RELEASE_NOTES.md
caendesilva Aug 7, 2022
80e2178
Merge branch 'front-matter-schemas' of github.com:hydephp/develop int…
caendesilva Aug 7, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ This update contains **breaking changes** to the internal API regarding page mod

The update makes large changes to how dynamic data is constructed. Instead of generating page data at runtime, now the data is generated when constructing a page object. This gives the major benefit of being able to see all dynamic data right away, without having to render the page.

The way metadata tags are handled internally is also refactored. The rendered result should not be affected.

### Added
- Added `compile()` method to `Facades\Markdown`, replacing the `parse()` method of the same class
- Adds new actions to handle complex dynamic constructors
- Adds new front matter schema traits to define the public API for front matter and hold their data
- Adds new Meta::link() helper to create `<link>` tags

### Changed
- Breaking: Rename AbstractMarkdownPage constructor parameter `slug` to `identifier`
Expand Down
25 changes: 25 additions & 0 deletions packages/framework/src/Concerns/FrontMatter/Schemas/PageSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Hyde\Framework\Actions\Constructors\FindsNavigationDataForPage;
use Hyde\Framework\Actions\Constructors\FindsTitleForPage;
use Hyde\Framework\Hyde;
use JetBrains\PhpStorm\ArrayShape;

trait PageSchema
Expand All @@ -15,12 +16,36 @@ trait PageSchema
*/
public string $title;

/**
* The settings for how the page should be presented in the navigation menu.
*/
#[ArrayShape(['title' => 'string', 'hidden' => 'bool', 'priority' => 'int'])]
public ?array $navigation = null;

/**
* The canonical URL of the page.
*
* @var string|null
*/
public ?string $canonicalUrl = null;

protected function constructPageSchema(): void
{
$this->title = FindsTitleForPage::run($this);
$this->navigation = FindsNavigationDataForPage::run($this);
$this->canonicalUrl = $this->makeCanonicalUrl();
}

protected function makeCanonicalUrl(): ?string
{
if (! empty($this->matter('canonicalUrl'))) {
return $this->matter('canonicalUrl');
}

if (Hyde::hasSiteUrl() && ! empty($this->identifier)) {
return $this->getRoute()->getQualifiedUrl();
}

return null;
}
}
52 changes: 7 additions & 45 deletions packages/framework/src/Contracts/AbstractPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

use Hyde\Framework\Actions\SourceFileParser;
use Hyde\Framework\Concerns\FrontMatter\Schemas\PageSchema;
use Hyde\Framework\Helpers\Features;
use Hyde\Framework\Helpers\Meta;
use Hyde\Framework\Hyde;
use Hyde\Framework\Models\FrontMatter;
use Hyde\Framework\Models\Pages\MarkdownPost;
use Hyde\Framework\Models\Route;
use Hyde\Framework\Services\DiscoveryService;
use Hyde\Framework\Services\RssFeedService;
use Illuminate\Support\Collection;

/**
Expand Down Expand Up @@ -163,12 +161,9 @@ public function getBladeView(): string
/** @inheritDoc */
abstract public function compile(): string;

public function getCanonicalUrl(): string
{
return $this->getRoute()->getQualifiedUrl();
}

/**
* @internal
*
* @return string[]
*
* @psalm-return list<string>
Expand All @@ -177,25 +172,13 @@ public function getDynamicMetadata(): array
{
$array = [];

if ($this->canUseCanonicalUrl()) {
$array[] = '<link rel="canonical" href="'.$this->getCanonicalUrl().'" />';
}

if (Features::sitemap()) {
$array[] = '<link rel="sitemap" type="application/xml" title="Sitemap" href="'.Hyde::url('sitemap.xml').'" />';
if (! empty($this->canonicalUrl)) {
$array[] = Meta::link('canonical', $this->canonicalUrl);
}

if (Features::rss()) {
$array[] = $this->makeRssFeedLink();
}

if (isset($this->title)) {
if ($this->hasTwitterTitleInConfig()) {
$array[] = '<meta name="twitter:title" content="'.$this->htmlTitle().'" />';
}
if ($this->hasOpenGraphTitleInConfig()) {
$array[] = '<meta property="og:title" content="'.$this->htmlTitle().'" />';
}
if (! empty($this->title)) {
$array[] = Meta::name('twitter:title', $this->htmlTitle());
$array[] = Meta::property('title', $this->htmlTitle());
}

if ($this instanceof MarkdownPost) {
Expand All @@ -218,27 +201,6 @@ public function renderPageMetadata(): string
);
}

public function canUseCanonicalUrl(): bool
{
return Hyde::hasSiteUrl() && isset($this->identifier);
}

public function hasTwitterTitleInConfig(): bool
{
return str_contains(json_encode(config('hyde.meta', [])), 'twitter:title');
}

public function hasOpenGraphTitleInConfig(): bool
{
return str_contains(json_encode(config('hyde.meta', [])), 'og:title');
}

protected function makeRssFeedLink(): string
{
return '<link rel="alternate" type="application/rss+xml" title="'.RssFeedService::getDescription().
'" href="'.Hyde::url(RssFeedService::getDefaultOutputFilename()).'" />';
}

public function showInNavigation(): bool
{
return ! $this->navigation['hidden'];
Expand Down
43 changes: 43 additions & 0 deletions packages/framework/src/Helpers/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

namespace Hyde\Framework\Helpers;

use Hyde\Framework\Hyde;
use Hyde\Framework\Services\RssFeedService;

/**
* Helpers to fluently declare HTML meta tags.
*
Expand All @@ -21,6 +24,19 @@ public static function property(string $property, string $content): string
return '<meta property="'.e($property).'" content="'.e($content).'">';
}

public static function link(string $rel, string $href, array $attr = []): string
{
if (! $attr) {
return '<link rel="'.e($rel).'" href="'.e($href).'">';
}

$attributes = collect($attr)->map(function ($value, $key) {
return e($key).'="'.e($value).'"';
})->implode(' ');

return '<link rel="'.e($rel).'" href="'.e($href).'" '.$attributes.'>';
}

public static function render(array $withMergedData = []): string
{
return implode(
Expand Down Expand Up @@ -52,6 +68,33 @@ protected static function filterUnique(array $meta): array
}

public static function getGlobalMeta(): array
{
return array_merge(
static::getDynamicMeta(),
static::getConfiguredMeta()
);
}

protected static function getDynamicMeta(): array
{
$array = [];

if (Features::sitemap()) {
$array[] = Meta::link('sitemap', Hyde::url('sitemap.xml'), [
'type' => 'application/xml', 'title' => 'Sitemap',
]);
}

if (Features::rss()) {
$array[] = Meta::link('alternate', Hyde::url(RssFeedService::getDefaultOutputFilename()), [
'type' => 'application/rss+xml', 'title' => RssFeedService::getDescription(),
]);
}

return $array;
}

protected static function getConfiguredMeta(): array
{
return config('hyde.meta', []);
}
Expand Down
Loading