chore: update kirby-seo plugin to v2.0.0-alpha.12
Update plugin from v1.1.2 to v2.0.0-alpha.12 for Kirby 5 compatibility. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
ff215de723
commit
04a14a7f1f
70 changed files with 6142 additions and 3 deletions
114
site/plugins/kirby-seo/snippets/prompts/content.php
Normal file
114
site/plugins/kirby-seo/snippets/prompts/content.php
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site */
|
||||
|
||||
$contentHtml = $page->render();
|
||||
|
||||
if ($contentHtml !== '' && class_exists('DOMDocument')) {
|
||||
$dom = new \DOMDocument('1.0', 'UTF-8');
|
||||
$previousLibxmlState = libxml_use_internal_errors(true);
|
||||
|
||||
$encoded = mb_encode_numericentity($contentHtml, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8');
|
||||
|
||||
$loaded = $dom->loadHTML('<?xml encoding="UTF-8"?>' . $encoded, LIBXML_NOERROR | LIBXML_NOWARNING | LIBXML_NONET);
|
||||
|
||||
libxml_clear_errors();
|
||||
libxml_use_internal_errors($previousLibxmlState);
|
||||
|
||||
if ($loaded !== false) {
|
||||
foreach (
|
||||
[
|
||||
'script',
|
||||
'style',
|
||||
'noscript',
|
||||
'template',
|
||||
'svg',
|
||||
'canvas',
|
||||
'iframe',
|
||||
'video',
|
||||
'audio',
|
||||
'object',
|
||||
'embed',
|
||||
'source',
|
||||
'track',
|
||||
'nav',
|
||||
'footer',
|
||||
'aside',
|
||||
'form',
|
||||
'button',
|
||||
'input',
|
||||
'select',
|
||||
'textarea',
|
||||
'label',
|
||||
'menu',
|
||||
'header',
|
||||
] as $tag
|
||||
) {
|
||||
$nodes = $dom->getElementsByTagName($tag);
|
||||
for ($i = $nodes->length - 1; $i >= 0; $i--) {
|
||||
$node = $nodes->item($i);
|
||||
if ($node !== null && $node->parentNode !== null) {
|
||||
$node->parentNode->removeChild($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$xpath = new \DOMXPath($dom);
|
||||
foreach (
|
||||
[
|
||||
'navigation',
|
||||
'banner',
|
||||
'contentinfo',
|
||||
'complementary',
|
||||
'search',
|
||||
'menu',
|
||||
'menubar',
|
||||
'toolbar',
|
||||
] as $role
|
||||
) {
|
||||
$nodes = $xpath->query("//*[@role='{$role}']");
|
||||
if ($nodes === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($nodes as $node) {
|
||||
if ($node->parentNode !== null) {
|
||||
$node->parentNode->removeChild($node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$body = $dom->getElementsByTagName('body')->item(0) ?? $dom->documentElement;
|
||||
if ($body instanceof \DOMNode) {
|
||||
$innerHtml = '';
|
||||
foreach ($body->childNodes as $child) {
|
||||
$innerHtml .= $dom->saveHTML($child);
|
||||
}
|
||||
|
||||
if ($innerHtml !== '') {
|
||||
$contentHtml = $innerHtml;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$blockClosingPattern = 'p|div|section|article|main|aside|header|footer|li|ul|ol|dl|blockquote|pre|figure|figcaption|h[1-6]|table|thead|tbody|tfoot|tr|td|th|dd|dt';
|
||||
$contentHtml = preg_replace('~<(?:br|hr)\b[^>]*?>~i', "\n", $contentHtml);
|
||||
$contentHtml = preg_replace('~</(?:' . $blockClosingPattern . ')>~i', "\n", $contentHtml);
|
||||
|
||||
$text = Str::unhtml($contentHtml);
|
||||
$text = Str::replace($text, "\r", "\n");
|
||||
$text = preg_replace("/[ \t\x{00A0}\x{202F}\x{2007}\x{2060}]+/u", ' ', $text);
|
||||
$text = preg_replace("/ *\n+ */", "\n", $text);
|
||||
$text = preg_replace("/\n{3,}/", "\n\n", $text);
|
||||
|
||||
$content = trim($text);
|
||||
|
||||
?>
|
||||
|
||||
<content>
|
||||
<?= htmlspecialchars($content, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') ?>
|
||||
</content>
|
||||
46
site/plugins/kirby-seo/snippets/prompts/introduction.php
Normal file
46
site/plugins/kirby-seo/snippets/prompts/introduction.php
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $instructions
|
||||
** @var string|null $edit */ ?>
|
||||
|
||||
<role>
|
||||
You are a professional SEO copywriter for <?= $site->title() ?>. Create high-quality content. Mimic the site's tone and style. You'll be rewarded based on the conversion rate.
|
||||
</role>
|
||||
|
||||
<rules>
|
||||
- You MUST only output the answer without additional prose or introduction.
|
||||
- You MUST mimic the site's tone and style. DO NOT shift register (informal stays informal).
|
||||
- The output language MUST be <language><?= $site->lang() ?></language>. Translate the content into <?= $site->lang() ?>.
|
||||
- ALWAYS and ONLY provide exactly one answer. DO NOT suggest multiple answers.
|
||||
- NEVER output any formatting. No new lines, no HTML tags, no quotes, no markdown.
|
||||
- NEVER output or introduce information that is not provided in the content.
|
||||
- NEVER output duplicate content in the same answer.
|
||||
</rules>
|
||||
|
||||
<?php if (isset($edit) && $edit !== null && $edit !== '') : ?>
|
||||
<primary-editing-task>
|
||||
YOU ARE EDITING EXISTING CONTENT - NOT CREATING NEW CONTENT.
|
||||
|
||||
Current text that needs editing:
|
||||
<current-value><?= $edit ?></current-value>
|
||||
|
||||
CRITICAL EDITING RULES:
|
||||
- Start from the text above and modify ONLY what is requested
|
||||
- Preserve as much of the original as possible
|
||||
- Keep the same style, tone, and structure
|
||||
- Change ONLY the specific parts mentioned in the instructions below
|
||||
</primary-editing-task>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (isset($instructions) && $instructions !== null && $instructions !== '') : ?>
|
||||
<user-instructions>
|
||||
<?php if (isset($edit) && $edit !== null && $edit !== '') : ?>
|
||||
Apply ONLY these changes to the text above:
|
||||
<?php else : ?>
|
||||
The user has provided these specific instructions:
|
||||
<?php endif ?>
|
||||
<?= $instructions ?>
|
||||
</user-instructions>
|
||||
<?php endif ?>
|
||||
28
site/plugins/kirby-seo/snippets/prompts/meta.php
Normal file
28
site/plugins/kirby-seo/snippets/prompts/meta.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $currentField */
|
||||
|
||||
$meta = $page->metadata();
|
||||
$currentField = $currentField ?? null;
|
||||
|
||||
$metaFields = [
|
||||
'metaTitle' => 'Meta Title',
|
||||
'metaDescription' => 'Meta Description',
|
||||
'ogTitle' => 'Open Graph Title',
|
||||
'ogDescription' => 'Open Graph Description'
|
||||
];
|
||||
?>
|
||||
|
||||
<existing-metadata>
|
||||
<?php foreach ($metaFields as $key => $label) : ?>
|
||||
<?php
|
||||
$value = $meta->get($key);
|
||||
if ($currentField === $key || !$value || $value === '') {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<<?= $key ?>><?= $value ?></<?= $key ?>>
|
||||
<?php endforeach ?>
|
||||
</existing-metadata>
|
||||
25
site/plugins/kirby-seo/snippets/prompts/site-meta.php
Normal file
25
site/plugins/kirby-seo/snippets/prompts/site-meta.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $currentField */
|
||||
|
||||
$currentField = $currentField ?? null;
|
||||
|
||||
$metaFields = [
|
||||
'metaDescription' => 'Site Meta Description',
|
||||
'ogDescription' => 'Site Open Graph Description',
|
||||
'ogSiteName' => 'Site Name'
|
||||
];
|
||||
?>
|
||||
|
||||
<existing-site-metadata>
|
||||
<?php foreach ($metaFields as $key => $label) : ?>
|
||||
<?php
|
||||
$value = $site->$key()->value();
|
||||
if ($currentField === $key || !$value || $value === '') {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<<?= $key ?>><?= $value ?></<?= $key ?>>
|
||||
<?php endforeach ?>
|
||||
</existing-site-metadata>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $instructions
|
||||
** @var string|null $edit */
|
||||
|
||||
$meta = $page->metadata();
|
||||
|
||||
snippet('seo/prompts/introduction', [
|
||||
'instructions' => $instructions ?? null,
|
||||
'edit' => $edit ?? null
|
||||
]); ?>
|
||||
|
||||
<task>
|
||||
Create a useful meta description for this page called <page-title><?= $page->title()->value() ?></page-title>. <?php if ($page->isHomePage()) : ?>This page is the homepage of the website.<?php endif ?>
|
||||
|
||||
The entire meta description SHOULD be between 120 and 158 characters long.
|
||||
|
||||
You'll receive the content of the page as well as any meta tags that are already set below.
|
||||
</task>
|
||||
|
||||
<?php snippet('seo/prompts/meta', ['currentField' => 'metaDescription']);
|
||||
snippet('seo/prompts/content');
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $instructions
|
||||
** @var string|null $edit */
|
||||
|
||||
$meta = $page->metadata();
|
||||
|
||||
snippet('seo/prompts/introduction', [
|
||||
'instructions' => $instructions ?? null,
|
||||
'edit' => $edit ?? null
|
||||
]); ?>
|
||||
|
||||
<task>
|
||||
Create a useful open graph description for this page called <page-title><?= $page->title()->value() ?></page-title>. <?php if ($page->isHomePage()) : ?>This page is the homepage of the website.<?php endif ?>
|
||||
This description will be shown on social media platforms like Facebook, WhatsApp and LinkedIn.
|
||||
|
||||
The entire meta description SHOULD be between 120 and 158 characters long.
|
||||
|
||||
You'll receive the content of the page as well as any meta tags that are already set below.
|
||||
</task>
|
||||
|
||||
<?php snippet('seo/prompts/meta', ['currentField' => 'ogDescription']);
|
||||
snippet('seo/prompts/content');
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $instructions
|
||||
** @var string|null $edit */
|
||||
|
||||
snippet('seo/prompts/introduction', [
|
||||
'instructions' => $instructions ?? null,
|
||||
'edit' => $edit ?? null
|
||||
]); ?>
|
||||
|
||||
<task>
|
||||
Create a useful GLOBAL open graph description for this site <site-title><?= $site->title()->value() ?>.</site-title>
|
||||
This description will be shown on social media platforms like Facebook, WhatsApp and LinkedIn.
|
||||
This description is meant as FALLBACK for when the page does not have a meta description itself.
|
||||
This description should be unique and relevant to the site's content.
|
||||
|
||||
The entire meta description SHOULD be between 120 and 158 characters long.
|
||||
|
||||
You'll receive the content of the home page as well as any meta tags that are already set below.
|
||||
</task>
|
||||
|
||||
<?php snippet('seo/prompts/site-meta', ['currentField' => 'ogDescription']);
|
||||
snippet('seo/prompts/content'); ?>
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $instructions
|
||||
** @var string|null $edit */
|
||||
|
||||
snippet('seo/prompts/introduction', [
|
||||
'instructions' => $instructions ?? null,
|
||||
'edit' => $edit ?? null
|
||||
]); ?>
|
||||
|
||||
<task>
|
||||
Create a useful GLOBAL meta description for this site <site-title><?= $site->title()->value() ?>.</site-title>
|
||||
This description is meant as FALLBACK for when the page does not have a meta description itself.
|
||||
This description should be unique and relevant to the site's content.
|
||||
|
||||
The entire meta description SHOULD be between 120 and 158 characters long.
|
||||
|
||||
You'll receive the content of the home page as well as any meta tags that are already set below.
|
||||
</task>
|
||||
|
||||
<?php snippet('seo/prompts/site-meta', ['currentField' => 'metaDescription']);
|
||||
snippet('seo/prompts/content'); ?>
|
||||
39
site/plugins/kirby-seo/snippets/prompts/tasks/title.php
Normal file
39
site/plugins/kirby-seo/snippets/prompts/tasks/title.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
use Kirby\Toolkit\Str;
|
||||
|
||||
/** @var \Kirby\Cms\Page $page
|
||||
** @var \Kirby\Cms\Site $site
|
||||
** @var string|null $instructions
|
||||
** @var string|null $edit */
|
||||
|
||||
$meta = $page->metadata();
|
||||
|
||||
snippet('seo/prompts/introduction', [
|
||||
'instructions' => $instructions ?? null,
|
||||
'edit' => $edit ?? null
|
||||
]); ?>
|
||||
|
||||
<task>
|
||||
Create a useful meta title for this page called <page-title><?= $page->title()->value() ?></page-title>. <?php if ($page->isHomePage()) : ?>This page is the homepage of the website. AVOID an overly generic title such as 'Home'.<?php endif ?>
|
||||
|
||||
<?php if ($page->useTitleTemplate()->isEmpty() ? true : $page->useTitleTemplate()->toBool()):
|
||||
$template = $meta->get('metaTemplate');
|
||||
$templatePreview = $page->toString($template, ['title' => '{{ title }}']);
|
||||
$templateBaseLength = Str::length($page->toString($template, ['title' => '']));
|
||||
?>
|
||||
The final page title will be rendered as:
|
||||
|
||||
<template><?= $templatePreview ?></template>
|
||||
|
||||
Where {{ title }} is your page title. The entire title SHOULD be between <?= max(0, 50 - $templateBaseLength) ?>-<?= max(max(0, 50 - $templateBaseLength), 60 - $templateBaseLength) ?> characters long.
|
||||
DO NOT output the Title Template. ONLY output what should be placed inside {{ title }}. DO NOT repeat ANYTHING that exists in the template. You MUST NOT repeat the name of the site.
|
||||
<?php else: ?>
|
||||
Your response will be set as title without any changes. The entire title SHOULD be between 50-60 characters long.
|
||||
<?php endif; ?>
|
||||
|
||||
If useful for the customers niche, include a keyword for the location. AVOID for global companies or niche subpages.
|
||||
</task>
|
||||
|
||||
<?php snippet('seo/prompts/meta', ['currentField' => 'metaTitle']);
|
||||
snippet('seo/prompts/content');
|
||||
Loading…
Add table
Add a link
Reference in a new issue