Cómo estructurar un plugin

8 abr 2012, 19:13:30
Vistas: 32.7K
Votos: 55

Esta no es una pregunta sobre cómo construir un plugin de WordPress. Más bien, trata sobre qué guías, si las hay, se podrían aplicar a cómo organizar la arquitectura de archivos de cualquier plugin.

Algunos otros lenguajes de programación o bibliotecas tienen formas muy controladas de organizar directorios y archivos. A veces esto es molesto y resalta la libertad que ofrece PHP, pero por otro lado, los plugins de WordPress se ensamblan de cualquier manera según lo determine su autor.

No hay una respuesta correcta, pero mi esperanza es refinar cómo yo y otros construimos plugins para hacerlos más amigables para que otros desarrolladores los analicen, sean más fáciles de depurar, más fáciles de navegar y posiblemente más eficientes.

La pregunta final: ¿cuál crees que es la mejor manera de organizar un plugin?

A continuación se muestran algunas estructuras de ejemplo, pero de ninguna manera es una lista exhaustiva. Siéntete libre de agregar tus propias recomendaciones.

Estructura Predeterminada Asumida

  • /wp-content
    • /plugins
      • /my-plugin
        • my-plugin.php

Método Modelo Vista Controlador (MVC)

  • /wp-content
    • /plugins
      • /my-plugin
        • /controller
          • Controller.php
        • /model
          • Model.php
        • /view
          • view.php
        • my-plugin.php

Las tres partes del MVC:

  • El modelo interactúa con la base de datos, consultando y guardando datos, y contiene la lógica.
  • El controlador contendría etiquetas de plantilla y funciones que utilizaría la vista.
  • La vista es responsable de mostrar los datos proporcionados por el modelo según lo construido por el controlador.

Método organizado por tipo

  • /wp-content
  • /plugins
    • /my-plugin
      • /admin
        • admin.php
      • /assets
        • css/
        • images/
      • /classes
        • my-class.php
      • /lang
        • my-es_ES.mo
      • /templates
        • my-template.php
      • /widgets
        • my-widget.php
      • my-plugin.php

WordPress Plugin Boilerplate

Disponible en Github

Basado en la API de Plugins, Estándares de Codificación, y Estándares de Documentación.

  • /wp-content
    • /plugins
      • /my-plugin
        • /admin
          • /css
          • /js
          • /partials
          • my-plugin-admin.php
        • /includes
          • my_plugin_activator.php
          • my_plugin_deactivator.php
          • my_plugin_i18n.php
          • my_plugin_loader.php
          • my_plugin.php
        • /languages
          • my_plugin.pot
        • /public
          • /css
          • /js
          • /partials
          • my-plugin-public.php
        • LICENSE.txt
        • README.txt
        • index.php
        • my-plugin.php
        • uninstall.php

Método organizado libremente

  • /wp-content
  • /plugins
    • /my-plugin
      • css/
      • images/
      • js/
      • my-admin.php
      • my-class.php
      • my-template.php
      • my-widget.php
      • my-plugin.php
3
Comentarios

Esta no es una pregunta real, pero no voy a votar para cerrarla, sino que la marcaré para convertirla en un Wiki de la Comunidad. Por cierto: no creo que tenga sentido prefijar los nombres de los archivos.

kaiser kaiser
8 abr 2012 19:19:06

Gracias, preferiría que esto fuera un wiki de la comunidad de todas formas. Tampoco creo que prefijar los archivos de esa manera tenga mucho sentido, pero lo he visto mucho.

developdaly developdaly
8 abr 2012 19:25:16

Otro punto adicional: Quizás nombres más semánticamente correctos para las carpetas css/, images/ y js/ serían styles/, images/ y scripts/.

Andrew Odri Andrew Odri
6 dic 2012 02:59:40
Todas las respuestas a la pregunta 11
0
19

Tenga en cuenta que todos los plugins son "controladores" según los estándares de WP.

Depende de lo que el plugin deba hacer, pero en todos los casos intentaría separar la salida en pantalla del código PHP tanto como sea posible.

Aquí hay una forma fácil de hacerlo: primero, define una función que cargue la plantilla:

