106 lines
3.6 KiB
PHP
106 lines
3.6 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Author: ywxapp <admin@ywxapp.cn>
|
||
// +----------------------------------------------------------------------
|
||
|
||
namespace ywxapp\library;
|
||
|
||
/**
|
||
* 皮肤变量/配色层(Discuz 式风格变量,无需改 HTML)。
|
||
*
|
||
* 模板在 template.json 声明 variables(如主色/背景/字体),后台可覆盖并写入
|
||
* config/template.php 的 settings.variables[<模板名>]。渲染时由 Addon 基类的
|
||
* fetch 钩子把变量注入为 <style id="ywx-skin-vars">:root{--primary:...}</style>,
|
||
* 皮肤 CSS 用 var(--primary) 即可生效,无需改动任何视图文件。
|
||
*/
|
||
class SkinVariables
|
||
{
|
||
/**
|
||
* 读取模板声明的变量定义(已归一化为 {key:{label,default,type}})。
|
||
* 支持简写:variables: { "primary": "#2d8cf0" } 等价于 { "primary": {"default":"#2d8cf0"} }。
|
||
*/
|
||
public static function definitions(string $name): array
|
||
{
|
||
$file = root_path() . 'templates' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'template.json';
|
||
if (! is_file($file)) {
|
||
return [];
|
||
}
|
||
$meta = json_decode(file_get_contents($file), true) ?? [];
|
||
$vars = $meta['variables'] ?? [];
|
||
if (! is_array($vars)) {
|
||
return [];
|
||
}
|
||
$out = [];
|
||
foreach ($vars as $key => $def) {
|
||
if (is_string($def)) {
|
||
$def = ['default' => $def];
|
||
}
|
||
if (! is_array($def)) {
|
||
continue;
|
||
}
|
||
$out[$key] = [
|
||
'label' => $def['label'] ?? $key,
|
||
'default' => $def['default'] ?? '',
|
||
'type' => $def['type'] ?? 'color',
|
||
];
|
||
}
|
||
return $out;
|
||
}
|
||
|
||
/**
|
||
* 当前生效的变量值(默认 + 后台覆盖)。
|
||
* 返回带 -- 前缀的 CSS 变量名 => 值(仅返回非空值)。
|
||
*/
|
||
public static function values(string $name): array
|
||
{
|
||
$defs = self::definitions($name);
|
||
$settings = TemplateManager::getSettings();
|
||
$overrides = $settings['variables'][$name] ?? [];
|
||
if (! is_array($overrides)) {
|
||
$overrides = [];
|
||
}
|
||
$out = [];
|
||
foreach ($defs as $key => $d) {
|
||
$val = $overrides[$key] ?? $d['default'];
|
||
if ($val === '' || $val === null) {
|
||
continue;
|
||
}
|
||
$out['--' . ltrim($key, '-')] = (string) $val;
|
||
}
|
||
return $out;
|
||
}
|
||
|
||
/**
|
||
* 生成 :root 内的 CSS 变量声明字符串(不含 :root{} 包裹),如无变量返回空串。
|
||
*/
|
||
public static function declaration(string $name): string
|
||
{
|
||
$vals = self::values($name);
|
||
$parts = [];
|
||
foreach ($vals as $k => $v) {
|
||
$parts[] = $k . ':' . $v;
|
||
}
|
||
return implode(';', $parts);
|
||
}
|
||
|
||
/**
|
||
* 针对某插件/区域,返回可直接注入页面的 <style> 标签;无激活皮肤或无变量返回空串。
|
||
*/
|
||
public static function styleTag(string $addon, string $area): string
|
||
{
|
||
$name = SkinOverlay::templateOf($addon);
|
||
if ($name === null) {
|
||
return '';
|
||
}
|
||
$decl = self::declaration($name);
|
||
if ($decl === '') {
|
||
return '';
|
||
}
|
||
return '<style id="ywx-skin-vars">:root{' . $decl . '}</style>';
|
||
}
|
||
}
|