Files
larablog/app/Domain/Theme/ThemeSlot.php
T
ak 263b98b218 Initial baseline: LaraBlog core with plugin commerce surface.
Captures the current working tree after theme slots, ArticleAccess, and the payment / paid-content plugins so subsequent work has a reviewable git history.
2026-08-12 01:15:38 +08:00

113 lines
2.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Domain\Theme;
use App\Domain\Plugin\Hook;
/**
* Named injection points for themes / plugins / site snippets.
*
* Themes call ThemeSlot::render('head') (or @themeslot('head')).
* Plugins listen on Hook event "theme.{slot}".
* Admin SnippetSettings also appends into these slots at boot.
*/
final class ThemeSlot
{
public const HEAD = 'head';
public const BODY_START = 'body_start';
public const BODY_END = 'body_end';
public const HEADER_AFTER = 'header_after';
public const NAV_AFTER = 'nav_after';
public const CONTENT_BEFORE = 'content_before';
public const CONTENT_AFTER = 'content_after';
public const ARTICLE_TOP = 'article_top';
public const ARTICLE_BOTTOM = 'article_bottom';
public const SIDEBAR_BEFORE = 'sidebar_before';
public const SIDEBAR = 'sidebar';
public const SIDEBAR_AFTER = 'sidebar_after';
public const FOOTER_BEFORE = 'footer_before';
public const FOOTER_AFTER = 'footer_after';
/** @return list<string> */
public static function all(): array
{
return [
self::HEAD,
self::BODY_START,
self::BODY_END,
self::HEADER_AFTER,
self::NAV_AFTER,
self::CONTENT_BEFORE,
self::CONTENT_AFTER,
self::ARTICLE_TOP,
self::ARTICLE_BOTTOM,
self::SIDEBAR_BEFORE,
self::SIDEBAR,
self::SIDEBAR_AFTER,
self::FOOTER_BEFORE,
self::FOOTER_AFTER,
];
}
public static function event(string $slot): string
{
return 'theme.'.$slot;
}
public static function render(string $slot): string
{
return Hook::gather(self::event($slot), '');
}
/**
* Soft contract for theme authors & admin UI.
* Sizes are recommendations only — the active theme's CSS wins.
*
* @return array<string, array{label: string, place: string, size: string, multi: bool}>
*/
public static function catalog(): array
{
$catalog = [];
foreach (self::all() as $slot) {
$catalog[$slot] = [
'label' => __('admin.slots.'.$slot.'.label'),
'place' => __('admin.slots.'.$slot.'.place'),
'size' => __('admin.slots.'.$slot.'.size'),
'multi' => true,
];
}
return $catalog;
}
public static function hint(string $slot): string
{
$meta = self::catalog()[$slot] ?? null;
if ($meta === null) {
return __('admin.slots.custom', ['slot' => $slot]);
}
return __('admin.slots.hint', [
'place' => $meta['place'],
'size' => $meta['size'],
'slot' => $slot,
]);
}
}