function my_plugin_load_template(array $_vars){

  // no puedes permitir que locate_template cargue tu plantilla
  // porque los desarrolladores de WP se aseguraron de que no puedas pasar
  // variables a tu plantilla :(
  $_template = locate_template('my_plugin', false, false);

  // usa la predeterminada si el tema no la tiene
  if(!_$template)
    $_template = 'views/template.php';

  // cárgala
  extract($_vars);        
  require $template;
}

Ahora, si el plugin usa un widget para mostrar datos:

class Your_Widget extends WP_Widget{

  ...      
  public function widget($args, $instance){

    $title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base);

    // este widget muestra los últimos 5 "películas"
    $posts = new WP_Query(array('posts_per_page' => 5, 'post_type' => 'movie')); 

    if($title)
      print $before_title . $title . $after_title;

    // aquí dependemos de la plantilla para mostrar los datos en pantalla
    my_plugin_load_template(array(

      // variables que deseas exponer en la plantilla
     'posts'    => $posts,          
    ));

    print $before_widget;
  }
  ...

}

La plantilla:

<?php while($posts->have_posts()): $posts->the_post(); ?>

<p><?php the_title(); ?></p> 

<?php endwhile; ?>

Archivos:

/plugins/my_plugin/plugin.php           <-- solo hooks 
/plugins/my_plugin/widget.php           <-- clase del widget, si tienes un widget
/themes/twentyten/my_plugin.php         <-- plantilla
/plugins/my_plugin/views/template.php   <-- plantilla de respaldo

Dónde coloques tu CSS, JS, imágenes o cómo diseñes el contenedor para los hooks es menos importante. Supongo que es cuestión de preferencia personal.

9 abr 2012 16:21:26
2

Depende del plugin. Esta es mi estructura básica para casi todos los plugins:

my-plugin/
    inc/
        Cualquier archivo PHP adicional específico del plugin va aquí
    lib/
        Clases de biblioteca, css, js y otros archivos que uso con muchos
        plugins van aquí
    css/
    js/
    images/
    lang/
        Archivos de traducción
    my-plugin.php
    readme.txt

Esto sería algo que iría en la carpeta lib.

Si es un plugin particularmente complejo, con mucha funcionalidad en el área de administración, agregaría una carpeta admin para contener todos esos archivos PHP. Si el plugin hace algo como reemplazar archivos del tema incluidos, podría haber una carpeta template o theme también.

Entonces, una estructura de directorios podría verse así:

my-plugin/
    inc/
    lib/
    admin/
    templates/
    css/
    js/
    images/
    lang/
    my-plugin.php
    readme.txt
9 abr 2012 08:13:15
Comentarios

¿También incluirías los archivos CSS y JS del administrador dentro de la carpeta /admin? ¿Por lo tanto, tendrías otra carpeta /css y /js dentro de /admin?

urok93 urok93
12 ago 2012 10:52:14

Hola Chris, ¡Guau, hace más de una década, pero todavía una respuesta bastante buena! Sin embargo, también me gustaría escuchar tu respuesta a la pregunta de @urok93

Eric Hepperle - CodeSlayer2010 Eric Hepperle - CodeSlayer2010
14 feb 2024 15:36:52
0

En mi humilde opinión, la ruta más fácil, potente y mantenible es usar una estructura MVC, y WP MVC está diseñado para hacer que escribir plugins MVC sea muy sencillo (aunque soy un poco parcial...). Con WP MVC, simplemente creas los modelos, vistas y controladores, y todo lo demás se maneja automáticamente detrás de escena.

Se pueden crear controladores y vistas separados para las secciones públicas y de administración, y todo el framework aprovecha muchas de las características nativas de WordPress. La estructura de archivos y gran parte de la funcionalidad son exactamente iguales a las de los frameworks MVC más populares (Rails, CakePHP, etc.).

Puedes encontrar más información y un tutorial aquí:

14 abr 2012 17:29:44
0

Estamos utilizando una combinación de todos los métodos. En primer lugar, usamos el Zend Framework 1.11 en nuestros plugins y por lo tanto tuvimos que usar una estructura similar para los archivos de clases debido al mecanismo de autocarga.

