Cómo estructurar un complemento

34

Esto no es una pregunta sobre cómo crear un complemento de WordPress. Más bien, qué guías, si las hay, podrían aplicarse a cómo armar la arquitectura de archivos de cualquier complemento.

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 en el lado opuesto, los complementos de WordPress se combinan de cualquier manera según lo determine su autor.

No hay una respuesta correcta , pero mi esperanza es refinar la forma en que yo, y otros, construimos complementos para hacerlos más amigables para otros desarrolladores, más fáciles de depurar, más fáciles de navegar , y posiblemente más eficiente.

La pregunta final: ¿qué cree usted que es la mejor manera de organizar un complemento?

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

Estructura predeterminada supuesta

  • %código%
    • %código%
      • %código%
        • /wp-content

Método del controlador de vista de modelo (MVC)

  • %código%
    • %código%
      • %código%
        • %código%
          • /plugins
        • %código%
          • /my-plugin
        • %código%
          • my-plugin.php
        • /wp-content

MVC en tres partes:

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

Organizado por el método de tipo

  • %código%
    • %código%
      • %código%
        • %código%
          • /plugins
        • %código%
          • /my-plugin
          • /controller
        • %código%
          • Controller.php
        • %código%
          • /model
        • %código%
          • Model.php
        • %código%
          • /view
        • view.php

Método poco organizado

  • %código%
    • %código%
      • %código%
        • my-plugin.php
        • /wp-content
        • /plugins
        • /my-plugin
        • /admin
        • admin.php
        • /assets
        • css/
pregunta developdaly 08.04.2012 - 18:13

10 respuestas

16

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

Depende de lo que se supone que haga el complemento, pero en todos los casos trataría de separar la salida de pantalla del código PHP tanto como sea posible.

Esta es una forma de hacerlo fácilmente: primero, defina una función que cargue la plantilla:

function my_plugin_load_template(array $_vars){

  // you cannot let locate_template to load your template
  // because WP devs made sure you can't pass
  // variables to your template :(
  $_template = locate_template('my_plugin', false, false);

  // use the default one if the theme doesn't have it
  if(!_$template)
    $_template = 'views/template.php';

  // load it
  extract($_vars);        
  require $template;
}

