- 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.
394 lines
10 KiB
Markdown
394 lines
10 KiB
Markdown
# 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
|
|
|
|
1. **Solo lectura**: El frontend solo lee configuraciones, no las modifica
|
|
2. **Performance**: Optimizado para carga rápida y caché
|
|
3. **Presentación**: Se enfoca en renderizar HTML, CSS, JS
|
|
4. **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
|
|
|
|
```php
|
|
// 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,
|
|
];
|
|
}
|
|
}
|
|
```
|
|
|
|
```php
|
|
// 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';
|
|
}
|
|
}
|
|
```
|
|
|
|
```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']);
|
|
}
|
|
}
|
|
```
|
|
|
|
```php
|
|
// 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
|
|
|
|
```php
|
|
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
|
|
|
|
```php
|
|
if ($data['sticky']) {
|
|
wp_enqueue_script('roi-navbar-sticky');
|
|
}
|
|
```
|
|
|
|
### 3. Lazy Loading de Componentes
|
|
|
|
```php
|
|
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
|
|
```php
|
|
// 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
|
|
```php
|
|
// 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)
|
|
```php
|
|
// tests/E2E/Public/NavbarRenderingTest.php
|
|
public function test_navbar_renders_on_homepage()
|
|
{
|
|
$this->visit('/');
|
|
$this->see('.roi-navbar');
|
|
$this->see('Logo');
|
|
}
|
|
```
|
|
|
|
### Tests de Performance
|
|
```php
|
|
// 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:
|
|
```php
|
|
$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
|
|
|
|
1. Crear primer componente en Fase-3 (ej: Navbar)
|
|
2. Implementar Domain layer (entidades de lectura)
|
|
3. Implementar Application layer (casos de uso de lectura)
|
|
4. Implementar Infrastructure layer (renderizado, hooks)
|
|
5. Crear templates y assets
|
|
6. Optimizar con caché
|
|
7. Crear tests de performance
|
|
8. Repetir para cada componente
|