La estructura de nuestro plugin principal (que sirve como base para todos nuestros plugins) es similar a esta:

webeo-core/
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Core.php
        Zend/
            /** archivos de ZF **/
        Loader.php
    views/
    readme.txt
    uninstall.php
    webeo-core.php
  1. WordPress llama al archivo webeo-core.php en la carpeta raíz del plugin.
  2. En este archivo configuramos la ruta de inclusión de PHP y registramos los hooks de activación y desactivación del plugin.
  3. También tenemos una clase Webeo_CoreLoader dentro de este archivo, que establece algunas constantes del plugin, inicializa el autocargador de clases y realiza una llamada al método setup de la clase Core.php dentro de la carpeta lib/Webeo. Esto se ejecuta en el hook de acción plugins_loaded con una prioridad de 9.
  4. La clase Core.php es nuestro archivo de arranque del plugin. El nombre se basa en el nombre del plugin.

Como puedes ver, tenemos un subdirectorio dentro de la carpeta lib para todos nuestros paquetes de proveedores (Webeo, Zend). Todos los subpaquetes dentro de un proveedor están estructurados por el módulo en sí. Para un nuevo formulario de administración de Configuración de Correo, tendríamos la siguiente estructura:

webeo-core/
    ...
    lib/
        Webeo/
            Form/
                Admin/
                    MailSettings.php
                Admin.php
            Core.php
            Form.php

Nuestros sub-plugins tienen la misma estructura con una excepción. Vamos un nivel más profundo dentro de la carpeta del proveedor para resolver conflictos de nombres durante el evento de autocarga. También llamamos a la clase de arranque del plugin Ejemplo: Faq.php con prioridad 10 dentro del hook plugins_loaded.

webeo-faq/ (usa/extiende webeo-core)
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Faq/
                Faq.php
                /** todos los archivos de clase relevantes del plugin **/
    views/
    readme.txt
    uninstall.php
    webeo-faq.php

Probablemente en la próxima versión cambiaré el nombre de la carpeta lib a vendors y moveré todas las carpetas públicas (css, images, js, languages) a una carpeta llamada public.

13 abr 2012 11:51:01
0

Como muchos ya han respondido aquí, realmente depende de lo que se supone que debe hacer el plugin, pero aquí está mi estructura base:

my-plugin/
    admin/
        contiene todos los archivos administrativos del backend
        js/
            contiene todos los archivos JavaScript del backend
        css/                    
            contiene todos los archivos CSS del backend
        images/
            contiene todas las imágenes del backend
        admin_file_1.php        archivo de funcionalidad del backend
        admin_file_2.php        otro archivo de funcionalidad del backend
    js/
        contiene todos los archivos JavaScript para el frontend
    css/
        contiene todos los archivos CSS para el frontend
    inc/
        contiene todas las clases auxiliares
    lang/                   
        contiene todos los archivos de traducción
    images/
        contiene todas las imágenes para el frontend
    my-plugin.php               archivo principal del plugin con metadatos, principalmente includes, hooks de acciones y filtros
    readme.txt                  
    changelog.txt
    license.txt
13 abr 2012 19:43:40
0

Me inclino por la siguiente estructura de plugin, aunque suele variar dependiendo de los requisitos específicos del plugin.

wp-content/
    plugins/
        mi-plugin/
            inc/
                Archivos específicos solo para este plugin
                admin/ 
                    Archivos para tareas administrativas
            lib/
                Aquí van las clases de biblioteca/helpers
            css/
                Archivos CSS para el plugin
            js/
                Archivos JavaScript
            images/
                Imágenes para mi plugin
            lang/
                Archivos de traducción
        plugin.php 
            Este es el archivo principal que incluye/llama a otros archivos
        README 
            Normalmente coloco los detalles de la licencia aquí además de información útil

Todavía no he creado un plugin para WordPress que requiera una arquitectura estilo MVC, pero si tuviera que hacerlo, lo estructuraría con un directorio MVC separado que a su vez contenga views/controllers/models.

13 abr 2012 09:02:48
0

Todos mis plugins siguen esta estructura, que parece ser muy similar a lo que hacen la mayoría de otros desarrolladores:

