'页头( 前)', 'header' => '页头下方', 'sidebar_top' => '侧边栏顶部', 'sidebar_bottom' => '侧边栏底部', 'content_top' => '内容区顶部', 'content_bottom' => '内容区底部', 'post_content_top' => '文章正文前', 'post_content_bottom' => '文章正文后', 'footer' => '页脚前', 'body_end' => '页面末尾( 前)', ]; /** * Old SaBlog stylevar names → inject points. Unmapped HTML vars go to footer. * * @var array> */ public const STYLEVAR_POINTS = [ 'head' => ['ad_head', 'headad'], 'header' => ['headerad', 'header_ad', 'ad_header', 'topad', 'ad_top', 'sitead', 'site_ad'], 'sidebar_top' => ['sidebarad', 'sidebar_ad', 'ad_sidebar', 'leftad', 'ad_left'], 'sidebar_bottom' => ['ad_sidebar_bottom'], 'content_top' => ['indexad', 'ad_index', 'contentad', 'ad_content'], 'content_bottom' => ['ad_content_bottom'], 'post_content_top' => ['ad_post_top', 'insad'], 'post_content_bottom' => ['ad_post_bottom'], 'footer' => ['footerad', 'footer_ad', 'ad_footer', 'huangjinlian', 'huangjinlian2', 'huangjinlian3'], 'body_end' => ['ad_body_end'], ]; /** * 读取某一注入点的所有注入块(多条,已排序、已过滤停用), * 并把插件追加的 HTML 合并进来。 */ public static function blocksFor(string $point): array { $raw = Setting::get('inject.blocks', []); $raw = is_array($raw) ? $raw : (json_decode((string) $raw, true) ?: []); $blocks = collect($raw) ->filter(fn (array $b) => ($b['point'] ?? null) === $point && ($b['enabled'] ?? true)) ->sortBy(fn (array $b) => (int) ($b['sort'] ?? 0)) ->pluck('html') ->filter() ->values() ->all(); foreach (self::stylevarBlocks($point) as $html) { $blocks[] = $html; } $extra = (string) app(PluginManager::class)->applyFilters("theme.inject.{$point}", ''); if ($extra !== '') { $blocks[] = $extra; } return $blocks; } /** * 注册 View Composer:渲染前台视图前把各注入点内容 push 到对应 @stack。 */ public static function registerComposer(): void { $views = ['index', 'show', 'list', 'archives', 'tags', 'tag', 'search', 'links', 'comments', 'login', 'register', 'profile', 'membership.*', 'payments.*']; \Illuminate\Support\Facades\View::composer($views, function (\Illuminate\View\View $view) { foreach (array_keys(self::POINTS) as $point) { foreach (self::blocksFor($point) as $html) { $view->getFactory()->startPush("theme:{$point}", $html); } } }); } /** * @return list */ private static function stylevarBlocks(string $point): array { $vars = app(ThemeManager::class)->variables(); if ($vars === []) { return []; } $html = []; foreach (self::STYLEVAR_POINTS[$point] ?? [] as $key) { $value = trim((string) ($vars[$key] ?? '')); if ($value !== '') { $html[] = $value; } } if ($point !== 'footer') { return $html; } $mapped = []; foreach (self::STYLEVAR_POINTS as $keys) { foreach ($keys as $key) { $mapped[$key] = true; } } foreach ($vars as $key => $value) { $value = trim((string) $value); if ($value === '' || isset($mapped[$key]) || ! str_contains($value, '<')) { continue; } $html[] = $value; } return $html; } }