From e80a33bf2ad4fe1b47037add7470a6c2770f4036 Mon Sep 17 00:00:00 2001 From: Yassine Doghri <yassine@doghri.fr> Date: Wed, 1 May 2024 15:41:13 +0000 Subject: [PATCH] feat(plugins): add siteHead hook to add custom meta tags to public pages --- app/Config/View.php | 3 ++- app/Helpers/rss_helper.php | 4 ++-- app/Views/Decorators/SiteHead.php | 36 +++++++++++++++++++++++++++++ modules/Plugins/BasePlugin.php | 8 +++++-- modules/Plugins/PluginInterface.php | 6 +++-- modules/Plugins/Plugins.php | 7 +++--- 6 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 app/Views/Decorators/SiteHead.php diff --git a/app/Config/View.php b/app/Config/View.php index 7225324cb8..c43985de57 100644 --- a/app/Config/View.php +++ b/app/Config/View.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace Config; +use App\Views\Decorators\SiteHead; use CodeIgniter\Config\View as BaseView; use CodeIgniter\View\ViewDecoratorInterface; use ViewComponents\Decorator; @@ -53,5 +54,5 @@ class View extends BaseView * * @var list<class-string<ViewDecoratorInterface>> */ - public array $decorators = [Decorator::class]; + public array $decorators = [Decorator::class, SiteHead::class]; } diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php index dc5e1cee45..bf7918ba94 100644 --- a/app/Helpers/rss_helper.php +++ b/app/Helpers/rss_helper.php @@ -298,7 +298,7 @@ if (! function_exists('get_rss_feed')) { } // run plugins hook at the end - $plugins->setChannelTag($podcast, $channel); + $plugins->channelTag($podcast, $channel); foreach ($episodes as $episode) { if ($episode->is_premium && ! $subscription instanceof Subscription) { @@ -460,7 +460,7 @@ if (! function_exists('get_rss_feed')) { ], $item); } - $plugins->setItemTag($episode, $item); + $plugins->itemTag($episode, $item); } return $rss->asXML(); diff --git a/app/Views/Decorators/SiteHead.php b/app/Views/Decorators/SiteHead.php new file mode 100644 index 0000000000..ff8e91a1b0 --- /dev/null +++ b/app/Views/Decorators/SiteHead.php @@ -0,0 +1,36 @@ +<?php + +declare(strict_types=1); + +namespace App\Views\Decorators; + +use CodeIgniter\View\ViewDecoratorInterface; + +class SiteHead implements ViewDecoratorInterface +{ + private static int $renderedCount = 0; + + public static function decorate(string $html): string + { + if (url_is(config('Admin')->gateway . '*') || url_is(config('Install')->gateway)) { + return $html; + } + + if (static::$renderedCount > 0) { + return $html; + } + + ob_start(); // Start output buffering + // run hook to add tags to <head> + service('plugins')->siteHead(); + $metaTags = ob_get_contents(); // Store buffer in variable + ob_end_clean(); + + if (str_contains($html, '</head>')) { + $html = str_replace('</head>', "\n\t{$metaTags}\n</head>", $html); + ++static::$renderedCount; + } + + return $html; + } +} diff --git a/modules/Plugins/BasePlugin.php b/modules/Plugins/BasePlugin.php index d73683c1d4..973dc31eeb 100644 --- a/modules/Plugins/BasePlugin.php +++ b/modules/Plugins/BasePlugin.php @@ -59,11 +59,15 @@ abstract class BasePlugin implements PluginInterface // TODO: setup navigation and views? } - public function setChannelTag(Podcast $podcast, SimpleRSSElement $channel): void + public function channelTag(Podcast $podcast, SimpleRSSElement $channel): void { } - public function setItemTag(Episode $episode, SimpleRSSElement $item): void + public function itemTag(Episode $episode, SimpleRSSElement $item): void + { + } + + public function siteHead(): void { } diff --git a/modules/Plugins/PluginInterface.php b/modules/Plugins/PluginInterface.php index 7c46f18b57..229ff29084 100644 --- a/modules/Plugins/PluginInterface.php +++ b/modules/Plugins/PluginInterface.php @@ -10,7 +10,9 @@ use App\Libraries\SimpleRSSElement; interface PluginInterface { - public function setChannelTag(Podcast $podcast, SimpleRSSElement $channel): void; + public function channelTag(Podcast $podcast, SimpleRSSElement $channel): void; - public function setItemTag(Episode $episode, SimpleRSSElement $item): void; + public function itemTag(Episode $episode, SimpleRSSElement $item): void; + + public function siteHead(): void; } diff --git a/modules/Plugins/Plugins.php b/modules/Plugins/Plugins.php index 48c6a42a70..0995cc2a6c 100644 --- a/modules/Plugins/Plugins.php +++ b/modules/Plugins/Plugins.php @@ -9,8 +9,9 @@ use App\Entities\Podcast; use App\Libraries\SimpleRSSElement; /** - * @method void setChannelTag(Podcast $podcast, SimpleRSSElement $channel) - * @method void setItemTag(Episode $episode, SimpleRSSElement $item) + * @method void channelTag(Podcast $podcast, SimpleRSSElement $channel) + * @method void itemTag(Episode $episode, SimpleRSSElement $item) + * @method string siteHead() */ class Plugins { @@ -19,7 +20,7 @@ class Plugins /** * @var list<string> */ - protected const HOOKS = ['setChannelTag', 'setItemTag']; + protected const HOOKS = ['channelTag', 'itemTag', 'siteHead']; /** * @var array<BasePlugin> -- GitLab