跳转到内容
TubePress — 免费、自托管 & 持续维护
外观与主题

主题开发

打造你自己的主题:目录结构、theme.json、functions.php、模板与辅助函数。

TubePress 主题是一个包含 PHP 模板及可选资源和辅助函数的文件夹。当 外观 和主题编辑器不够用、您希望完全掌控标记时,可使用自定义主题。本页面是构建指南;请将 主题 API 参考 保持在旁边,以查阅变量和辅助函数的完整列表。

贯穿始终的黄金法则:读取 TubePress 注入的设置,而不是硬编码。如果您遵循以 $_ 为前缀的变量,您的主题将完全可从管理后台进行配置,就像内置的 Simply 主题一样。

主题结构

主题存放在 themes/{slug}/ 下。只有 theme.jsontemplates/layout.php 是严格必需的 — 其余所有内容都是可选的,并会回退到 Simply。

themes/aurora/
├── theme.json            Required — metadata
├── functions.php         Enqueue assets, helper functions
├── assets/
│   ├── css/style.css
│   └── js/app.js
└── templates/
    ├── layout.php        Required — the HTML shell
    ├── home.php          Homepage
    ├── video.php         Watch page
    ├── category.php      …tag/performer/channel (+ plurals)
    ├── search.php        Search results
    ├── page.php          Static page
    ├── favorites.php     User favourites
    ├── history.php       Watch history
    ├── 404.php           Not found
    ├── auth/             login, register, profile
    └── partials/
        └── video-card.php  Reusable card partial

theme.json

此清单文件是必需的。它包含主题的元数据、可选的默认颜色集以及任意 settingsnameversionauthor 会显示在 /admin/themes 中。

{
    "name": "Aurora",
    "description": "A custom theme for TubePress",
    "version": "1.0.0",
    "author": "Your Name",
    "screenshot": "screenshot.png",
    "colors": {
        "primary": "#2563eb",
        "secondary": "#7c3aed",
        "background": "#ffffff",
        "text": "#1e293b"
    },
    "settings": {
        "videos_per_row": 4
    }
}

functions.php

此文件在启动时自动加载。使用它来注册样式表和脚本,并定义模板调用的辅助函数。使用 filemtime() 查询字符串注册资源,以确保浏览器始终获取最新编辑;第二个参数是加载优先级(数值越小越先加载)。

<?php
declare(strict_types=1);

// filemtime() busts the cache on every edit.
$cssVer = @filemtime(ThemeManager::themePath()
    . '/assets/css/style.css') ?: time();
$jsVer  = @filemtime(ThemeManager::themePath()
    . '/assets/js/app.js') ?: time();

ThemeRenderer::enqueueCSS(
    ThemeManager::assetUrl('css/style.css') . '?v=' . $cssVer, 1);
ThemeRenderer::enqueueJS(
    ThemeManager::assetUrl('js/app.js') . '?v=' . $jsVer, 1);

// A reusable video-card helper, called from listing templates.
function auroraVideoCard(array $video): string
{
    // Record an impression so the CTR system can rank this card.
    ImpressionTracker::collect((int) $video['id']);

    // Let a plugin replace the card entirely if it wants to.
    $card = HookSystem::applyFilter('video.card.html', '', $video);
    if ($card !== '') {
        return $card;
    }

    ob_start();
    require ThemeManager::templatePath('partials/video-card');
    return ob_get_clean();
}

Simply 正是定义了这类辅助函数——simplyVideoCard()——以及 simplyPagination()simplySortTabs()ImpressionTracker::collect() 调用正是为 CTR 排名 提供数据;批量写入会在 layout.php 中稍后刷新。

优先为卡片使用局部模板。 通过 ThemeManager::templatePath() 和输出缓冲渲染 partials/video-card.php,如上所示。这样可以将标记集中在一处,并允许插件通过 video.card.html 过滤器覆盖它。

模板与渲染流程

控制器将数据传递给 ThemeRenderer::render($template, $data),然后渲染器接管后续工作。了解执行顺序有助于您知晓各处可用的内容。

  1. 控制器渲染。 例如 ThemeRenderer::render('home', ['videos' => $videos])
  2. 注入全局变量。$_ 为前缀的站点、外观、区域设置及卡片/观看变量被添加进来。
  3. 插件调整数据。 theme.template_data 过滤器运行,接收参数 ($data, $templateName)
  4. 您的模板进行缓冲。 模板文件被捕获到 $content 中。
  5. 布局加载。 layout.php 接收 $content 及所有变量,并输出完整的 HTML 框架。
  6. 印象数据刷新。 ImpressionTracker::flush()</body> 之前写入批量 CTR 更新。
  7. Cron 运行。 CronManager::run() 执行所有到期的计划任务。

您的 layout.php 负责框架:在 <head> 中包含 ThemeRenderer::renderCSS()$_colorOverrides,输出 $content,然后在 </body> 之前调用 ThemeRenderer::renderJS()ImpressionTracker::flush()主题 API 列出了完整的八项检查清单。

全局变量与辅助函数

每个模板都接收全局 $_ 变量及其自身数据。主题 API 参考 记录了所有内容;以下是最常用的变量。

最常用的变量用途
$_siteName, $_siteUrl, $_user站点标识和已登录用户(或 null)。
$_videosPerRow列表页的网格列数(4、5 或 6)。
$_colorOverrides<head> 中颜色自定义属性的 <style> 块。
$_card*, $_watch*在外观中设置的卡片和观看页开关。
$_menuItems, $_menuSearch导航项目和搜索栏开关。
关键辅助函数用途
ThemeRenderer::enqueueCSS/::enqueueJS::partial::renderCSS/::renderJS
ThemeManager::assetUrl::themePath::templatePath::active
Format::number::duration::timeAgo,用于格式化显示。
Router / url()URL,以及用于表单的 ::csrfField()
Setting__()读取设置;翻译键值。

模板回退

如果当前主题缺少某个模板,TubePress 将改用 Simply 的版本。这意味着您只需覆盖想要更改的部分:从复制单个模板开始——例如 home.php——放入您的主题中,其余内容继续从 Simply 继承,直到您准备好接管为止。一个主题可以只有一个文件,也可以有五十个。

主题钩子

除模板之外,少量钩子点允许您(和插件)在不派生的情况下扩展页面。动作(Action)是即触即忘的;过滤器(Filter)转换您返回的值。

钩子类型用途
head.meta动作<head> 内输出标签(meta、JSON-LD、验证标签)。
footer.scripts动作</body> 之前输出标记。
video.card.html过滤器替换卡片的 HTML。参数为 ($html, $video);返回非空字符串以覆盖默认值。
// An action — fire and forget, inside <head>.
HookSystem::doAction('head.meta');

// A filter — return '' to keep the default card.
HookSystem::addFilter('video.card.html',
    function (string $html, array $video): string {
        return $html;
    });

还有两个过滤器值得了解:theme.template_data 用于在渲染前调整数据数组,head.css 用于追加 <style> 字符串——Simply 使用后者将其网格间距和圆角以 CSS 变量的形式发布。有关更广泛的动作/过滤器目录,请参阅 钩子与插件

后续步骤

还有疑问?

从您的控制面板提交工单,我们的团队将为您提供帮助。

体验在线演示 → 下载 TubePress →