Files
roi-theme/_openspec/specs/nomenclatura.md
FrankZamora 0f6387ab46 refactor: reorganizar openspec y planificacion con spec recaptcha
- 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>
2026-01-08 15:30:45 -06:00

22 KiB

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:
    // 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:
    // 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:
    // 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:
    final class ContactFormRenderer
    final class ComponentSettings
    final class VisibilityChecker
    
  • AND ejemplos incorrectos:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    interface RendererInterface
    interface CSSGeneratorInterface
    interface ComponentRepositoryInterface
    interface AjaxControllerInterface
    
  • AND ejemplos incorrectos:
    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:
    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:
    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:
    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:
    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:
    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:
    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:
    private CSSGeneratorInterface $cssGenerator;
    private string $componentName;
    protected array $settings;
    
  • AND ejemplos incorrectos:
    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:
    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:
    $showDesktop = $data['visibility']['show_on_desktop'] ?? true;
    $visibilityClass = $this->getVisibilityClass($data);
    $componentSettings = $this->repository->get($componentName);
    
  • AND ejemplos incorrectos:
    $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:
    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:
    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:
    private const COMPONENT_NAME = 'contact-form';
    public const MAX_RETRY_COUNT = 3;
    protected const DEFAULT_TIMEOUT = 5000;
    
  • AND ejemplos incorrectos:
    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:
    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:
    {
      "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:
    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:
    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:
    $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:
    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-formContactForm
PascalCase kebab-case ContactFormcontact-form
PascalCase camelCase ContactFormcontactForm
snake_case PascalCase contact_formContactForm
snake_case camelCase contact_formcontactForm

Última actualización: 2026-01-08