Desarrollo de temas
Crea tu propio tema: estructura, theme.json, functions.php, plantillas y funciones auxiliares.
Un tema de TubePress es una carpeta de plantillas PHP con activos opcionales y funciones auxiliares. Recurre a un tema personalizado cuando Apariencia y el editor de temas no son suficientes y deseas control total del marcado. Esta página es la guía de construcción; mantén la referencia de la API del tema abierta junto a ella para la lista exhaustiva de variables y helpers.
La regla de oro es: lee los ajustes que TubePress inyecta en lugar de escribirlos de forma fija. Si respetas las variables con prefijo $_, tu tema permanece completamente configurable desde el admin, exactamente como el tema incluido Simply.
Estructura del tema
Los temas viven bajo themes/{slug}/. Solo theme.json y templates/layout.php son estrictamente necesarios — todo lo demás es opcional y recae en Simply como respaldo.
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 partialtheme.json
Este manifiesto es obligatorio. Contiene los metadatos del tema, un conjunto de colores predeterminados opcional y settings arbitrarios. El name, version y author aparecen en /admin/themes.
{
"name": "Aurora",
"description": "A custom theme for TubePress",
"version": "1.0.0",
"author": "Your Name",
"screenshot": "screenshot.png",
"supports": ["subscriptions", "member_uploads", "pwa"],
"colors": {
"primary": "#2563eb",
"secondary": "#7c3aed",
"background": "#ffffff",
"text": "#1e293b"
},
"settings": {
"videos_per_row": 4
}
}Funciones opcionales: supports
Desde TubePress 1.2, un tema activa las funciones de comunidad con la lista supports. Una función activada en Configuración permanece invisible en un tema que no la declara, así que añade una opción solo cuando tus plantillas la gestionen:
| Opción | Lo que aporta tu tema |
|---|---|
subscriptions | Botones de suscripción en channel.php y video.php (lee $subscriptionsOn, $isSubscribed y $subscriberCount) y la pestaña Suscripciones de auth/profile.php. |
member_uploads | La plantilla upload.php — sin la opción, /upload responde 404 — y la pestaña Mis videos de auth/profile.php. |
pwa | Nada que construir: el núcleo añade el manifiesto, el service worker y el aviso de instalación mediante los hooks head.meta y footer.scripts. Decláralo cuando tu layout muestre las entradas Instalar la aplicación (cualquier elemento con data-pwa-install). |
Simply y Hentai Noir declaran las tres, así que sus plantillas son el mejor punto de partida. Todas las variables implicadas están en la referencia de la API de temas.
functions.php
Este archivo se carga automáticamente al inicio. Úsalo para encolar tu hoja de estilos y script, y para definir las funciones auxiliares que llaman tus plantillas. Encola los activos con una cadena de consulta filemtime() para que los navegadores siempre obtengan tu última edición; el segundo argumento es la prioridad de carga (un valor menor carga antes).
<?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 define exactamente este tipo de helper — simplyVideoCard() — junto con simplyPagination() y simplySortTabs(). La llamada a ImpressionTracker::collect() es la que alimenta el ranking CTR; la escritura en lote se vacía más tarde en layout.php.
partials/video-card.php mediante ThemeManager::templatePath() y almacenamiento en búfer de salida, como se muestra arriba. Mantiene el marcado en un solo lugar y permite que los plugins lo reemplacen a través del filtro video.card.html.Plantillas y el flujo de renderizado
Un controlador pasa datos a ThemeRenderer::render($template, $data), y el renderizador toma el control desde ahí. Entender el orden te ayuda a saber qué está disponible en cada punto.
- El controlador renderiza. p. ej.
ThemeRenderer::render('home', ['videos' => $videos]). - Se inyectan las variables globales. Se añaden las variables de sitio, apariencia, configuración regional y tarjeta/reproducción con prefijo
$_. - Los plugins ajustan los datos. Se ejecuta el filtro
theme.template_data, recibiendo($data, $templateName). - Tu plantilla se almacena en búfer. El archivo de plantilla se captura en
$content. - Se carga el layout.
layout.phprecibe$contentjunto con todas las variables y genera el shell HTML completo. - Se vacían las impresiones.
ImpressionTracker::flush()escribe la actualización de CTR en lote antes de</body>. - Se ejecuta el cron.
CronManager::run()ejecuta las tareas programadas pendientes.
Tu layout.php es responsable del shell: incluye ThemeRenderer::renderCSS() y $_colorOverrides en <head>, escribe $content, luego llama a ThemeRenderer::renderJS() e ImpressionTracker::flush() antes de </body>. La API del tema incluye la lista de verificación completa de ocho puntos.
Variables globales y helpers
Cada plantilla recibe las variables globales $_ más sus propios datos. La referencia de la API del tema las documenta todas; estas son las que usarás con más frecuencia.
| Variables más usadas | Uso |
|---|---|
$_siteName, $_siteUrl, $_user | Identidad y el usuario autenticado (o null). |
$_videosPerRow | Columnas de cuadrícula (4, 5 o 6) para tus listados. |
$_colorOverrides | El bloque <style> de propiedades personalizadas de color para <head>. |
$_card*, $_watch* | Los interruptores de tarjeta y página de reproducción configurados en Apariencia. |
$_menuItems, $_menuSearch | Elementos de navegación y el interruptor de la barra de búsqueda. |
| Helpers clave | Uso |
|---|---|
ThemeRenderer | ::enqueueCSS/::enqueueJS, ::partial, ::renderCSS/::renderJS. |
ThemeManager | ::assetUrl, ::themePath, ::templatePath, ::active. |
Format | ::number, ::duration, ::timeAgo para mostrar. |
Router / url() | URLs, más ::csrfField() para formularios. |
Setting, __() | Leer un ajuste; traducir una clave. |
Plantilla de respaldo
Si al tema activo le falta una plantilla, TubePress renderiza en su lugar la copia de Simply. Eso significa que solo reemplazas lo que quieres cambiar: empieza copiando una sola plantilla — home.php, por ejemplo — en tu tema, y deja que todo lo demás herede de Simply hasta que estés listo para tomarlo. Un tema puede ser un archivo o cincuenta.
Hooks del tema
Más allá de las plantillas, un pequeño conjunto de puntos de enganche te permite (y a los plugins) extender la página sin hacer un fork. Las acciones son de disparar y olvidar; los filtros transforman un valor que devuelves.
| Hook | Tipo | Propósito |
|---|---|---|
head.meta | Acción | Emite etiquetas dentro de <head> (meta, JSON-LD, verificación). |
footer.scripts | Acción | Emite marcado justo antes de </body>. |
video.card.html | Filtro | Reemplaza el HTML de una tarjeta. Args ($html, $video); devuelve una cadena no vacía para reemplazar. |
// 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;
});Vale la pena conocer dos filtros más: theme.template_data para ajustar el arreglo de datos antes del renderizado, y head.css para agregar una cadena <style> — Simply usa el segundo para publicar su espacio de cuadrícula y radio como variables CSS. Para el catálogo más amplio de acciones y filtros, consulta hooks y plugins.
Pasos siguientes
¿Todavía con dudas?
Abre un ticket desde tu panel y nuestro equipo te ayudará.