Ahora, si el complemento utiliza 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);

    // this widget shows the last 5 "movies"
    $posts = new WP_Query(array('posts_per_page' => 5, 'post_type' => 'movie')); 

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

    // here we rely on the template to display the data on the screen
    my_plugin_load_template(array(

      // variables you wish to expose in the template
     '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           <-- just hooks 
/plugins/my_plugin/widget.php           <-- widget class, if you have a widget
/themes/twentyten/my_plugin.php         <-- template
/plugins/my_plugin/views/template.php   <-- fallback template

¿Dónde colocas tu CSS, JS, imágenes o cómo diseñar el contenedor para los ganchos es menos importante? Es una cuestión de preferencia personal, supongo.

    
respondido por el onetrickpony 09.04.2012 - 15:21
6

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

my-plugin/
    inc/
        Any additional plugin-specific PHP files go here
    lib/
        Library classes, css, js, and other files that I use with many
        plugins go here
    css/
    js/
    images/
    lang/
        Translation files
    my-plugin.php
    readme.txt

Esto sería algo que se incluiría en la carpeta lib .

Si es un complemento particularmente complejo, con una gran cantidad de funciones en el área de administración, agregaría una carpeta admin para contener todos esos archivos PHP. Si el complemento hace algo como reemplazar, se incluyen archivos de tema , quizás haya un La carpeta template o theme también.

Por lo tanto, una estructura de directorios podría tener este aspecto:

my-plugin/
    inc/
    lib/
    admin/
    templates/
    css/
    js/
    images/
    lang/
    my-plugin.php
    readme.txt
    
respondido por el chrisguitarguy 09.04.2012 - 07:13
6

En mi humilde opinión, la ruta más fácil, más poderosa y más fácil de mantener es usar una estructura MVC, y WP MVC está diseñado para hacer que la escritura de complementos MVC sea muy fácil (aunque estoy un poco sesgado, sin embargo ...). Con WP MVC, simplemente creas los modelos, las vistas y los controladores, y todo lo demás se maneja entre bambalinas para ti.

Se pueden hacer vistas y controladores separados para las secciones de administración y público, y todo el marco aprovecha muchas de las características nativas de WordPress. La estructura de archivos y gran parte de la funcionalidad es exactamente la misma que en los marcos MVC más populares (Rails, CakePHP, etc.).

Más información y un tutorial se pueden encontrar aquí:

respondido por el Tom 14.04.2012 - 16:29
5

Estamos usando una mezcla de todos los métodos. En primer lugar, estamos utilizando Zend Framework 1.11 en nuestros complementos y, por lo tanto, tuvimos que usar una estructura similar para los archivos de clase debido a la mecánica de carga automática.

La estructura de nuestro complemento principal (que es utilizado por todos nuestros complementos como base) es similar a esto:

webeo-core/
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Core.php
        Zend/
            /** ZF files **/
        Loader.php
    views/
    readme.txt
    uninstall.php
    webeo-core.php
  1. WordPress llama al archivo webeo-core.php en la carpeta raíz del complemento.
  2. En este archivo vamos a establecer la ruta de inclusión de PHP y registrar los ganchos de activación y desactivación para el complemento.
  3. También tenemos una clase Webeo_CoreLoader dentro de este archivo, que establece algunas constantes de complementos, inicializa el autoloader de la clase y realiza una llamada al método de configuración de la clase Core.php dentro de la carpeta lib/Webeo . Esto se ejecuta en el gancho de acción plugins_loaded con una prioridad de 9 .
  4. La clase Core.php es nuestro archivo bootstrap de complemento. El nombre se basa en el nombre de los complementos.

Como puede 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 propio módulo. Para un nuevo formulario de administrador Mail Settings , 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. Profundizamos en la carpeta del proveedor para resolver los conflictos de nombres durante el evento de carga automática. También llamamos a la clase boostrap de complementos E.g. Faq.php en la prioridad 10 dentro del gancho plugins_loaded .

webeo-faq/ (uses/extends webeo-core)
    css/
    images/
    js/
    languages/
    lib/
        Webeo/
            Faq/
                Faq.php
                /** all plugin relevant class files **/
    views/
    readme.txt
    uninstall.php
    webeo-faq.php

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

    
respondido por el rofflox 13.04.2012 - 10:51
5

Al igual que muchos de los que están aquí ya contestados. Realmente depende de lo que se supone que debe hacer el complemento, pero aquí está mi estructura base:

my-plugin/
    admin/
        holds all back-end administrative files
        js/
            holds all back-end JavaScript files
        css/                    
            holds all back-end CSS files
        images/
            holds all back-end images
        admin_file_1.php        back-end functionality file
        admin_file_2.php        another back-end functionality file 
    js/
        holds all front end JavaScript files
    css/
        holds all fronted CSS files
    inc/
        holds all helper classes
    lang/                   
        holds all translation files
    images/
        holds all fronted images
    my-plugin.php               main plugin file with plugin meta, mostly includes,action and filter hooks
    readme.txt                  
    changelog.txt
    license.txt
    
respondido por el Bainternet 13.04.2012 - 18:43
4

Soy parcial al siguiente diseño de complementos, sin embargo, generalmente cambia según los requisitos de los complementos.

wp-content/
    plugins/
        my-plugin/
            inc/
                Specific files for only this plugin
                admin/ 
                    Files for dealing with administrative tasks
            lib/
                Library/helper classes go here
            css/
                CSS files for the plugin
            js/
                JS files
            images/
                Images for my plugin
            lang/
                Translation files
        plugin.php 
            This is the main file that calls/includes other files 
        README 
            I normally put the license details in here in addition to helpful information 

Todavía tengo que crear un complemento de WordPress que requiera una arquitectura de estilo MVC, pero si tuviera que hacer esto, lo establecería con un directorio MVC separado, que a su vez contiene vistas / controladores / modelos.

    
respondido por el mystline 13.04.2012 - 08:02
4

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

controller/
    frontend.php
    wp-admin.php
    widget1.php
    widget2.php
model/
    standard-wp-tables.php // if needed split it up
    custom-tabel1.php
    custom-tabel2.php
view/
    helper.php
    frontend/
        files...php
    wp-admin/
        files...php
    widget1/
        file...php
    widget2/
        file...php
css/
js/
image/
library/  //php only, mostly for Zend Framework, again if needed
constants.php //tend to use it often
plugin.php //init file
install-unistall.php  //only on big plugins
    
respondido por el janw 18.04.2012 - 14:20
3

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

plugin-folder/
    admin/
        css/
            images/
        js/
    core/
    css/
        images/
    js/
    languages/
    library/
    templates/
    plugin-folder.php
    readme.txt
    changelog.txt
    license.txt

plugin-folder.php generalmente es una clase que carga todos los archivos requeridos desde el núcleo / carpeta. Más a menudo en el gancho init o plugins_loaded.

También solía prefijar todos mis archivos, pero como @kaiser señaló anteriormente, es realmente redundante y recientemente he decidido eliminarlo de cualquier complemento futuro.

La biblioteca / carpeta contiene todas las bibliotecas auxiliares externas de las que podría depender el complemento.

Dependiendo del complemento, también podría haber un archivo uninstall.php en la raíz del complemento. Sin embargo, la mayoría de las veces esto se maneja a través de register_uninstall_hook ().

Obviamente, es posible que algunos complementos no requieran archivos o plantillas de administrador, etc., pero la estructura anterior funciona para mí. Al final, solo tienes que encontrar una estructura que funcione para ti y luego seguir con ella.

También tengo un complemento de inicio, basado en la estructura anterior que utilizo como punto de partida para todos mis complementos. Todo lo que necesito hacer es hacer una búsqueda / reemplazo de prefijos de función / clase y listo. Cuando aún estaba prefijando mis archivos, era un paso adicional que tenía que hacer (y me molestaba bastante), pero ahora solo tengo que cambiar el nombre de la carpeta de complementos y el archivo de complementos principal.

    
respondido por el shabushabu 13.04.2012 - 12:28
1

También, vea esta excelente plantilla de widgets de WP . Brinda excelentes sugerencias sobre estructuras (incluso si no hay una clase ni una carpeta para modelos separados).

    
respondido por el Cedric 17.06.2013 - 10:42
0

Un enfoque menos común para estructurar los archivos y directorios de un complemento es el enfoque de tipo de archivo. Vale la pena mencionar aquí para completar:

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 archivos de ese tipo solamente. Vale la pena señalar que este enfoque se queda corto cuando tiene muchos tipos de archivos .png .gif .jpg que podrían archivarse de manera más lógica en un solo directorio, por ejemplo, images/ .

    
respondido por el henrywright 08.11.2015 - 00:40

Lea otras preguntas en las etiquetas