- Creada estructura shared/ con Domain, Application, Infrastructure - Documentación completa de arquitectura (5 READMEs, ~6150 líneas) - Archivos .gitkeep para preservar estructura en Git - Contextos admin/ y public/ documentados Estructura shared/: - Domain/ (ValueObjects, Exceptions, Contracts) - Application/ (Contracts, Services) - Infrastructure/ (Services, Traits) Documentación incluye: - Principios de Clean Architecture - Reglas de dependencia - Ejemplos de código - Guías de testing - Mejores prácticas Preparación completa para implementación en Fase-1.
Contexto Public - Renderizado Frontend de Componentes
Propósito
El contexto public/ contiene todo el código relacionado con el renderizado de componentes en el frontend.
Cada componente tiene su propia carpeta con su Clean Architecture completa.
Filosofía: Context-First Architecture
Similar a admin/, el contexto public/ agrupa todo lo relacionado con la visualización pública de componentes.
Cada componente es independiente y tiene sus propias capas de Clean Architecture.
Estructura (Fase-00)
En Fase-00 solo creamos la estructura base. Los componentes se crearán en fases posteriores:
public/
├── README.md (este archivo)
└── .gitkeep (preserva directorio en Git)
Estructura Futura (Post Fase-00)
public/
├── Navbar/ # Componente Navbar
│ ├── Domain/
│ │ ├── NavbarData.php # Entidad de lectura
│ │ └── NavbarDataProviderInterface.php
│ ├── Application/
│ │ ├── GetNavbarDataUseCase.php # Caso de uso
│ │ └── DTO/
│ │ └── NavbarDataDTO.php
│ ├── Infrastructure/
│ │ ├── Persistence/
│ │ │ └── WordPressNavbarDataProvider.php
│ │ ├── UI/
│ │ │ ├── NavbarRenderer.php # Renderizador
│ │ │ ├── views/
│ │ │ │ └── navbar.php # Template
│ │ │ └── assets/
│ │ │ ├── css/
│ │ │ │ └── navbar.css
│ │ │ └── js/
│ │ │ └── navbar.js
│ │ └── Hooks/
│ │ └── NavbarHooks.php # WordPress hooks
│ └── README.md
├── Footer/ # Otro componente
│ └── (misma estructura)
└── (más componentes...)
Principios del Contexto Public
- Solo lectura: El frontend solo lee configuraciones, no las modifica
- Performance: Optimizado para carga rápida y caché
- Presentación: Se enfoca en renderizar HTML, CSS, JS
- Independencia: Cada componente es autónomo
Responsabilidades
El contexto public/ se encarga de:
✅ Renderizado de componentes en el frontend
✅ Lectura de configuraciones de la base de datos
✅ Generación de HTML según templates
✅ Carga de assets (CSS, JS) del componente
✅ Enqueue de scripts y estilos
✅ Hooks de WordPress para frontend (wp_head, wp_footer, etc.)
❌ NO se encarga de:
- Administración de componentes (va en
admin/) - Guardado de configuraciones
- Lógica compartida (va en
shared/)
Ejemplo de Flujo de Public
1. Usuario visita página web
Usuario (navegador)
↓
WordPress carga tema
↓
NavbarHooks.php (registra hook 'wp_body_open')
↓
Hook ejecutado
↓
NavbarRenderer.php (obtiene datos y renderiza)
↓
GetNavbarDataUseCase.php (obtiene configuración)
↓
WordPressNavbarDataProvider.php (lee de DB)
↓
navbar.php (template con HTML)
↓
HTML enviado al navegador
2. Código de ejemplo
// public/Navbar/Application/GetNavbarDataUseCase.php
namespace ROITheme\Public\Navbar\Application;
use ROITheme\Public\Navbar\Domain\NavbarDataProviderInterface;
final class GetNavbarDataUseCase
{
public function __construct(
private readonly NavbarDataProviderInterface $dataProvider
) {}
public function execute(): array
{
$data = $this->dataProvider->get();
// Transformar datos si es necesario
return [
'logo_url' => $data['logo_url'] ?? '',
'menu_items' => $data['menu_items'] ?? [],
'sticky' => $data['sticky'] ?? false,
];
}
}
// public/Navbar/Infrastructure/UI/NavbarRenderer.php
namespace ROITheme\Public\Navbar\Infrastructure\UI;
use ROITheme\Public\Navbar\Application\GetNavbarDataUseCase;
final class NavbarRenderer
{
public function __construct(
private readonly GetNavbarDataUseCase $getNavbarData
) {}
public function render(): void
{
$data = $this->getNavbarData->execute();
// Encolar assets
wp_enqueue_style(
'roi-navbar',
get_template_directory_uri() . '/public/Navbar/Infrastructure/UI/assets/css/navbar.css',
[],
'1.0.0'
);
wp_enqueue_script(
'roi-navbar',
get_template_directory_uri() . '/public/Navbar/Infrastructure/UI/assets/js/navbar.js',
['jquery'],
'1.0.0',
true
);
// Renderizar template
require __DIR__ . '/views/navbar.php';
}
}
// public/Navbar/Infrastructure/Hooks/NavbarHooks.php
namespace ROITheme\Public\Navbar\Infrastructure\Hooks;
use ROITheme\Public\Navbar\Infrastructure\UI\NavbarRenderer;
final class NavbarHooks
{
public function __construct(
private readonly NavbarRenderer $renderer
) {}
public function register(): void
{
add_action('wp_body_open', [$this->renderer, 'render']);
}
}
// public/Navbar/Infrastructure/UI/views/navbar.php
<?php
/**
* Template del Navbar
*
* @var array $data Datos del navbar
*/
?>
<nav class="roi-navbar <?= $data['sticky'] ? 'sticky' : '' ?>">
<div class="container">
<a href="<?= home_url() ?>">
<img src="<?= esc_url($data['logo_url']) ?>" alt="Logo">
</a>
<ul class="menu">
<?php foreach ($data['menu_items'] as $item): ?>
<li>
<a href="<?= esc_url($item['url']) ?>">
<?= esc_html($item['label']) ?>
</a>
</li>
<?php endforeach; ?>
</ul>
</div>
</nav>
Relación con Otros Contextos
admin/ → Guarda configuraciones
↓
Base de Datos → Almacena settings
↓ lee
public/ → Renderiza componentes
↓
Navegador del Usuario
Clave: public/ solo LECTURA, nunca escritura.
Optimización y Caché
1. Usar Transients de WordPress
public function get(): array
{
$cached = get_transient('roi_navbar_data');
if ($cached !== false) {
return $cached;
}
$data = $this->fetchFromDatabase();
set_transient('roi_navbar_data', $data, HOUR_IN_SECONDS);
return $data;
}
2. Conditional Asset Loading
if ($data['sticky']) {
wp_enqueue_script('roi-navbar-sticky');
}
3. Lazy Loading de Componentes
add_action('wp_body_open', function() {
if (is_front_page()) {
// Solo cargar en homepage
$renderer->render();
}
});
Reglas de Dependencia
✅ PUEDE depender de:
shared/Domain/(Value Objects, Exceptions)shared/Application/(Contracts, Services)shared/Infrastructure/(Implementaciones de servicios)- WordPress frontend functions (
wp_enqueue_style,wp_head, etc.)
❌ NO PUEDE depender de:
admin/(contexto independiente)- Funciones de administración de WordPress
Testing
Tests Unitarios
// tests/Unit/Public/Navbar/Application/GetNavbarDataUseCaseTest.php
public function test_returns_navbar_data()
{
$dataProvider = $this->createMock(NavbarDataProviderInterface::class);
$dataProvider->method('get')->willReturn(['logo_url' => 'test.png']);
$useCase = new GetNavbarDataUseCase($dataProvider);
$data = $useCase->execute();
$this->assertEquals('test.png', $data['logo_url']);
}
Tests de Integración
// tests/Integration/Public/Navbar/Infrastructure/WordPressNavbarDataProviderTest.php
public function test_retrieves_navbar_settings_from_db()
{
update_option('roi_navbar_settings', ['logo_url' => 'test.png']);
$provider = new WordPressNavbarDataProvider();
$data = $provider->get();
$this->assertEquals('test.png', $data['logo_url']);
}
Tests E2E (Playwright)
// tests/E2E/Public/NavbarRenderingTest.php
public function test_navbar_renders_on_homepage()
{
$this->visit('/');
$this->see('.roi-navbar');
$this->see('Logo');
}
Tests de Performance
// tests/Performance/Public/NavbarPerformanceTest.php
public function test_navbar_renders_in_less_than_100ms()
{
$start = microtime(true);
$renderer = new NavbarRenderer($this->getNavbarDataUseCase);
ob_start();
$renderer->render();
ob_end_clean();
$duration = (microtime(true) - $start) * 1000;
$this->assertLessThan(100, $duration);
}
Cuándo Agregar Código Aquí
Agrega código a public/ cuando:
- Renderizas un componente en el frontend
- Necesitas mostrar datos al usuario final
- Cargas assets (CSS, JS) para el frontend
- Registras hooks de frontend (
wp_head,wp_footer, etc.) - Optimizas performance de renderizado
No agregues aquí:
- Formularios de admin (van en
admin/) - Guardado de configuraciones
- Lógica compartida (va en
shared/)
Assets y Performance
Organización de Assets
public/Navbar/Infrastructure/UI/assets/
├── css/
│ ├── navbar.css # Estilos del componente
│ └── navbar.min.css # Versión minificada
├── js/
│ ├── navbar.js # JavaScript del componente
│ └── navbar.min.js # Versión minificada
└── images/
└── default-logo.png # Imágenes del componente
Minificación y Concatenación
En producción, usar versiones minificadas:
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
wp_enqueue_style('roi-navbar', "...navbar{$suffix}.css");
Estado Actual (Fase-00)
En Fase-00, public/ solo tiene la estructura base. Los componentes se crearán en las siguientes fases:
- Fase-1: Estructura base e infraestructura
- Fase-2: Migración de base de datos
- Fase-3: Implementación de componentes públicos
- Fase-4+: Componentes adicionales y optimización
Próximos Pasos
- Crear primer componente en Fase-3 (ej: Navbar)
- Implementar Domain layer (entidades de lectura)
- Implementar Application layer (casos de uso de lectura)
- Implementar Infrastructure layer (renderizado, hooks)
- Crear templates y assets
- Optimizar con caché
- Crear tests de performance
- Repetir para cada componente