Skip to content

Commit

Permalink
add helper method for findPageOrDraft, bypasses getkirby/kirby#6339
Browse files Browse the repository at this point in the history
Signed-off-by: Tobias Möritz <[email protected]>
  • Loading branch information
tobimori authored Mar 16, 2024
1 parent 41dc8b2 commit fa23801
Showing 1 changed file with 62 additions and 52 deletions.
114 changes: 62 additions & 52 deletions classes/Meta.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace tobimori\Seo;

use Kirby\Cms\App;
use Kirby\Cms\Page;
use Kirby\Content\Field;
use Kirby\Exception\InvalidArgumentException;
Expand Down Expand Up @@ -52,7 +53,7 @@ protected function metaArray(): array
*/
$meta =
[
'title' => 'metaTitle',
'title' => 'title',
'description' => 'metaDescription',
'date' => fn () => $this->page->modified($this->dateFormat()),
'og:title' => 'ogTitle',
Expand All @@ -72,36 +73,31 @@ protected function metaArray(): array
}

// only add canonical and alternate tags if the page is indexable
// we have to resolve this lazily (using a callable) to avoid an infinite loop
$allowsIndexFn = fn () => !$robotsActive || !Str::contains($this->robots(), 'noindex');

// canonical
$canonicalFn = fn () => $allowsIndexFn() ? $this->canonicalUrl() : null;
$meta['canonical'] = $canonicalFn;
$meta['og:url'] = $canonicalFn;

// Multi-lang alternate tags
if (kirby()->languages()->count() > 1 && kirby()->language() !== null) {
foreach (kirby()->languages() as $lang) {
// only add alternate tags if the page is indexable
$meta['alternate'][] = fn () => $allowsIndexFn() ? [
'hreflang' => $lang->code(),
'href' => $this->page->url($lang->code()),
] : null;

if ($lang !== kirby()->language()) {
$meta['og:locale:alternate'][] = fn () => $lang->code();
if (!$robotsActive || !Str::contains($this->robots(), 'noindex')) {
$meta['canonical'] = 'canonicalUrl';
$meta['og:url'] = 'canonicalUrl';

// Multi-lang
if (kirby()->languages()->count() > 1 && kirby()->language() !== null) {
foreach (kirby()->languages() as $lang) {
$meta['alternate'][] = [
'hreflang' => fn () => $lang->code(),
'href' => fn () => $this->page->url($lang->code()),
];

if ($lang !== kirby()->language()) {
$meta['og:locale:alternate'][] = fn () => $lang->code();
}
}
}

// only add alternate tags if the page is indexable
$meta['alternate'][] = fn () => $allowsIndexFn() ? [
'hreflang' => 'x-default',
'href' => $this->page->url(kirby()->language()->code()),
] : null;
$meta['og:locale'] = fn () => kirby()->language()->locale(LC_ALL);
} else {
$meta['og:locale'] = fn () => $this->locale(LC_ALL);
$meta['alternate'][] = [
'hreflang' => fn () => 'x-default',
'href' => fn () => $this->page->url(kirby()->language()->code()),
];
$meta['og:locale'] = fn () => kirby()->language()->locale(LC_ALL);
} else {
$meta['og:locale'] = fn () => $this->locale(LC_ALL);
}
}

// Twitter tags "opt-in" - TODO: wip
Expand Down Expand Up @@ -178,9 +174,12 @@ public function snippetData(array $raw = null): array

// allow overrides from metaDefaults for keys that are a callable or array by default
// (all fields from meta array that are not part of the regular cascade)
if ((is_callable($value) || is_array($value)) && $mergeWithDefaults && array_key_exists($name, $this->metaDefaults)) {
$this->consumed[] = $name;
$value = $this->metaDefaults[$name];

if (is_callable($value) || is_array($value)) {
if ($mergeWithDefaults && array_key_exists($name, $this->metaDefaults)) {
$this->consumed[] = $name;
$value = $this->metaDefaults[$name];
}
}

// if the value is a string, we know it's a field name
Expand Down Expand Up @@ -298,13 +297,8 @@ public function get(string $key, array $exclude = []): Field
}

// Track consumed keys, so we don't output legacy field values
$toBeConsumed = $key;
if (
(array_key_exists($toBeConsumed, $this->metaDefaults)
|| array_key_exists($toBeConsumed = $this->findTagForField($toBeConsumed), $this->metaDefaults))
&& !in_array($toBeConsumed, $this->consumed)
) {
$this->consumed[] = $toBeConsumed;
if (A::has($this->metaDefaults, $key)) {
$this->consumed[] = $key;
}

foreach (array_diff($cascade, $exclude) as $method) {
Expand Down Expand Up @@ -377,12 +371,6 @@ protected function fallbackFields(string $key): Field|null
return null;
}


protected function findTagForField(string $fieldName): string|null
{
return array_search($fieldName, $this->metaArray());
}

/**
* Get the meta value for a given key from the page's meta
* array, which can be set in the page's model metaDefaults method
Expand All @@ -402,7 +390,7 @@ protected function programmatic(string $key): Field|null
* try looking it up in the meta array
* maybe it is a meta tag and not a field name?
*/
if (!isset($val) && ($key = $this->findTagForField($key)) && array_key_exists($key, $this->metaDefaults)) {
if (!isset($val) && ($key = array_search($key, $this->metaArray())) && array_key_exists($key, $this->metaDefaults)) {
$val = $this->metaDefaults[$key];
}

Expand All @@ -424,7 +412,7 @@ protected function programmatic(string $key): Field|null
}

if (is_a($val, 'Kirby\Content\Field')) {
return new Field($this->page, $key, $val->value());
return $val;
}

return new Field($this->page, $key, $val);
Expand Down Expand Up @@ -504,10 +492,10 @@ private function canInherit(string $key): bool
/**
* Applies the title template, and returns the correct title
*/
public function metaTitle()
public function title()
{
$title = $this->get('metaTitle');
$template = $this->get('metaTemplate');
$title = $this->metaTitle();
$template = $this->metaTemplate();

$useTemplate = $this->page->useTitleTemplate();
$useTemplate = $useTemplate->isEmpty() ? true : $useTemplate->toBool();
Expand All @@ -532,8 +520,8 @@ public function metaTitle()
*/
public function ogTitle()
{
$title = $this->get('metaTitle');
$template = $this->get('ogTemplate');
$title = $this->metaTitle();
$template = $this->ogTemplate();

$useTemplate = $this->page->useOgTemplate();
$useTemplate = $useTemplate->isEmpty() ? true : $useTemplate->toBool();
Expand Down Expand Up @@ -645,4 +633,26 @@ public function ogImage(): string|null

return null;
}

/**
* Helper method the get the current page from the URL path,
* for use in programmatic blueprints
*/
public static function currentPage(): Page|null
{
$path = App::instance()->request()->url()->toString();
$matches = Str::match($path, "/pages\/([a-zA-Z0-9-_+]+)\/?/m");
$segments = Str::split($matches[1], '+');

$page = App::instance()->site();
foreach ($segments as $segment) {
if ($page = $page->findPageOrDraft($segment)) {
continue;
}

return null;
}

return $page;
}
}

0 comments on commit fa23801

Please sign in to comment.