Comment structurer un plugin

41

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 à 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 assemblés de la manière que leur auteur détermine.

Il n’ya pas de bonne réponse , mais j’espère pouvoir préciser comment, ainsi que 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 efficaces.

La dernière question: quel est selon vous 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 de 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 contrôleur contiendrait des balises de modèle et des fonctions que la vue utiliserait.
  • La vue est responsable de l'affichage des 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 l' API de plug-in , les normes de codage et les 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
développés
la source
Ce n'est pas une vraie question, mais je ne vais pas fermer le vote, mais en faire un wiki de la communauté. Btw: Je pense que cela n'a aucun sens de perfixer les noms de fichiers.
Kaiser
Merci, je préférerais de toute façon que ce soit un wiki de communauté. Je ne pense pas que préfixer les fichiers de cette façon ait beaucoup de sens non plus, mais je l'ai souvent vu.
developdaly
1
Un autre point côté: Peut-être que des noms plus sémantiquement correct pour les dossiers css/, images/et js/serait styles/, images/et scripts/.
Andrew Odri

Réponses:

16

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

Cela dépend de ce que le plugin 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.

onetrickpony
la source
6

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

Ce serait quelque chose qui irait dans le libdossier.

Si c'est un plugin particulièrement complexe, avec de nombreuses fonctionnalités de la zone d'administration, j'ajouterais un admindossier contenant tous ces fichiers PHP. Si le plugin remplace , par exemple , les fichiers de thème inclus , il peut également y avoir un dossier templateou 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
chrisguitarguy
la source
Souhaitez-vous également inclure les fichiers css et js de l'administrateur dans le dossier / admin? Vous avez donc un autre / css et / js dans / admin?
urok93
6

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 (je suis cependant un peu biaisé ...). 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 du 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:

À M
la source
5

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 en raison du mécanisme de chargement automatique.

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 webeo-core.phpfichier 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 Webeo_CoreLoaderclasse 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 Core.phpclasse dans le lib/Webeodossier. Cela fonctionne sur le plugins_loadedcrochet d’action avec une priorité de 9.
  4. La Core.phpclasse 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 libdossier 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 Mail Settingsformulaire d'administration, 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 la classe boostrap des plugins E.g. Faq.phpen priorité 10dans le plugins_loadedhook.

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 libdossier vendorset déplacer tous les dossiers publics (css, images, js, langues) dans un dossier nommé publicdans la prochaine version.

rofflox
la source
5

Comme beaucoup de personnes ici déjà répondues Cela dépend vraiment de 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
Bainternet
la source
4

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, des contrôleurs et des modèles.

mystline
la source
4

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
Janw
la source
3

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 @kaiser l'a noté plus haut, 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.

Shabushabu
la source
1

Aussi, voir ce grand widget de Wp chauds . 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).

Cedric
la source
0

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 des nombreux types de fichiers .png .gif .jpgpouvant être classés de manière plus logique dans un seul répertoire, images/par exemple.

écrivain
la source