web-dev-qa-db-fra.com

Comment structurer un plugin

Ce n'est pas une question sur la façon de construire un plugin WordPress. Quels guides, le cas échéant, pourraient être appliqués sur la manière de mettre en place l'architecture de fichier d'un plugin.

Certains autres langages de programmation ou bibliothèques ont des méthodes très contrôlées d’organisation des répertoires et des fichiers. Parfois, cela est agaçant et met en évidence la liberté offerte par PHP, mais du côté opposé, les plugins WordPress sont mis en place de la manière que leur auteur détermine.

Il n'y a pas de bonne réponse}, mais mon espoir est de préciser comment, moi et d'autres, construisons des plugins pour les rendre plus conviviaux pour les autres développeurs, plus faciles à déboguer, plus faciles à naviguer, et peut-être plus efficace.

La dernière question: qu’est-ce que vous pensez être le meilleur moyen d’organiser un plugin?

Vous trouverez ci-dessous quelques exemples de structures, mais en aucun cas une liste exhaustive. N'hésitez pas à ajouter vos propres recommandations.

Structure supposée par défaut

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

Méthode du contrôleur de vue modèle (MVC)

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

Les trois parties de MVC:

  • Le modèle interagit avec la base de données, interroge et enregistre des données, et contient une logique.
  • Le controller contiendrait les balises de modèle et les fonctions que la vue utiliserait.
  • Le view est chargé d’afficher les données fournies par le modèle tel que construit par le contrôleur.

Organisé par type de méthode

  • /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 sur Github

Basé sur le Plugin API , Normes de codage et Normes de documentation .

  • /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éthode mal organisée

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

Notez que les plugins sont tous des "contrôleurs" selon les standards WP.

Cela dépend de ce que le plug-in est censé faire, mais dans tous les cas, j'essayerais de séparer autant que possible la sortie de l'écran du code PHP.

Voici une façon de le faire facilement. Commencez par définir une fonction qui charge le modèle:

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;
}

Maintenant, si le plugin utilise un widget pour afficher des données:

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;
  }
  ...

}

Le gabarit:

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

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

<?php endwhile; ?>

Des dossiers:

/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

Où mettez-vous votre CSS, JS, images, ou comment concevez-vous le conteneur pour les crochets est moins important. Je suppose que c'est une question de préférence personnelle.

16
onetrickpony

IMHO, la route la plus facile, la plus puissante et la plus facile à maintenir consiste à utiliser une structure MVC, et WP MVC est conçu pour rendre l'écriture de plugins MVC très facile (cependant, je suis un peu partial) ... . Avec WP MVC, vous créez simplement les modèles, les vues et les contrôleurs, et tout le reste est géré en arrière-plan pour vous.

Des contrôleurs et des vues distincts peuvent être créés pour les sections public et admin, et l'ensemble de la structure tire parti de nombreuses fonctionnalités natives de WordPress. La structure de fichier et la plupart des fonctionnalités sont exactement les mêmes que dans les frameworks MVC les plus populaires (Rails, CakePHP, etc.).

Plus d'informations et un tutoriel peuvent être trouvés ici:

6
Tom

Cela dépend du plugin. Ceci est ma structure de base pour presque chaque plugin:

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

Ceci serait quelque chose qui irait dans le dossier lib.

Si c'est un plugin particulièrement complexe, avec de nombreuses fonctionnalités de la zone d'administration, j'ajouterais un dossier admin pour contenir tous ces fichiers PHP. Si le plug-in effectue quelque chose comme remplacer les fichiers de thème inclus , il existe peut-être également un dossier template ou theme.

Ainsi, une structure de répertoire pourrait ressembler à ceci:

my-plugin/
    inc/
    lib/
    admin/
    templates/
    css/
    js/
    images/
    lang/
    my-plugin.php
    readme.txt
6
chrisguitarguy

Comme beaucoup d’entre eux ont déjà répondu Cela dépend vraiment dépendde ce que le plugin est censé faire, mais voici ma structure de 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
5
Bainternet

Nous utilisons un mélange de toutes les méthodes. Tout d'abord, nous utilisons le Zend Framework 1.11 dans nos plugins et nous avons donc dû utiliser une structure similaire pour les fichiers de classe à cause du mécanisme d'autoload.

