Ir al contenido
  • Inicio
  • Libro
  • Blog
  • Sobre nosotros
  • Ayuda
  • Contáctanos
  •  [email protected]
  • Inicia sesión
  • English (US) Español (BO)
  • Simplify It S.R.L.
    • Contáctanos
Simplify It S.R.L.
      • Inicio
      • Libro
      • Blog
      • Sobre nosotros
      • Ayuda
      • Contáctanos
    •  [email protected]
    • English (US) Español (BO)
    • Inicia sesión
    • Contáctanos

    Capítulo 5: ¡Hola, OWL! Tu Primer Componente

  • Todos los blogs
  • Libro OWL
  • Capítulo 5: ¡Hola, OWL! Tu Primer Componente
  • 25 de agosto de 2026 por
    Capítulo 5: ¡Hola, OWL! Tu Primer Componente
    Grover Menacho

    ¿Por qué este capítulo? Cada característica de OWL que aprenderás más adelante se apoya en el mismo esqueleto de tres archivos que armas aquí — si dominas esta parte, el resto del libro son adiciones, no sorpresas. ¿Qué trata de resolver Odoo con esto? Una estructura predecible y consistente para cada pieza de interfaz personalizada del ecosistema, para que cualquier desarrollador de Odoo pueda abrir la carpeta static/src de cualquier addon y saber de inmediato dónde mirar. Aplicación en la vida real: Este es exactamente el andamiaje que reutilizarás el primer día de cualquier proyecto de cliente — un widget de dashboard personalizado, un formulario de portal, una tarjeta de kanban modificada — antes de escribir una sola línea de lógica de negocio.

    ¡Felicidades por completar los fundamentos! Ahora tienes todo el conocimiento de JavaScript que necesitas para comenzar a construir con OWL. En este capítulo, la teoría termina y la aplicación práctica comienza. Vamos a construir nuestro primer componente clásico "¡Hola, Mundo!".

    Este es el momento donde todo lo que has aprendido—clases, módulos, plantillas literales, destructuración y la mentalidad declarativa—se une. Al final de este capítulo, tendrás un componente OWL funcionando dentro de Odoo. Comencemos.


    Anatomía de un Componente OWL

    Un componente OWL no es un solo archivo. Es un pequeño ecosistema autónomo típicamente compuesto por tres archivos, cada uno con una responsabilidad específica. Esta separación de responsabilidades es un principio central que mantiene tu código limpio, organizado y mantenible.

    Piensa en ello como construir una casa:

    1. El Archivo JavaScript (.js): Este es el cerebro de tu componente. Contiene la lógica, el estado, los métodos y define cómo se comporta el componente. Aquí es donde todas tus habilidades modernas de JavaScript entran en juego.

    2. El Archivo XML (.xml): Este es el esqueleto. Define la estructura y diseño de la UI de tu componente usando QWeb, el poderoso lenguaje de plantillas de Odoo. Esto determina lo que ven los usuarios.

    3. El Archivo CSS/SCSS (.scss): Esta es la piel. Contiene todas las reglas de estilo para hacer que tu componente se vea profesional y coincida con el sistema de diseño de Odoo. (Cubriremos el estilo en detalle en capítulos posteriores.)

    Para nuestro primer componente, nos enfocaremos en los primeros dos: el archivo JavaScript y el XML. No te preocupes por el estilo por ahora—primero hagamos que la funcionalidad funcione.


    Configurando la Estructura de tu Módulo

    Antes de escribir cualquier código, establezcamos una estructura de archivos adecuada. La organización importa, especialmente cuando tus componentes crecen en complejidad.

    Crea la siguiente estructura de directorios en tu módulo de Odoo:

    my_odoo_module/
    |-- __manifest__.py
    |-- static/
    |   |-- src/
    |       |-- components/
    |           |-- hello_world/
    |               |-- hello_world.js
    |               |-- hello_world.xml
    |               |-- hello_world.scss (lo añadiremos después)
    |-- views/
        |-- hello_world_views.xml
    

    ¿Por qué esta estructura? - static/src/components/: Esta es la ubicación estándar para componentes OWL en módulos de Odoo - Carpetas específicas de componentes: Cada componente tiene su propia carpeta (hello_world/) para mantener los archivos relacionados juntos - Nomenclatura consistente: Los archivos se nombran según el componente para fácil identificación


    El Archivo JavaScript: La Lógica del Componente

    Creemos nuestro primer componente. Crea el archivo my_odoo_module/static/src/components/hello_world/hello_world.js:

    /** @odoo-module **/
    
    import { Component } from "@odoo/owl";
    import { registry } from "@web/core/registry";
    
    export class HelloWorld extends Component {
        static template = "my_odoo_module.HelloWorld";
    
        setup() {
            console.log("¡El componente HelloWorld se está configurando!");
        }
    }
    
    // Registrar el componente como acción de cliente para que Odoo pueda mostrarlo
    registry.category("actions").add("hello_world_app", HelloWorld);
    

    Analicemos esto línea por línea:

    /** @odoo-module **/: Este es un comentario especial que le dice al sistema de assets de Odoo que trate este archivo como un módulo. Es obligatorio para todos los archivos JavaScript en módulos de Odoo. Sin él, tu componente no será reconocido.

    import { Component } from "@odoo/owl";: Aquí estamos usando la sintaxis de importación con destructuración que aprendimos. Estamos extrayendo la clase Component de la librería OWL. Esto nos da acceso a todas las características poderosas de los componentes OWL.

    export class HelloWorld extends Component { ... }: Esta línea hace varias cosas importantes: - export: Hace nuestra clase disponible para otras partes del sistema (¿recuerdas los módulos?) - class HelloWorld: Define nuestra clase de componente con un nombre descriptivo - extends Component: Hereda toda la funcionalidad de OWL (¿recuerdas la herencia de clases?)

    static template = "my_odoo_module.HelloWorld";: Este es el enlace crucial entre nuestra lógica JavaScript y nuestra plantilla XML. El nombre debe ser: - Único en toda tu instancia de Odoo - Seguir la convención: nombre_modulo.NombreComponente - Coincidir exactamente con lo que definimos en el archivo XML

    setup() { ... }: Este es el enfoque moderno de OWL 2.0 para la inicialización de componentes. Reemplaza el patrón del constructor anterior y se ejecuta cuando se crea el componente. El console.log nos ayudará a ver cuándo nuestro componente está funcionando.

    registry.category("actions").add("hello_world_app", HelloWorld);: Esto registra nuestro componente en el registro de acciones de Odoo bajo el tag hello_world_app. En un momento crearemos una acción de cliente en el servidor cuyo campo tag coincida con este nombre—así es como Odoo sabe qué componente renderizar cuando se dispara la acción.

    Entendiendo el Ciclo de Vida del Componente

    Incluso en este ejemplo simple, OWL está haciendo mucho detrás de escena:

    1. Creación del Componente: OWL crea una instancia de nuestra clase HelloWorld
    2. Ejecución del Setup: Nuestro método setup() se ejecuta, permitiéndonos inicializar estado y servicios
    3. Renderizado de Plantilla: OWL encuentra la plantilla que especificamos y la renderiza
    4. Inserción en el DOM: El HTML renderizado se inserta en la página

    El Archivo XML: La Plantilla del Componente

    Ahora creemos la plantilla que nuestro archivo JavaScript referencia. Crea el archivo my_odoo_module/static/src/components/hello_world/hello_world.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <templates xml:space="preserve">
    
        <t t-name="my_odoo_module.HelloWorld" owl="1">
            <div class="hello-world-component">
                <div class="alert alert-info">
                    <h1 class="alert-heading">
                        <i class="fa fa-rocket me-2"></i>
                        ¡Hola, Mundo OWL!
                    </h1>
                    <p class="mb-0">
                        ¡Este es mi primer componente OWL, y está funcionando perfectamente!
                    </p>
                    <hr class="my-3"/>
                    <p class="mb-0">
                        <strong>Nombre del Componente:</strong> HelloWorld<br/>
                        <strong>Plantilla:</strong> my_odoo_module.HelloWorld<br/>
                        <strong>Framework:</strong> OWL 2.0
                    </p>
                </div>
            </div>
        </t>
    
    </templates>
    

    Examinemos las partes importantes:

    <templates xml:space="preserve">: Este es el envoltorio estándar para todos los archivos de plantilla de Odoo. El xml:space="preserve" asegura que el espacio en blanco en tus plantillas se maneje correctamente.

    <t t-name="my_odoo_module.HelloWorld" owl="1">: Aquí es donde ocurre la magia: - <t>: Una etiqueta de plantilla QWeb que no se renderiza a sí misma, solo su contenido - t-name="my_odoo_module.HelloWorld": El identificador único que debe coincidir exactamente con la propiedad static template en nuestra clase JavaScript - owl="1": Este atributo crucial le dice al motor QWeb de Odoo que procese esta plantilla usando el renderizador OWL en lugar del renderizador heredado

    El Contenido HTML: Dentro de la etiqueta <t> está el HTML estándar que se convertirá en la estructura DOM real de tu componente. He usado clases de Bootstrap (que Odoo incluye) para que se vea profesional de inmediato.

    ¿Por qué Esta Estructura de Plantilla?

    • HTML Semántico: Usamos elementos HTML5 apropiados y clases de Bootstrap
    • Retroalimentación visual clara: El estilo de alerta hace obvio cuándo el componente se renderiza
    • Información de depuración: Incluimos los nombres del componente y la plantilla para fácil identificación
    • Apariencia profesional: Incluso un componente "Hello World" debería verse bien en Odoo

    Registrando el Componente con Odoo

    Hemos creado los archivos del componente, pero Odoo aún no sabe sobre ellos. Necesitamos registrarlos con el sistema de assets.

    Paso 1: Actualizar el Manifiesto del Módulo

    Abre el archivo __manifest__.py de tu módulo y añade los nuevos archivos al diccionario assets:

    # En __manifest__.py
    {
        'name': 'Mi Módulo Hello World OWL',
        'version': '1.0',
        'depends': ['base', 'web'],
        'data': [
            'views/hello_world_views.xml',
        ],
        'assets': {
            'web.assets_backend': [
                'my_odoo_module/static/src/components/hello_world/hello_world.js',
                'my_odoo_module/static/src/components/hello_world/hello_world.xml',
            ],
        },
        'installable': True,
        'auto_install': False,
    }
    

    Puntos importantes sobre assets: - web.assets_backend: Este bundle se carga en el backend de Odoo (donde viven la mayoría de las aplicaciones de negocio) - El orden importa: Los archivos JavaScript generalmente deberían venir antes que los archivos XML - Precisión en las rutas: Revisa dos veces las rutas de tus archivos—los errores tipográficos aquí causarán fallas silenciosas

    Paso 2: Crear una Vista para Mostrar el Componente

    Crea un archivo de vista en my_odoo_module/views/hello_world_views.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <odoo>
        <data>
    
            <!-- Definir una acción de cliente para mostrar nuestro componente.
                 El "tag" debe coincidir con el nombre usado en registry.category("actions").add(...) -->
            <record id="action_hello_world" model="ir.actions.client">
                <field name="name">Hola Mundo OWL</field>
                <field name="tag">hello_world_app</field>
                <field name="target">current</field>
            </record>
    
            <!-- Añadir un elemento de menú para que los usuarios puedan encontrar tu componente -->
            <menuitem id="menu_hello_world"
                      name="Hola Mundo OWL"
                      action="action_hello_world"
                      parent="base.menu_administration"
                      sequence="100"/>
    
        </data>
    </odoo>
    

    Entendiendo esta estructura:

    Acción de Cliente: A diferencia de las vistas regulares de Odoo (formulario, lista, etc.), los componentes OWL a menudo usan "acciones de cliente"—acciones especiales que renderizan aplicaciones JavaScript personalizadas en lugar de vistas estándar.

    El campo tag es el enlace: Cuando el usuario dispara esta acción, Odoo busca hello_world_app en el registro de acciones de JavaScript y encuentra el componente HelloWorld que registramos ahí. No se necesita ninguna plantilla del lado del servidor—la propia plantilla QWeb del componente se encarga del renderizado.

    Integración de Menú: El <menuitem> les da a los usuarios una forma de acceder a tu componente a través del sistema de menú estándar de Odoo.


    Probando tu Componente

    ¡Ahora el momento de la verdad! Vamos a hacer funcionar tu componente:

    Paso 1: Instalar/Actualizar tu Módulo

    # Si este es un módulo nuevo
    ./odoo-bin -d tu_base_de_datos -i my_odoo_module --dev=all
    
    # Si estás actualizando un módulo existente
    ./odoo-bin -d tu_base_de_datos -u my_odoo_module --dev=all
    

    La bandera --dev=all es crucial—asegura que tus cambios de JavaScript y XML se carguen inmediatamente sin necesidad de reiniciar el servidor.

    Paso 2: Navegar a tu Componente

    1. Inicia sesión en tu instancia de Odoo
    2. Ve a Configuración (o donde hayas puesto tu elemento de menú)
    3. Haz clic en "Hola Mundo OWL"

    Si todo funcionó correctamente, ¡deberías ver tu hermoso componente renderizado con el estilo de alerta de Bootstrap!

    Paso 3: Verificar en las Herramientas de Desarrollo del Navegador

    Abre las DevTools de tu navegador (F12) y:

    1. Revisa la Consola: Deberías ver el mensaje "¡El componente HelloWorld se está configurando!"
    2. Inspecciona los Elementos: Deberías ver la estructura HTML de tu plantilla
    3. Revisa la pestaña Network: Verifica que tus archivos .js y .xml se cargaron

    Problemas Comunes y Soluciones

    Error "Component not found": - Verifica que tu propiedad static template coincida exactamente con el t-name en tu XML - Verifica que ambos archivos estén listados en __manifest__.py - Asegúrate de haber actualizado tu módulo

    Error "Template not found": - Confirma que el atributo owl="1" esté presente en tu plantilla - Revisa errores tipográficos en el nombre de la plantilla - Verifica que el archivo XML sea válido (sin errores de sintaxis)

    El componente no aparece: - Revisa la consola del navegador para errores de JavaScript - Verifica que tu acción de cliente y elemento de menú estén definidos correctamente - Asegúrate de estar ejecutando con --dev=all

    El estilo se ve mal: - Odoo incluye Bootstrap por defecto, así que nuestras clases deberían funcionar - Intenta inspeccionar los elementos para ver qué CSS se está aplicando - Recuerda que no hemos añadido CSS personalizado aún—eso viene en capítulos posteriores


    Lo que has Logrado

    ¡Felicidades! Acabas de construir tu primer componente OWL e integrarlo en Odoo. Este ejemplo aparentemente simple demuestra varios conceptos cruciales:

    Arquitectura de Componentes: Has visto cómo la lógica JavaScript y las plantillas XML trabajan juntas

    JavaScript Moderno en la Práctica: Has usado import, export, class y extends en una aplicación real

    Integración con Odoo: Entiendes cómo los componentes OWL encajan en el sistema de módulos de Odoo

    Flujo de Trabajo de Desarrollo: Sabes cómo crear, registrar y probar componentes

    Fundamentos de Depuración: Tienes los conceptos básicos para solucionar problemas cuando las cosas salen mal

    TL;DR: Un componente OWL es una clase JS (static template + setup()) emparejada con una plantilla XML QWeb (t-name, owl="1") cuyos nombres deben coincidir exactamente; se registra con registry.category("actions").add(tag, Component) y un registro ir.actions.client que comparte ese tag.

    Pruébalo tú mismo: El ejemplo de este capítulo está disponible como addon instalable de Odoo 19: simplifyit_owl_book_ch5_ex1. Las instrucciones de instalación están en el README del repositorio.

    Ejercicios

    1. Personaliza el saludo. Cambia el componente para que salude a un nombre específico (ej. "¡Hola, Ana!") agregando una propiedad JavaScript simple en setup() y mostrándola con t-esc en la plantilla.
    2. Rómpelo a propósito. Renombra el t-name en tu archivo XML para que ya no coincida con static template en el archivo JavaScript, recarga la página, y lee el error exacto que Odoo muestra en la consola. Luego arréglalo. Reconocer este mensaje de error te ahorrará tiempo más adelante.
    3. Añade una segunda acción. Añade un botón que llame a un nuevo método que registre un mensaje en la consola con console.log, y verifícalo en la pestaña Console de las DevTools del navegador del Capítulo 2.

    ¿Qué Sigue?

    Ahora mismo este componente es estático — muestra el mismo texto sin importar nada. El Capítulo 6 lo hace dinámico: aprenderás las directivas QWeb (t-esc, t-if, t-foreach y más) que permiten que tu plantilla reaccione a los datos que vienen del lado JavaScript.

    en Libro OWL
    Capítulo 6: Renderizado con Plantillas QWeb
    Reading the whole book? Take it with you — free, no sign-up.
    PDF EPUB All chapters
    Enlaces útiles
    • Inicio
    • Sobre nosotros
    • Blog
    • El libro de OWL 2.0
    • Ayuda
    • Contáctanos
    Sobre nosotros

    Simplify It S.R.L. es una firma de implementación y desarrollo Odoo con base en La Paz, Bolivia, que trabaja con empresas de Latinoamérica y Norteamérica. Desarrollamos sobre Odoo desde la versión 6.1: módulos a medida, migraciones de versión y localización boliviana.

    También somos autores del libro de OWL 2.0, que publicamos gratis capítulo a capítulo en nuestro blog.

    Conecta con nosotros
    • Contáctanos
    • [email protected]
    • +591 65144144
    • La Paz, Bolivia
    Síguenos
    Copyright © Simplify It S.R.L.
    English (US) | Español (BO)
    Con la tecnología de Odoo - Cree un sitio web gratuito