carpeta-del-plugin/
    admin/
        css/
            imagenes/
        js/
    core/
    css/
        imagenes/
    js/
    languages/
    library/
    templates/
    carpeta-del-plugin.php
    readme.txt
    changelog.txt
    license.txt

El archivo carpeta-del-plugin.php es usualmente una clase que carga todos los archivos requeridos desde la carpeta core/. La mayoría de las veces en el hook init o plugins_loaded.

Solía prefijar todos mis archivos también, pero como @kaiser mencionó anteriormente, es realmente redundante y recientemente decidí eliminarlo de cualquier plugin futuro.

La carpeta library/ contiene todas las librerías externas auxiliares de las que el plugin podría depender.

Dependiendo del plugin, podría haber un archivo uninstall.php en la raíz del plugin también. La mayoría de las veces esto se maneja mediante register_uninstall_hook(), sin embargo.

Obviamente, algunos plugins podrían no requerir archivos de administración o plantillas, etc, pero la estructura anterior funciona para mí. Al final solo tienes que encontrar una estructura que funcione para ti y luego mantenerla.

También tengo un plugin de inicio, basado en la estructura anterior que uso como punto de partida para todos mis plugins. Todo lo que necesito hacer entonces es una búsqueda/reemplazo para los prefijos de funciones/clases y listo. Cuando todavía estaba prefijando mis archivos ese era un paso extra que tenía que hacer (y bastante molesto por cierto), pero ahora solo tengo que renombrar la carpeta del plugin y el archivo principal del plugin.

13 abr 2012 13:28:34
0

Mi lógica es que cuanto más grande es el plugin, más estructura utilizo.
Para plugins grandes tiendo a usar MVC.
Uso esto como punto de partida y omito lo que no sea necesario.

controller/
    frontend.php
    wp-admin.php
    widget1.php
    widget2.php
model/
    standard-wp-tables.php // si es necesario, dividirlo
    custom-tabel1.php
    custom-tabel2.php
view/
    helper.php
    frontend/
        archivos...php
    wp-admin/
        archivos...php
    widget1/
        archivo...php
    widget2/
        archivo...php
css/
js/
image/
library/  //solo php, principalmente para Zend Framework, nuevamente si es necesario
constants.php //tiendo a usarlo con frecuencia
plugin.php //archivo de inicialización
install-unistall.php  //solo en plugins grandes
18 abr 2012 15:20:46
0

También, revisa este excelente boilerplate para widgets de WP. Proporciona excelentes pistas sobre las estructuras (incluso si no hay una clase ni carpeta para modelos separados).

17 jun 2013 11:42:52
1

Un enfoque menos común para estructurar los archivos y directorios de un plugin es el enfoque por tipo de archivo. Vale la pena mencionarlo aquí para completar la información:

plugin-name/
    js/
        sparkle.js
        shake.js
    css/
        style.css
    scss/
        header.scss
        footer.scss
    php/
        class.php
        functions.php
    plugin-name.php
    uninstall.php
    readme.txt

Cada directorio contiene solo archivos de ese tipo. Es importante señalar que este enfoque se queda corto cuando tienes muchos tipos de archivos .png .gif .jpg que podrían organizarse de manera más lógica bajo un solo directorio, como por ejemplo images/.

8 nov 2015 01:40:00
Comentarios

Un aplauso por contribuir a la completitud

Eric Hepperle - CodeSlayer2010 Eric Hepperle - CodeSlayer2010
14 feb 2024 15:39:59
0

¡He desarrollado una plantilla de repositorio en GitHub para plugins de WordPress, encapsulando más de 10 años de experiencia en un esquema estructurado!

https://github.com/EdwardBock/wordpress-plugin-starterkit

La plantilla cumple con los estándares PSR-4 para minimizar los includes de strings y utiliza namespaces para un nombrado de clases conciso y una clase de componente de plantillas. También incluye un archivo docker compose para poder desarrollar el plugin de forma aislada. Pero también puede colocarse en un proyecto existente y funcionar sin problemas.

¡Disfruta explorando y no dudes en contribuir!

11 jul 2024 23:07:34