La structure de notre plugin principal (qui est utilisé par tous nos plugins comme base) ressemble à ceci:

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 appelle le fichier webeo-core.php dans le dossier racine du plugin.
  2. Dans ce fichier, nous allons définir le chemin d’inclusion PHP et enregistrer les points d’activation et de désactivation du plug-in.
  3. Nous avons également une classe Webeo_CoreLoader dans ce fichier, qui définit certaines constantes de plug-in, initialise l'autoloader de la classe et appelle la méthode d'installation de la classe Core.php dans le dossier lib/Webeo. Ceci s’exécute sur le hook d’action plugins_loaded avec une priorité de 9.
  4. La classe Core.php est notre fichier d'amorçage de plugin. Le nom est basé sur le nom du plugin.

Comme vous pouvez le constater, nous avons un sous-répertoire dans le dossier lib pour tous nos packages de fournisseurs (Webeo, Zend). Tous les sous-packages d'un fournisseur sont structurés par le module lui-même. Pour un nouveau formulaire d'administration Mail Settings, nous aurions la structure suivante:

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

Nos sous-plugins ont la même structure à une exception près. Nous allons plus loin dans le dossier du fournisseur en raison de la résolution des conflits de noms lors de l'événement de chargement automatique. Nous appelons également les plugins boostrap classe E.g. Faq.php à la priorité 10 à l'intérieur du hook 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

Je vais probablement renommer le dossier lib en vendors et déplacer tous les dossiers publics (css, images, js, langues) dans un dossier nommé public dans la prochaine version.

5
rofflox

Ma logique, plus le plugin est gros, plus je prends de structure.
Pour les gros plugins, j’ai tendance à utiliser MVC.
J'utilise cela comme point de départ et évite ce qui n'est pas nécessaire.

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
4
janw

Je suis partisan de la disposition suivante du plugin, mais cela change généralement en fonction des exigences du plugin.

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 

Je n'ai pas encore créé de plug-in WordPress nécessitant une architecture de style MVC, mais si je devais le faire, je le disposerais dans un répertoire MVC séparé, qui contient lui-même des vues/contrôleurs/modèles.

4
mystline

Tous mes plugins suivent cette structure, qui semble être très similaire à celle de la plupart des autres développeurs:

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 est alors généralement une classe qui charge tous les fichiers requis à partir du dossier core /. Le plus souvent sur le crochet init ou plugins_loaded.

J'avais aussi l'habitude de préfixer tous mes fichiers, mais comme l'a noté @kaiser ci-dessus, c'est vraiment redondant et j'ai récemment décidé de le supprimer de tous les futurs plugins.

La bibliothèque/dossier contient toutes les bibliothèques auxiliaires externes sur lesquelles le plugin pourrait dépendre.

Selon le plugin, il peut également y avoir un fichier uninstall.php à la racine du plugin. La plupart du temps, cela est géré via register_uninstall_hook (), cependant.

Évidemment, certains plugins peuvent ne pas nécessiter de fichiers d’administrateur, de modèles, etc., mais la structure ci-dessus fonctionne pour moi. En fin de compte, vous devez simplement trouver une structure qui fonctionne pour vous, puis vous y tenir.

J'ai également un plugin de démarrage, basé sur la structure ci-dessus, que j'utilise comme point de départ pour tous mes plugins. Tout ce que j'ai à faire est alors de faire une recherche/remplacement pour les préfixes de fonction/classe et c'est parti. Quand je préfixais encore mes fichiers, c’était une étape supplémentaire que je devais faire (et assez ennuyeux à cela), mais maintenant je dois juste renommer le dossier du plugin et le fichier de plugin principal.

3
shabushabu

Aussi, voyez ce superbe WP widget "warmplate" . Cela donne d'excellentes indications quant aux structures (même s'il n'y a pas de classe ni de dossier pour des modèles séparés).

1
Cedric

L'approche par type de fichier est une approche moins commune pour structurer les fichiers et les répertoires d'un plug-in. Il convient de mentionner ici pour être complet:

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

Chaque répertoire contient des fichiers de ce type uniquement. Il convient de noter que cette approche ne tient pas compte de plusieurs types de fichiers .png .gif .jpg qui pourraient être classés de manière plus logique dans un seul répertoire, par exemple images/.

0
henrywright