- renombrar openspec/ a _openspec/ (carpeta auxiliar) - mover specs de features a changes/ - crear specs base: arquitectura-limpia, estandares-codigo, nomenclatura - migrar _planificacion/ con design-system y roi-theme-template - agregar especificacion recaptcha anti-spam (proposal, tasks, spec) - corregir rutas y referencias en todas las specs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
688 lines
22 KiB
Markdown
688 lines
22 KiB
Markdown
# Especificacion de Nomenclatura - ROI Theme
|
|
|
|
## Purpose
|
|
|
|
Define las convenciones de nomenclatura para carpetas, archivos, clases, metodos, propiedades y variables en el tema ROI Theme (PHP 8.x / WordPress).
|
|
|
|
> **NOTA**: Para principios SOLID y estandares de codigo, ver `_openspec/specs/estandares-codigo.md`
|
|
> **NOTA**: Para arquitectura y modularidad, ver `_openspec/specs/arquitectura-limpia.md`
|
|
|
|
---
|
|
|
|
## Resumen de Nomenclaturas
|
|
|
|
| Elemento | Nomenclatura | Ejemplo |
|
|
|----------|-------------|---------|
|
|
| **Carpetas principales** | PascalCase | `Admin/`, `Public/`, `Shared/` |
|
|
| **Carpetas de contexto** | PascalCase | `Admin/`, `Public/` |
|
|
| **Carpetas de modulo** | PascalCase | `ContactForm/`, `FeaturedImage/` |
|
|
| **Carpetas de capa** | PascalCase | `Domain/`, `Application/`, `Infrastructure/` |
|
|
| **Carpetas auxiliares** | _minusculas | `_planificacion/`, `_arquitectura/` |
|
|
| **Archivos PHP de clase** | PascalCase.php | `ContactFormRenderer.php` |
|
|
| **Archivos PHP de interface** | PascalCaseInterface.php | `RendererInterface.php` |
|
|
| **Archivos JSON schema** | kebab-case.json | `contact-form.json` |
|
|
| **Namespaces** | PascalCase | `ROITheme\Public\ContactForm\Infrastructure\Ui` |
|
|
| **Clases** | PascalCase | `ContactFormRenderer` |
|
|
| **Interfaces** | PascalCase + Interface | `RendererInterface`, `CSSGeneratorInterface` |
|
|
| **Metodos** | camelCase | `render()`, `getVisibilityClass()` |
|
|
| **Propiedades** | camelCase | `$cssGenerator`, `$componentName` |
|
|
| **Variables locales** | $camelCase | `$showDesktop`, `$visibilityClass` |
|
|
| **Parametros** | $camelCase | `$component`, `$data` |
|
|
| **Campos privados** | $camelCase | `$cssGenerator` (con private) |
|
|
| **Constantes clase** | UPPER_SNAKE_CASE | `COMPONENT_NAME`, `MAX_ITEMS` |
|
|
| **Constantes globales** | UPPER_SNAKE_CASE | `ROI_THEME_VERSION` |
|
|
| **component_name** | kebab-case | `"contact-form"`, `"featured-image"` |
|
|
| **Hooks WordPress** | snake_case con prefijo | `roi_theme_after_render` |
|
|
|
|
---
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Nomenclatura de Carpetas
|
|
|
|
Los nombres de carpetas siguen convenciones basadas en su proposito.
|
|
|
|
#### Scenario: Carpetas principales del tema
|
|
- **WHEN** se nombra una carpeta principal de codigo
|
|
- **THEN** DEBE usar PascalCase
|
|
- **AND** ejemplos correctos: `Admin/`, `Public/`, `Shared/`, `Schemas/`
|
|
- **AND** ejemplos incorrectos: `admin/`, `ADMIN/`, `shared_code/`
|
|
|
|
#### Scenario: Carpetas de contexto
|
|
- **WHEN** se nombra una carpeta que representa un contexto de la aplicacion
|
|
- **THEN** DEBE usar PascalCase
|
|
- **AND** carpetas permitidas:
|
|
- `Admin/` - Componentes del panel de administracion
|
|
- `Public/` - Componentes del frontend publico
|
|
- `Shared/` - Codigo compartido entre contextos
|
|
- **AND** ejemplos incorrectos: `backend/`, `frontend/`, `common/`
|
|
|
|
#### Scenario: Carpetas de modulo (componente)
|
|
- **WHEN** se nombra una carpeta que representa un modulo/componente
|
|
- **THEN** DEBE seguir PascalCase
|
|
- **AND** DEBE coincidir con component_name convertido de kebab-case
|
|
- **AND** ejemplos correctos:
|
|
- `ContactForm/` (de `contact-form`)
|
|
- `FeaturedImage/` (de `featured-image`)
|
|
- `TopNotificationBar/` (de `top-notification-bar`)
|
|
- `CtaBoxSidebar/` (de `cta-box-sidebar`)
|
|
- **AND** ejemplos incorrectos:
|
|
- `contact-form/` (kebab-case)
|
|
- `contactForm/` (camelCase)
|
|
- `CONTACT_FORM/` (UPPER_SNAKE)
|
|
|
|
#### Scenario: Carpetas de capa (Clean Architecture)
|
|
- **WHEN** se nombra una carpeta que representa una capa de arquitectura
|
|
- **THEN** DEBE usar PascalCase
|
|
- **AND** carpetas permitidas dentro de cada modulo:
|
|
- `Domain/` - Entidades, interfaces, value objects
|
|
- `Application/` - Casos de uso
|
|
- `Infrastructure/` - Implementaciones (Ui, Api, Persistence, Services)
|
|
- **AND** subcarpetas de Infrastructure permitidas:
|
|
- `Ui/` - Renderers, FormBuilders
|
|
- `Api/` - Handlers AJAX, REST endpoints
|
|
- `Persistence/` - Repositorios
|
|
- `Services/` - Servicios de infraestructura
|
|
- `WordPress/` - Integraciones especificas de WordPress
|
|
- **AND** ejemplos correctos: `Infrastructure/Ui/`, `Infrastructure/Api/WordPress/`
|
|
- **AND** ejemplos incorrectos: `infrastructure/`, `UI/`, `api/`
|
|
|
|
#### Scenario: Carpetas auxiliares (no codigo)
|
|
- **WHEN** se nombra una carpeta de documentacion, planificacion o configuracion
|
|
- **THEN** DEBE usar prefijo guion bajo + minusculas
|
|
- **AND** ejemplos correctos:
|
|
- `_planificacion/` - Documentos de planificacion
|
|
- `_arquitectura/` - Documentos de arquitectura
|
|
- **AND** nombres compuestos usan guion medio: `_pruebas-regresion/`
|
|
- **AND** el guion bajo indica carpetas auxiliares/no-codigo
|
|
|
|
#### Scenario: Carpetas de cambios (OpenSpec)
|
|
- **WHEN** se crea una carpeta para un cambio/feature en `_openspec/changes/`
|
|
- **THEN** DEBE usar nombre en kebab-case descriptivo
|
|
- **AND** maximo 1 nivel de carpeta despues de `changes/`
|
|
- **AND** ejemplos correctos:
|
|
- `anti-spam-validator/`
|
|
- `lazy-loading-images/`
|
|
- `improved-caching/`
|
|
- **AND** ejemplos incorrectos:
|
|
- `AntiSpam/` (PascalCase)
|
|
- `anti_spam/` (snake_case)
|
|
- `anti-spam/subfolder/` (anidamiento prohibido)
|
|
|
|
#### Scenario: Excepciones permitidas
|
|
- **WHEN** existen carpetas especiales del sistema
|
|
- **THEN** se permiten las siguientes excepciones:
|
|
- `.git/` - Control de versiones
|
|
- `.serena/` - Configuracion de Serena MCP
|
|
- `.claude/` - Configuracion de Claude Code
|
|
- `node_modules/` - Dependencias npm (si aplica)
|
|
- `vendor/` - Dependencias Composer (si aplica)
|
|
- `_openspec/` - Sistema de especificaciones (carpeta auxiliar)
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Archivos PHP
|
|
|
|
Los archivos PHP DEBEN seguir convencion PascalCase.
|
|
|
|
#### Scenario: Archivos de clase
|
|
- **WHEN** se nombra un archivo que contiene una clase PHP
|
|
- **THEN** DEBE seguir PascalCase
|
|
- **AND** el nombre DEBE coincidir EXACTAMENTE con el nombre de la clase
|
|
- **AND** extension `.php`
|
|
- **AND** ejemplos correctos:
|
|
- `ContactFormRenderer.php` (contiene `class ContactFormRenderer`)
|
|
- `NewsletterAjaxHandler.php` (contiene `class NewsletterAjaxHandler`)
|
|
- `CSSGeneratorService.php` (contiene `class CSSGeneratorService`)
|
|
- **AND** ejemplos incorrectos:
|
|
- `contact-form-renderer.php` (kebab-case)
|
|
- `contactFormRenderer.php` (camelCase)
|
|
- `class_contact_form.php` (snake_case con prefijo)
|
|
|
|
#### Scenario: Archivos de interface
|
|
- **WHEN** se nombra un archivo que contiene una interface
|
|
- **THEN** DEBE seguir PascalCase con sufijo Interface
|
|
- **AND** extension `.php`
|
|
- **AND** ejemplos correctos:
|
|
- `RendererInterface.php`
|
|
- `CSSGeneratorInterface.php`
|
|
- `ComponentRepositoryInterface.php`
|
|
- **AND** ejemplos incorrectos:
|
|
- `IRenderer.php` (prefijo I estilo C#)
|
|
- `Renderer.php` (sin sufijo)
|
|
|
|
#### Scenario: Archivos de trait
|
|
- **WHEN** se nombra un archivo que contiene un trait PHP
|
|
- **THEN** DEBE seguir PascalCase con sufijo Trait
|
|
- **AND** extension `.php`
|
|
- **AND** ejemplos correctos:
|
|
- `VisibilityTrait.php`
|
|
- `CSSGeneratorTrait.php`
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Archivos JSON (Schemas)
|
|
|
|
Los schemas JSON DEBEN usar kebab-case.
|
|
|
|
#### Scenario: Archivos de schema de componente
|
|
- **WHEN** se nombra un archivo JSON schema
|
|
- **THEN** DEBE usar kebab-case
|
|
- **AND** extension `.json`
|
|
- **AND** el nombre DEBE coincidir con el component_name
|
|
- **AND** ejemplos correctos:
|
|
- `contact-form.json` (component_name: "contact-form")
|
|
- `featured-image.json` (component_name: "featured-image")
|
|
- `top-notification-bar.json` (component_name: "top-notification-bar")
|
|
- `cta-box-sidebar.json` (component_name: "cta-box-sidebar")
|
|
- **AND** ejemplos incorrectos:
|
|
- `ContactForm.json` (PascalCase)
|
|
- `contact_form.json` (snake_case)
|
|
- `contactForm.json` (camelCase)
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Namespaces
|
|
|
|
Los namespaces PHP DEBEN seguir convencion PascalCase jerarquica.
|
|
|
|
#### Scenario: Namespace raiz
|
|
- **WHEN** se define el namespace principal del tema
|
|
- **THEN** DEBE ser `ROITheme`
|
|
- **AND** ejemplo: `namespace ROITheme;`
|
|
|
|
#### Scenario: Namespaces de modulo publico
|
|
- **WHEN** se define un namespace para un componente en Public/
|
|
- **THEN** DEBE seguir `ROITheme\Public\[Componente]\[Capa][\Subcapa]`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
// Renderers
|
|
namespace ROITheme\Public\ContactForm\Infrastructure\Ui;
|
|
namespace ROITheme\Public\FeaturedImage\Infrastructure\Ui;
|
|
namespace ROITheme\Public\TopNotificationBar\Infrastructure\Ui;
|
|
|
|
// AJAX Handlers
|
|
namespace ROITheme\Public\Footer\Infrastructure\Api\WordPress;
|
|
namespace ROITheme\Public\ContactForm\Infrastructure\Api\WordPress;
|
|
|
|
// Domain (si existe)
|
|
namespace ROITheme\Public\AdsensePlacement\Domain\ValueObjects;
|
|
namespace ROITheme\Public\AdsensePlacement\Domain\Contracts;
|
|
|
|
// Application (si existe)
|
|
namespace ROITheme\Public\CustomCSSManager\Application\UseCases;
|
|
```
|
|
|
|
#### Scenario: Namespaces de modulo admin
|
|
- **WHEN** se define un namespace para un componente en Admin/
|
|
- **THEN** DEBE seguir `ROITheme\Admin\[Componente]\[Capa][\Subcapa]`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
// FormBuilders
|
|
namespace ROITheme\Admin\ContactForm\Infrastructure\Ui;
|
|
namespace ROITheme\Admin\FeaturedImage\Infrastructure\Ui;
|
|
|
|
// Shared de Admin
|
|
namespace ROITheme\Admin\Shared\Infrastructure\Ui;
|
|
```
|
|
|
|
#### Scenario: Namespaces de Shared
|
|
- **WHEN** se define un namespace para codigo compartido
|
|
- **THEN** DEBE seguir `ROITheme\Shared\[Capa][\Subcapa]`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
// Domain
|
|
namespace ROITheme\Shared\Domain\Contracts;
|
|
namespace ROITheme\Shared\Domain\Entities;
|
|
namespace ROITheme\Shared\Domain\ValueObjects;
|
|
|
|
// Application
|
|
namespace ROITheme\Shared\Application\UseCases;
|
|
|
|
// Infrastructure
|
|
namespace ROITheme\Shared\Infrastructure\Services;
|
|
namespace ROITheme\Shared\Infrastructure\Persistence\WordPress;
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Clases
|
|
|
|
Los nombres de clase DEBEN seguir convencion PascalCase.
|
|
|
|
#### Scenario: Clases regulares
|
|
- **WHEN** se define una clase en PHP
|
|
- **THEN** el nombre DEBE seguir PascalCase
|
|
- **AND** DEBE ser un sustantivo o frase sustantiva
|
|
- **AND** DEBE ser descriptivo de su responsabilidad
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class ContactFormRenderer
|
|
final class ComponentSettings
|
|
final class VisibilityChecker
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
final class contactFormRenderer // camelCase
|
|
final class contact_form_renderer // snake_case
|
|
final class Render // verbo, no sustantivo
|
|
```
|
|
|
|
#### Scenario: Clases Renderer
|
|
- **WHEN** se define una clase que renderiza HTML de un componente
|
|
- **THEN** DEBE usar sufijo `Renderer`
|
|
- **AND** DEBE implementar `RendererInterface`
|
|
- **AND** DEBE ser `final`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class ContactFormRenderer implements RendererInterface
|
|
final class FeaturedImageRenderer implements RendererInterface
|
|
final class TopNotificationBarRenderer implements RendererInterface
|
|
```
|
|
|
|
#### Scenario: Clases FormBuilder
|
|
- **WHEN** se define una clase que genera formularios admin
|
|
- **THEN** DEBE usar sufijo `FormBuilder`
|
|
- **AND** DEBE ser `final`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class ContactFormFormBuilder
|
|
final class FeaturedImageFormBuilder
|
|
final class TopNotificationBarFormBuilder
|
|
```
|
|
|
|
#### Scenario: Clases de caso de uso
|
|
- **WHEN** se define una clase UseCase en Application/
|
|
- **THEN** DEBE usar sufijo `UseCase`
|
|
- **AND** el nombre DEBE describir la accion
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class GetCriticalCSSUseCase
|
|
final class CheckAdsenseVisibilityUseCase
|
|
final class GetDeferredSnippetsUseCase
|
|
```
|
|
|
|
#### Scenario: Clases de servicio
|
|
- **WHEN** se define una clase que provee servicios en Infrastructure/
|
|
- **THEN** DEBE usar sufijo `Service`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class CSSGeneratorService
|
|
final class AntiSpamValidatorService
|
|
final class CacheService
|
|
```
|
|
|
|
#### Scenario: Clases de repositorio
|
|
- **WHEN** se define una clase de acceso a datos
|
|
- **THEN** DEBE usar sufijo `Repository`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class ComponentSettingsRepository
|
|
final class PageVisibilityRepository
|
|
```
|
|
|
|
#### Scenario: Clases Handler (AJAX/API)
|
|
- **WHEN** se define una clase que maneja peticiones AJAX o API
|
|
- **THEN** DEBE usar sufijo `Handler` o `Controller`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
final class NewsletterAjaxHandler
|
|
final class ContactFormAjaxHandler
|
|
final class AdsenseVisibilityController
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Interfaces
|
|
|
|
Los nombres de interface DEBEN seguir convencion PascalCase con sufijo.
|
|
|
|
#### Scenario: Interfaces
|
|
- **WHEN** se define una interface en PHP
|
|
- **THEN** el nombre DEBE terminar con `Interface`
|
|
- **AND** DEBE seguir PascalCase
|
|
- **AND** DEBE describir la capacidad o contrato
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
interface RendererInterface
|
|
interface CSSGeneratorInterface
|
|
interface ComponentRepositoryInterface
|
|
interface AjaxControllerInterface
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
interface IRenderer // prefijo I estilo C#
|
|
interface Renderer // sin sufijo
|
|
interface renderer_interface // snake_case
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Metodos
|
|
|
|
Los nombres de metodo DEBEN seguir convencion camelCase.
|
|
|
|
#### Scenario: Metodos publicos
|
|
- **WHEN** se define un metodo publico
|
|
- **THEN** el nombre DEBE seguir camelCase
|
|
- **AND** DEBE comenzar con verbo que describe la accion
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
public function render(Component $component): string
|
|
public function getVisibilityClass(array $data): ?string
|
|
public function validateInput(string $input): bool
|
|
public function buildForm(string $componentId): string
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
public function Render() // PascalCase
|
|
public function get_visibility_class() // snake_case
|
|
public function visibility() // sin verbo
|
|
```
|
|
|
|
#### Scenario: Metodos privados
|
|
- **WHEN** se define un metodo privado
|
|
- **THEN** DEBE seguir camelCase (igual que publicos)
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
private function parseResponse(): array
|
|
private function validateInternal(): bool
|
|
private function generateCSS(array $data): string
|
|
```
|
|
|
|
#### Scenario: Metodos booleanos
|
|
- **WHEN** un metodo retorna un valor booleano
|
|
- **THEN** DEBE usar prefijo `is`, `has`, `can`, `should`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
public function isEnabled(array $data): bool
|
|
public function hasPermission(string $capability): bool
|
|
public function canProcess(): bool
|
|
public function shouldShow(string $component): bool
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
public function enabled(): bool // sin prefijo
|
|
public function checkEnabled(): bool // check no es booleano
|
|
public function getIsEnabled(): bool // get redundante
|
|
```
|
|
|
|
#### Scenario: Metodos getter/setter
|
|
- **WHEN** se define un metodo de acceso
|
|
- **THEN** getters DEBEN usar prefijo `get`
|
|
- **AND** setters DEBEN usar prefijo `set`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
public function getData(): array
|
|
public function setData(array $data): void
|
|
public function getComponentName(): string
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Propiedades y Variables
|
|
|
|
Las propiedades y variables DEBEN seguir convencion camelCase.
|
|
|
|
#### Scenario: Propiedades de clase
|
|
- **WHEN** se declara una propiedad de clase
|
|
- **THEN** DEBE seguir camelCase
|
|
- **AND** DEBE tener visibilidad explicita (private, protected, public)
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
private CSSGeneratorInterface $cssGenerator;
|
|
private string $componentName;
|
|
protected array $settings;
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
private $CssGenerator; // PascalCase
|
|
private $css_generator; // snake_case
|
|
private $_cssGenerator; // prefijo _ (no necesario en PHP moderno)
|
|
```
|
|
|
|
#### Scenario: Propiedades booleanas
|
|
- **WHEN** se define una propiedad booleana
|
|
- **THEN** DEBE usar prefijo `is`, `has`, `can`
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
private bool $isEnabled;
|
|
private bool $hasChanges;
|
|
private bool $canEdit;
|
|
```
|
|
|
|
#### Scenario: Variables locales
|
|
- **WHEN** se declara una variable local
|
|
- **THEN** DEBE seguir $camelCase
|
|
- **AND** DEBE ser descriptiva
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
$showDesktop = $data['visibility']['show_on_desktop'] ?? true;
|
|
$visibilityClass = $this->getVisibilityClass($data);
|
|
$componentSettings = $this->repository->get($componentName);
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
$ShowDesktop // PascalCase
|
|
$show_desktop // snake_case
|
|
$sd // abreviatura
|
|
$strShowDesktop // notacion hungara
|
|
```
|
|
|
|
#### Scenario: Parametros de metodo
|
|
- **WHEN** se declara un parametro de metodo
|
|
- **THEN** DEBE seguir $camelCase
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
public function render(Component $component): string
|
|
public function validateField(string $fieldName, mixed $value): bool
|
|
```
|
|
|
|
#### Scenario: Variables de iteracion
|
|
- **WHEN** se usa una variable de iteracion en bucle
|
|
- **THEN** se permiten nombres cortos para indices: `$i`, `$j`, `$k`
|
|
- **AND** se prefiere nombre descriptivo para elementos
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
for ($i = 0; $i < count($items); $i++)
|
|
foreach ($components as $component)
|
|
foreach ($settings as $key => $value)
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Constantes
|
|
|
|
Las constantes DEBEN seguir convencion UPPER_SNAKE_CASE.
|
|
|
|
#### Scenario: Constantes de clase
|
|
- **WHEN** se define una constante de clase
|
|
- **THEN** DEBE seguir UPPER_SNAKE_CASE
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
private const COMPONENT_NAME = 'contact-form';
|
|
public const MAX_RETRY_COUNT = 3;
|
|
protected const DEFAULT_TIMEOUT = 5000;
|
|
```
|
|
- **AND** ejemplos incorrectos:
|
|
```php
|
|
private const componentName = 'contact-form'; // camelCase
|
|
private const ComponentName = 'contact-form'; // PascalCase
|
|
```
|
|
|
|
#### Scenario: Constantes globales
|
|
- **WHEN** se define una constante global del tema
|
|
- **THEN** DEBE usar prefijo `ROI_THEME_`
|
|
- **AND** DEBE seguir UPPER_SNAKE_CASE
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
define('ROI_THEME_VERSION', '1.0.0');
|
|
define('ROI_THEME_PATH', get_template_directory());
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de component_name
|
|
|
|
El identificador de componente DEBE usar kebab-case.
|
|
|
|
#### Scenario: component_name en JSON
|
|
- **WHEN** se define component_name en un schema JSON
|
|
- **THEN** DEBE usar kebab-case
|
|
- **AND** DEBE coincidir con el nombre del archivo JSON
|
|
- **AND** ejemplos correctos:
|
|
```json
|
|
{
|
|
"component_name": "contact-form",
|
|
"component_name": "featured-image",
|
|
"component_name": "top-notification-bar",
|
|
"component_name": "cta-box-sidebar"
|
|
}
|
|
```
|
|
|
|
#### Scenario: component_name en BD
|
|
- **WHEN** se guarda component_name en base de datos
|
|
- **THEN** DEBE mantener kebab-case
|
|
- **AND** tabla: `wp_roi_theme_component_settings`
|
|
- **AND** columna: `component_name`
|
|
|
|
#### Scenario: component_name en codigo PHP
|
|
- **WHEN** se usa component_name en codigo PHP
|
|
- **THEN** DEBE mantenerse en kebab-case
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
private const COMPONENT_NAME = 'contact-form';
|
|
|
|
public function supports(string $componentType): bool
|
|
{
|
|
return $componentType === 'contact-form';
|
|
}
|
|
|
|
// En data-attribute
|
|
$html .= 'data-component="contact-form"';
|
|
```
|
|
|
|
#### Scenario: Conversion kebab-case a PascalCase
|
|
- **WHEN** se necesita convertir component_name a nombre de carpeta/clase
|
|
- **THEN** eliminar guiones y capitalizar cada palabra
|
|
- **AND** ejemplos de conversion:
|
|
| kebab-case | PascalCase |
|
|
|------------|------------|
|
|
| `contact-form` | `ContactForm` |
|
|
| `featured-image` | `FeaturedImage` |
|
|
| `top-notification-bar` | `TopNotificationBar` |
|
|
| `cta-box-sidebar` | `CtaBoxSidebar` |
|
|
| `cta-lets-talk` | `CtaLetsTalk` |
|
|
|
|
---
|
|
|
|
### Requirement: Nomenclatura de Hooks WordPress
|
|
|
|
Los hooks DEBEN usar snake_case con prefijo del tema.
|
|
|
|
#### Scenario: Actions del tema
|
|
- **WHEN** se define un action hook del tema
|
|
- **THEN** DEBE usar prefijo `roi_theme_`
|
|
- **AND** DEBE seguir snake_case
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
do_action('roi_theme_after_render', $component);
|
|
do_action('roi_theme_before_form_submit');
|
|
do_action('roi_theme_component_loaded', $componentName);
|
|
```
|
|
|
|
#### Scenario: Filters del tema
|
|
- **WHEN** se define un filter hook del tema
|
|
- **THEN** DEBE usar prefijo `roi_theme_filter_`
|
|
- **AND** DEBE seguir snake_case
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
$css = apply_filters('roi_theme_filter_component_css', $css, $component);
|
|
$html = apply_filters('roi_theme_filter_render_output', $html);
|
|
```
|
|
|
|
#### Scenario: Acciones AJAX
|
|
- **WHEN** se registra una accion AJAX
|
|
- **THEN** DEBE usar prefijo `roi_`
|
|
- **AND** DEBE seguir snake_case
|
|
- **AND** ejemplos correctos:
|
|
```php
|
|
add_action('wp_ajax_roi_newsletter_subscribe', [$this, 'handle']);
|
|
add_action('wp_ajax_nopriv_roi_contact_form_submit', [$this, 'handle']);
|
|
```
|
|
|
|
---
|
|
|
|
### Requirement: Prohibicion de Notacion Hungara
|
|
|
|
La notacion hungara esta PROHIBIDA.
|
|
|
|
#### Scenario: Prefijos de tipo prohibidos
|
|
- **WHEN** se nombra una variable, propiedad o parametro
|
|
- **THEN** NO DEBE usar prefijos de tipo
|
|
- **AND** prefijos prohibidos:
|
|
|
|
| Prefijo | Significado | Ejemplo Incorrecto |
|
|
|---------|-------------|-------------------|
|
|
| `str` | String | `$strNombre` |
|
|
| `int`, `i` | Integer | `$intContador`, `$iTotal` |
|
|
| `b`, `bln` | Boolean | `$bActivo`, `$blnValido` |
|
|
| `arr` | Array | `$arrItems` |
|
|
| `obj` | Object | `$objRenderer` |
|
|
|
|
#### Scenario: Nombres correctos sin notacion hungara
|
|
- **WHEN** se reemplaza notacion hungara
|
|
- **THEN** usar nombres descriptivos
|
|
|
|
| Incorrecto | Correcto |
|
|
|------------|----------|
|
|
| `$strNombre` | `$name` o `$customerName` |
|
|
| `$bActivo` | `$isActive` |
|
|
| `$arrItems` | `$items` |
|
|
| `$objRenderer` | `$renderer` |
|
|
| `$intCount` | `$count` o `$itemCount` |
|
|
|
|
---
|
|
|
|
### Requirement: Validacion Pre-Commit de Nomenclatura
|
|
|
|
Las convenciones DEBEN validarse antes del commit.
|
|
|
|
#### Scenario: Checklist de nomenclatura
|
|
- **WHEN** el codigo esta listo para commit
|
|
- **THEN** verificar:
|
|
- [ ] Carpetas de modulo en PascalCase
|
|
- [ ] Archivos PHP en PascalCase.php
|
|
- [ ] Archivos JSON schema en kebab-case.json
|
|
- [ ] Namespaces en PascalCase jerarquico
|
|
- [ ] Clases en PascalCase
|
|
- [ ] Interfaces con sufijo Interface
|
|
- [ ] Metodos en camelCase
|
|
- [ ] Propiedades en camelCase
|
|
- [ ] Variables locales en $camelCase
|
|
- [ ] Constantes en UPPER_SNAKE_CASE
|
|
- [ ] component_name en kebab-case
|
|
- [ ] Hooks con prefijo roi_theme_
|
|
- [ ] SIN notacion hungara
|
|
- [ ] Metodos booleanos con is/has/can/should
|
|
- [ ] Renderers con sufijo Renderer
|
|
- [ ] FormBuilders con sufijo FormBuilder
|
|
- [ ] UseCases con sufijo UseCase
|
|
- [ ] Services con sufijo Service
|
|
|
|
---
|
|
|
|
## Tabla de Conversion Rapida
|
|
|
|
| De | A | Ejemplo |
|
|
|----|---|---------|
|
|
| kebab-case | PascalCase | `contact-form` → `ContactForm` |
|
|
| PascalCase | kebab-case | `ContactForm` → `contact-form` |
|
|
| PascalCase | camelCase | `ContactForm` → `contactForm` |
|
|
| snake_case | PascalCase | `contact_form` → `ContactForm` |
|
|
| snake_case | camelCase | `contact_form` → `contactForm` |
|
|
|
|
---
|
|
|
|
**Última actualización:** 2026-01-08
|