Hazlo tuyo
Dónde va tu producto para que una actualización de la base nunca lo pelee.
Vas a seguir mergeando versiones nuevas de Weblabor Base a tu proyecto mientras éste viva. Cada archivo que editan los dos es un conflicto que resuelves otra vez en cada merge, así que la base se queda con lo compartido y te da carpetas propias para lo tuyo. Esta guía dice cuáles son esas carpetas, qué va en cada una y cómo traer la siguiente versión de la base sin perder una línea de tu producto.
La regla detrás de todo: lo que es de tu producto vive en una carpeta con el nombre de tu producto. Un archivo que la base trae es un archivo que la base va a cambiar.
Nombra tu proyecto una vez
config/app.php tiene una clave project:
'project' => 'weblabor-base',
Cámbiala a un slug corto de tu producto, tu-proyecto en el resto de esta guía. Es un literal committeado, no una variable de entorno, a propósito: se define una vez, cuando arranca tu proyecto, y config/ es tuyo, así que sobrevive cada merge.
La aplicación lee tres lugares a partir de ese nombre:
| Qué | Ruta |
|---|---|
| Landing y páginas de características | resources/views/landing/tu-proyecto/ |
| Guías y changelog del centro de ayuda | docs/tu-proyecto/help/ |
| Componentes de diseño y layouts | resources/views/components/tu-proyecto/ |
Nada de las carpetas propias de la base se hereda. landing/weblabor-base/, docs/weblabor-base/ y resources/views/components/weblabor-base/ se quedan en el repositorio intactas y sin usarse, así que un merge que las cambie no cambia nada de lo que publicas.
Lo que una carpeta tuya no cubre sale de una carpeta genérica llamada project, escrita para cualquier producto. La regla es la misma para cada una: tu carpeta si existe, y project si no existe. El centro de ayuda lee docs/project/help/ mientras no exista docs/tu-proyecto/help/, lo que le da a un producto nuevo guías escritas para sus usuarios, como editar el perfil o cambiar de plan. En cuanto creas tu propia carpeta de ayuda, solo se leen las tuyas: copia a ella las guías genéricas que quieras conservar, como explica /help/write-guides-and-changelog. Los componentes de diseño funcionan igual, componente por componente, como explica «Tu aspecto» más abajo.
Tu página de inicio
La página de inicio en / renderiza resources/views/landing/tu-proyecto/home.blade.php dentro del layout público. Mientras no exista resources/views/landing/tu-proyecto/, la landing sigue la misma regla que lo demás: la página de inicio es la genérica de resources/views/landing/project/, con el nombre de tu aplicación, una frase neutra y los botones para entrar y registrarse, y /features muestra su estado vacío. En cuanto creas tu carpeta, necesita su propio home.blade.php: sin él, la página de inicio responde con un error que nombra el archivo que hay que crear. La página de inicio de la base está en resources/views/landing/weblabor-base/home.blade.php; cópiala como punto de partida y luego reescríbela.
resources/views/landing/tu-proyecto/identity.php es opcional y dice quién está detrás del producto, para el encabezado y el pie:
return [
'logo' => 'images/landing/tu-proyecto/logo.png',
'contact' => 'https://wa.me/5215550000000',
'about' => '#about',
];
logo es tu logo con su nombre, una ruta bajo public/, para el pie; sin él, el pie imprime el nombre de tu aplicación. El encabezado no lee este archivo: muestra el logo de tu marca, el logo de resources/brand/tu-proyecto.php o de config/app.php (su icon cuando no hay logo), completo y del mismo tamaño en cada pantalla. En un teléfono ocupa la primera fila y el botón del menú, el selector de idioma y los botones de acceder y registrarse pasan a una segunda, así que nada tiene que achicarse; solo un producto sin ninguna de las dos imágenes muestra ahí su nombre. contact es a dónde lleva el enlace Contacto del pie; sin él, el pie no muestra Contacto, porque no hay a dónde mandarlo. about es a dónde lleva el enlace Acerca de del pie, con la misma regla: sin él no hay Acerca de. Una sección de tu página de inicio, como #about, se alcanza desde cualquier página pública, no solo desde la de inicio; una dirección completa se sigue tal cual. Lee cualquiera de los dos en tus propias vistas con App\Classes\Landing::identity('contact').
resources/views/landing/tu-proyecto/demo.blade.php también es opcional: cuando existe se sirve en /demo, pública, como la página que invita a registrarse y probar el producto; sin ella, /demo no se encuentra. Enlázala desde tu nav-links.
El menú público muestra Ayuda, precedida de Características en cuanto features.php lista al menos una página (antes llevaría a una página vacía), y después lo que imprima resources/views/landing/tu-proyecto/nav-links.blade.php. El archivo es opcional. Pon ahí las anclas y páginas que tu landing sí tiene, para que el menú nunca apunte a una sección que no existe. El encabezado imprime el archivo dos veces, en su barra y en el menú que su botón abre en el celular, así que escribe solo los enlaces, sin maquetación alrededor; las condiciones que lleven valen en los dos:
<a class="text-default-500 hover:text-default-900 transition-colors" href="#about">
{{ __('About') }}
</a>
Las imágenes de la landing van en public/images/landing/tu-proyecto/. El encabezado y el pie son los componentes de diseño public-header y public-footer: para cambiarlos, agrega tu propia versión a tu carpeta de diseño, como explica "Tu aspecto" más abajo, en lugar de copiar el marco layouts/web.blade.php.
Tus páginas de características
/features lista lo que vende tu producto, una página por característica. La lista es resources/views/landing/tu-proyecto/features.php, un arreglo de entradas:
return [
[
'slug' => 'your-account',
'title' => 'Your account',
'summary' => 'Keep your details and your preferences the way you want them.',
'icon' => 'user-circle',
'image' => 'images/landing/tu-proyecto/features/your-account/profile.png',
'order' => 20,
],
];
Cada entrada es una declaración: su página es la vista Blade con el nombre de su slug, resources/views/landing/tu-proyecto/features/your-account.blade.php, y una entrada cuya vista nunca se escribió queda fuera del listado. Las páginas se construyen con tres componentes, <x-design::landing-hero>, <x-design::landing-block> y <x-design::landing-cta>, y sus capturas viven en public/images/landing/tu-proyecto/features/{slug}/.
Escríbelas como páginas de venta, no como documentación: empieza por lo que la persona obtiene, una o dos frases cada una, en segunda persona y en presente. Las claves del manifiesto, los componentes y sus atributos están en Escribe guías y el changelog.
Tus guías y tu changelog
El centro de ayuda en /help lee Markdown de tu propia carpeta:
docs/tu-proyecto/help/
├── guides/
│ ├── get-it-running.md
│ └── es/
│ └── get-it-running.md
└── changelog/
├── 2026-09.md
└── es/
└── 2026-09.md
Una guía es un archivo por slug, en inglés, con un front matter de title, summary, category y order. Su traducción es el mismo nombre de archivo dentro de una carpeta con el nombre del idioma, una carpeta por cada idioma de config/app.php que no sea inglés. Una guía sin traducción no existe en ese idioma: queda fuera de sus listas y su dirección responde 404, así que tradúcela antes de publicarla. El changelog es un archivo por mes.
Las categorías que una guía puede declarar están en config/help.php, con sus etiquetas en inglés. Una categoría que ninguna guía usa se oculta, así que reemplaza la lista con las categorías que tu lector necesita y nada se muestra vacío.
Las traducciones llevan una huella del inglés con el que se escribieron, para poder nombrar una guía cuyo inglés siguió adelante. Dos comandos la mantienen:
php artisan help:stamp --check # lista traducciones faltantes, desactualizadas y huérfanas
php artisan help:stamp # reescribe la huella en cada traducción
composer install apunta Git a scripts/git-hooks, cuyo hook pre-push corre la revisión sobre los documentos de ayuda que el push cambia, tal como quedan en sus commits, y detiene un push que publicaría uno desactualizado. Un documento que ya venía roto en la rama no lo frena, y lo que no está en un commit no cuenta. Sáltalo una vez con git push --no-verify. Los formatos de archivo, las entradas del changelog y cómo se renderizan las páginas están en Escribe guías y el changelog.
Tu brief
Tu brief dice qué es tu producto, qué promete, a quién le habla, el tono y qué nunca afirma. No se renderiza en ningún lado: es lo que mantiene consistentes el copy de la landing, las páginas de características y las guías cuando las escriben varias personas. Escríbelo antes del copy, no después.
Es un documento de trabajo, así que no vive en el repositorio. Vive en tu proyecto en el toolkit Weblabor, como identity/product.md, junto a tu manual de identidad, y se escribe y se lee con las herramientas de documentos del toolkit. Ahí lo busca y lo usa /design-catalog. El brief de la base es identity/product.md del proyecto weblabor-base en el toolkit y es una buena plantilla.
Tu aspecto
Cada pantalla toma su marco y sus piezas repetidas de componentes de diseño, que se llaman con un nombre neutro: <x-design::page-header>, <x-design::surface>, <x-design::auth-page> y los demás. El nombre nunca dice a qué producto pertenece. Se busca por capas: primero en resources/views/components/tu-proyecto/, luego en resources/views/components/project/, que guarda el aspecto genérico con el que empieza todo producto. Gana la primera carpeta que tiene el componente.
Así que cambias el aspecto agregando archivos, no editando los genéricos. Copia un componente de resources/views/components/project/ a tu carpeta con el mismo nombre de archivo, conserva sus atributos y sus slots, y cambia su marcado. Cada pantalla que lo llama lo sigue, incluidas las de acceso, el área con sesión, los layouts y las páginas de facturación. Un componente que nunca copias conserva el aspecto genérico.
Las pantallas de registros del admin, el listado, el detalle y los formularios de crear y editar que Laravel Front dibuja para cada recurso, también siguen tu capa. La base reemplaza las vistas del paquete con copias en resources/views/vendor/front/ que llaman componentes de diseño como page-header, panel, action-button y dialog, así que un componente que redefines llega a esas pantallas sin tocar las copias. No edites las copias: cambia el componente.
El resto de las pantallas también la siguen: el administrador de archivos, las campanas de notificaciones y anuncios y el menú de la cuenta, el perfil, la suscripción, los planes y los complementos, el campo de subida de archivos, el chat de soporte, el espacio de datos, los enlaces de página de cada lista y las tarjetas del admin. Solo las plantillas de correo, el sitemap, la pantalla sin conexión y la pantalla de diseño del admin siguen dibujados a mano.
Los layouts siguen la misma regla. Los cinco marcos, layouts/base, layouts/app, layouts/web, layouts/auth y layouts/help, los menús laterales de layouts/sidebars/ y los parciales de layouts/partials/ se buscan en una carpeta layouts/ dentro de cada carpeta de diseño: primero resources/views/components/tu-proyecto/layouts/, luego resources/views/components/project/layouts/, que guarda los genéricos. Copia a tu carpeta, con la misma ruta, solo los layouts que cambias; los demás siguen saliendo de la carpeta genérica. Cada pantalla los sigue llamando con el mismo nombre, como layouts.app o layouts.sidebars.admin, así que nada de lo que los usa cambia.
El marco con sesión elige su menú lateral por el primer segmento de la dirección: layouts/sidebars/admin.blade.php bajo /admin, layouts/sidebars/account.blade.php bajo /account. Para cambiar el menú de una sección, copia solo ese menú. Para darle menú a una sección tuya, agrega uno con su nombre, como layouts/sidebars/reports.blade.php para /reports; una sección para la que ninguna carpeta tiene menú no muestra ninguno. Un marco o un parcial que ninguna carpeta tiene falla con un error que lo nombra.
Weblabor Base también tiene su propia carpeta, resources/views/components/weblabor-base/, donde la base redefine un componente solo para sí misma: su encabezado y pie públicos, las piezas de su landing y los enlaces de su encabezado. Tu proyecto no la lee, así que la base puede cambiar su propio aspecto sin cambiar el tuyo. Cada componente que llaman las páginas propias de la base existe también en resources/views/components/project/, así que php artisan view:cache compila esas páginas en tu proyecto aunque nunca las muestre.
Un producto construido sobre otro producto, como uno construido sobre Weblabor Teams, lista la cadena completa en config/app.php:
'design_layers' => ['tu-proyecto', 'weblabor-teams'],
Vacía, la cadena es tu proyecto y luego project. Un producto que quiere el aspecto de Weblabor Base lista weblabor-base en la cadena. project siempre se busca al final. Un componente que ninguna capa tiene falla con un error que lo nombra, en lugar de no dibujar nada.
Tu paleta y tu fuente siguen la misma regla: resources/css/themes/tu-proyecto.css cuando existe, buscado por la misma cadena, y el genérico resources/css/themes/project.css cuando no. Los demás tokens, los colores de éxito, error, advertencia e información, siguen en resources/css/app.css, compartido por todos los productos, como explica Marca e interfaz. Un superadministrador ve cada componente de diseño en uso, en cada uno de sus estados, y de qué capa viene cada uno, en /admin/design.
Qué más es tuyo
config/ pertenece al proyecto derivado. Ahí defines los superadministradores, el logotipo y el icono, los idiomas, las banderas, las categorías de ayuda y el manifiesto de la PWA, y un merge de la base nunca necesita sobrescribirlos. Cuando la base agrega una clave nueva a un archivo de configuración la verás como un conflicto en ese archivo: conserva tus valores y toma la clave nueva.
Los archivos detrás de la marca, public/images/logo.svg, public/images/icon.svg y la carpeta generada public/images/icons/, son tuyos para reemplazarlos. .env nunca se committea. Tus migraciones, modelos, componentes Livewire y vistas son archivos nuevos que se mergean limpio mientras agregues en lugar de editar.
Dos cosas son compartidas y vale la pena saberlo. lang/en.json y lang/es.json guardan juntas todas las cadenas en pantalla de la base y de tu producto, así que los dos lados agregan líneas en cada merge; cuando entren en conflicto, conserva ambos lados. Y los layouts genéricos de resources/views/components/project/layouts/ son compartidos: cambia un layout copiándolo a resources/views/components/tu-proyecto/layouts/, como explica "Tu aspecto", nunca editando el genérico.
Si tu producto editó los layouts cuando todavía vivían en resources/views/layouts/, mueve tus versiones una sola vez a resources/views/components/tu-proyecto/layouts/, con la misma ruta. El merge que trae el cambio da conflicto en esos archivos esa única vez; después, los cambios de la base en sus layouts se mergean sin tocar los tuyos.
Sigue mergeando la base
Tu repositorio empieza como una copia de Weblabor Base. Agrega la base como segundo remoto y mergea su rama principal cada vez que salga una versión que quieras:
git remote add upstream https://gitlab.weblabor.mx/weblabormx/proyectos-internos/sistemas-base/weblabor-base.git
git fetch upstream
git merge upstream/master
Después del merge, actualiza lo que una versión cambia:
composer install
npm ci && npm run build
php artisan migrate
php artisan db:seed
Los seeders son seguros de volver a correr: crean lo que falta y vuelven a sincronizar el rol de administrador con todos los permisos, y nunca sobrescriben una contraseña.
Conflictos que debes esperar, y cómo cerrarlos:
| Archivo | Por qué entra en conflicto | Resolución |
|---|---|---|
config/*.php |
La base agregó o renombró una clave | Conserva tus valores, toma la clave nueva |
lang/*.json |
Los dos lados agregaron cadenas | Conserva ambos lados |
composer.lock, package-lock.json |
Los dos lados cambiaron dependencias | Toma el archivo de la base, corre la instalación y vuelve a hacer composer require de tus propios paquetes |
resources/views/layouts/* |
Editaste un layout antes de que los layouts pasaran a las carpetas de diseño | Una sola vez: mueve tu versión a resources/views/components/tu-proyecto/layouts/ con la misma ruta, y acepta que la base lo borró |
Todo lo que está en resources/views/landing/tu-proyecto/, resources/views/components/tu-proyecto/, docs/tu-proyecto/ y config/ nunca entra en conflicto, porque la base no lo toca. Mientras más de tu producto viva ahí, más corto es cada merge.