Objectif Meilleures pratiques pour le développement de plugins? [fermé]

135

Lancer un wiki de communauté pour rassembler les meilleures pratiques objectives pour le développement de plugins. Cette question a été inspirée par les commentaires de @ EAMann sur les wp-hackers .

L'idée est de collaborer sur ce que pourraient être les meilleures pratiques objectives afin que nous puissions éventuellement les utiliser dans le cadre d'un processus d'examen de la collaboration avec la communauté.

MISE À JOUR: Après avoir vu les premières réponses, il devient clair que nous n'avons besoin que d'une idée / suggestion / meilleure pratique par réponse et les personnes doivent consulter la liste pour s'assurer qu'il n'y a pas de doublons avant la publication.

MikeSchinkel
la source
Je ne comprends vraiment pas comment le wiki de la communauté devrait fonctionner correctement sur ce problème (et sur les autres) avec SE, mais c'est peut-être une question de méta. Cela ne fera qu'empiler des dupes dans les réponses.
hakre
@hakre: excellent point. Après avoir vu quelque chose, je vais ajouter à la description que les gens ne devraient ajouter qu'une idée par "réponse" et que je vais changer ma réponse existante en plusieurs réponses.
MikeSchinkel

Réponses:

72

Utiliser des actions et des filtres

Si vous pensez que les gens aimeraient ajouter ou modifier des données: fournissez apply_filters () avant de retourner .

PS Une chose que je trouve un peu décevante et que répond à votre question est le pourcentage de plugins conçus uniquement pour les utilisateurs finaux, c’est-à-dire qui ne possèdent pas de crochets propres. Imaginez si WordPress était conçu comme la plupart des plugins? Ce serait inflexible et une solution très niche.

Peut-être que les choses seraient différentes si WordPress était capable d'auto-installer des plugins sur lesquels d'autres plugins dépendaient? En général, je dois écrire de nombreuses fonctionnalités dont j'ai besoin, car les clients veulent certaines choses et que les plugins disponibles, même s'ils sont à 90%, ne me permettent pas de mettre à jour les 10% restants.

Je souhaite vraiment que ceux qui dirigent la communauté WordPress identifient un moyen de s'assurer que les plugins sont récompensés pour suivre les meilleures pratiques (telles que l'ajout de points d'ancrage pour les autres développeurs), tout comme les bonnes réponses sont récompensées sur un site StackExchange.

Prenons un exemple d' une autre question :

Exemple: je veux faire quelque chose dans mon plugin quand quelqu'un retweet un article. S'il existait un point d'ancrage personnalisé dans le plug-in Retweet populaire auquel je pouvais m'arranger, ce serait génial. Donc, je peux modifier leur plugin pour l'inclure, mais cela ne fonctionne que pour ma copie, et je ne veux pas essayer de le redistribuer.

Apparenté, relié, connexe

Arlen Beiler
la source
55

Charger des scripts / CSS avec wp_enqueue_scriptetwp_enqueue_style

Les plug-in ne doivent pas charger / tenter de charger des versions en double de fichiers JS / CSS, en particulier jQuery et d'autres fichiers JS inclus dans WP Core.

Les plugins doivent toujours utiliser wp_enqueue_scriptet wp_enqueue_stylelors de la liaison de fichiers JS et CSS et jamais directement via des <script>balises.

Apparenté, relié, connexe

hakre
la source
1
Suggestion : Peut-être vaut-il mieux coller une petite note sur l’utilisation des dépendances dans cet environnement (car cela fait partie du système de mise en file d’attente).
T31os
C'est vrai, mais mieux vaut enregistrer les styles et les scripts avant, puis les mettre en file d'attente via un ID. C'est très bien pour les autres développeurs de changer les scripts ou de l'utiliser dans des plugins personnalisés. Il est également plus facile de modifier l’ordre ou de créer un fichier de résumé.
Bueltge
2
plus, chargez les scripts et les styles sur les pages, le cas échéant. scribu.net/wordpress/optimal-script-loading.html
MR
49

I18n soutien

Toutes les chaînes de sortie doivent être liées à un domaine de texte approprié pour permettre l’internationalisation par les parties intéressées, même si le développeur n’a aucun intérêt à traduire son propre plug-in.

Notez qu'il est très important de charger les fichiers de langue pendant l' initaction pour que l'utilisateur puisse s'y connecter.

Voir le Codex: I18n pour les développeurs WordPress

Et aussi cet article: Chargement des fichiers de langue WP correctement .

Depuis WordPress 4.6+

WP 4.6 a modifié l’ordre de chargement et les emplacements vérifiés, ce qui a grandement facilité la tâche des développeurs et des utilisateurs.

Considérant un plugin avec un textdomain 'my-plugin', WordPress va maintenant rechercher un fichier de traduction dans:
/wp-content/languages/plugins/my-plugin-en_US.mo

S'il ne parvient pas à en trouver un ici, il en recherchera un pour lequel le plug-in lui dit de regarder (habituellement dans le dossier 'language' des pluigns si vous suivez le codex):
/ wp-content / plugins / my-plugin / languages ​​/ my- plugin-en_US.mo

Enfin, si aucun fichier de langue n’est trouvé, il vérifiera l’emplacement par défaut de:
/wp-content/languages/my-plugin-en_US.mo

La première vérification a été ajoutée en 4.6 et donne aux utilisateurs un emplacement défini pour ajouter un fichier de langue, car ils devaient auparavant savoir où le développeur avait ajouté le fichier de langue. Désormais, l'utilisateur doit simplement connaître le domaine textuel du plugin: / wp-content / languages ​​/ plugins / TEXTDOMAIN-LOCAL.mo


Ci-dessous l'ancienne méthode (non pertinent depuis le WP 4.6+)

[...]
Enfin, je voudrais souligner qu'il est important de charger les fichiers de langue utilisateur personnalisés à partir de WP_LANG_DIR avant de charger les fichiers de langue fournis avec le plug-in . Lorsque plusieurs fichiers mo sont chargés pour le même domaine, la première traduction trouvée sera utilisée. De cette façon, les fichiers de langue fournis par le plugin serviront de solution de secours pour les chaînes non traduites par l'utilisateur.

public function load_plugin_textdomain()
{
    $domain = 'my-plugin';
    // The "plugin_locale" filter is also used in load_plugin_textdomain()
    $locale = apply_filters( 'plugin_locale', get_locale(), $domain );

    load_textdomain( 
            $domain, 
            WP_LANG_DIR . '/my-plugin/' . $domain . '-' . $locale . '.mo' 
    );
    load_plugin_textdomain( 
            $domain, 
            FALSE, 
            dirname( plugin_basename(__FILE__) ) . '/languages/' 
    );
}
Stiofan O'Connor
la source
Pour moi le plus important. Cela ne représente pas beaucoup de travail supplémentaire mais une des choses que vous pouvez rendre votre plugin plus utile pour les millions d’utilisateurs qui ne parlent pas anglais comme première langue. Vous n'avez même pas à traduire vous-même un mot, mais à tout préparer.
2ndkauboy
C'est une chose tellement précieuse, mais facile à faire, je voulais juste dire que je suis d'accord et que chaque auteur de plug-in devrait le faire.
T31os
48

Assurez-vous que les plugins ne génèrent aucune erreur avec WP_DEBUG

Testez toujours vos plugins avec WP_DEBUGactivé et idéalement, activez-le tout au long de votre processus de développement. Un plugin ne devrait lancer AUCUNE erreur avec WP_DEBUG. Cela inclut les avis obsolètes et les index non vérifiés.

Pour activer le débogage, modifiez votre wp-config.phpfichier de sorte que la WP_DEBUGconstante soit définie sur true. Voir le Codex sur le débogage pour plus de détails.

John P Bloch
la source
S'il vous plaît voir la mise à jour sur le fait d'avoir seulement les meilleures pratiques par réponse; pouvez-vous diviser en plusieurs réponses?
MikeSchinkel
Bien sûr pas de problème. Désolé pour ça.
John P Bloch
Merci et ce n'était pas votre oubli, c'était le mien. J'ai révisé la question pour demander une meilleure pratique par réponse sur la base de la question de @ hakre sur les doublons et sur la manière de faire en sorte que cela fonctionne.
MikeSchinkel
6
Si je pouvais voter cette réponse deux fois, je le ferais. C'est tellement frustrant de travailler sur un site de développement et de devoir désactiver WP_DEBUG, car un plug-in que je dois utiliser diffuse des avertissements et des avis partout.
Ian Dunn
42

Première utilisation des fonctions existantes dans WordPress Core

Si vous le pouvez: utilisez les fonctions existantes incluses dans WordPress Core au lieu d’écrire les vôtres. Ne développez des fonctions PHP personnalisées que lorsqu'il n'existe pas de fonction préexistante appropriée dans le noyau WordPress.

Un des avantages est que vous pouvez utiliser des "avis obsolètes" pour contrôler facilement les fonctions à remplacer. Un autre avantage est que les utilisateurs peuvent consulter la documentation sur les fonctions dans le Codex et mieux comprendre ce que fait le plug-in, même s'ils ne sont pas des développeurs PHP expérimentés.

Apparenté, relié, connexe

hakre
la source
L’un des plus gros problèmes est d’apprendre qu’il existe une fonction appropriée. Ce qui serait utile serait un endroit où publier du code et / ou des fonctionnalités pour permettre à la communauté de commenter quelle fonction utiliser au mieux. Peut-être que StackExchange pourrait être utilisé pour cela?
MikeSchinkel
Puh. Ce serait assez difficile et je suppose une sorte de tâche sans fin. Je pense qu'il serait préférable de prolonger le codex de cette manière, car il existe déjà.
Kaiser
J'imagine que l'extension du codex et la création de liens à partir de là vers des threads d'échange de titres connexes seraient suffisantes.
Kaiser
4
Un problème avec cela est que beaucoup de noyau n'est pas vraiment conçu structurellement pour être réutilisé. Il me suffisait de copier et de modifier légèrement la moitié des fonctions de manipulation / métadonnées d'images pour créer mon propre type de pièce jointe se comportant après le type, simplement parce qu'une fonction comme downsize () appelle une fonction qui inclut un contrôle codé pour l'attachement de post-type = ' '. Il y a beaucoup de cela comme l'inflexible wp_count_posts () étant un autre exemple. Avant de pouvoir réellement réutiliser le noyau WP, il faut un refactoring complet.
Wyrfel
Complètement d'accord sur ce sujet. Mon exemple préféré de tous les temps: wp-login.php. Donc, "Si vous pouvez" était un bon débutant pour la réponse ...
kaiser
35

La désinstallation devrait supprimer toutes les données d'un plugin

Lorsqu'il est supprimé d'une installation WordPress, un plug-in doit supprimer tous les fichiers, dossiers, entrées de base de données et tables qu'il a créées, ainsi que les valeurs d'option créées.

Les plugins peuvent offrir une option pour exporter / importer les paramètres, afin que les paramètres puissent être enregistrés en dehors de WordPress avant la suppression.

Apparenté, relié, connexe

hakre
la source
4
Cela devrait être le comportement par défaut, oui, mais il devrait également inviter l'utilisateur à conserver certaines données ... comme lors de la désinstallation d'un jeu vidéo, il vous demande si vous souhaitez supprimer les jeux sauvegardés et le contenu téléchargé. Un utilisateur peut ne désactiver le plug-in qu'à des fins de test et ne souhaite pas revenir en arrière lors de la configuration de ses options lorsqu'il le réactivera.
EAMann
1
Je parle seulement du moment où un plugin est complètement supprimé, pas quand il est désactivé.
Travis Northcutt
2
Je comprends cela ... mais parfois je supprime des plug-ins pour pouvoir les rajouter manuellement à partir d'une version de sauvegarde ou d'une version bêta qui n'est pas encore hébergée dans le référentiel ...
EAMann
4
@EAMann: Pour cela et pour migrer des plugins vers un autre serveur, un plugin devrait fournir un mécanisme pour exporter et importer les paramètres.
hakre
2
J'ai vu quelques plugins offrir un bouton "Désinstaller" dans leurs paramètres avec de grands avertissements rouges, il va supprimer toutes les données. Ceci est distinct de la désactivation, et je pense un excellent moyen de le gérer. Tout le monde n'utilise pas le bouton "Supprimer" pour supprimer un plugin.
gabrielk
34

Empêcher l'injection SQL avec les données d'entrée

Un plugin doit supprimer toutes les entrées utilisateur récupérées directement ou indirectement (par exemple via $_POSTou$_GET ) avant d'utiliser des valeurs d'entrée pour interroger la base de données MySQL.

Voir: Formatage des instructions SQL .

hakre
la source
5
Vous devez également désinfectez les données provenant des de la base de données. Fondamentalement, ne faites jamais confiance à des données qui ne sont pas codées en dur. codex.wordpress.org/Data_Validation est également une bonne référence.
Ian Dunn
31

Préfixer tous les éléments d'espace de noms globaux

Un plugin doit correctement préfixer TOUS les éléments d’espace de noms globaux (constantes, fonctions, classes, variables, voire des éléments tels que les taxonomies personnalisées, les types de publication, les widgets, etc.). Par exemple, ne créez pas une fonction appelée init(); nommez-le plutôt jpb_init().

Son point commun devrait utiliser un préfixe de trois ou quatre lettres devant les noms ou utiliser la fonctionnalité PHP Namespace . Comparez: Préfixe à une lettre pour les constantes de classe PHP?

Apparenté, relié, connexe

hakre
la source
31

Utiliser un code PHP5 orienté objet et classe

Il n'y a aucune raison de ne pas écrire du code PHP5 propre et orienté objet. Le support de PHP4 disparaîtra après la prochaine version (WP 3.1). Bien sûr, vous pouvez préfixer tous les noms de fonctions de manière à ce qu'ils finissent par interminly_long_function_names_with_lots_of_underscores, mais il est beaucoup plus facile d'écrire une simple classe et de regrouper tout le contenu. En outre, placez votre classe dans un fichier séparé et nommez-la en conséquence pour pouvoir l'étendre et la maintenir facilement:

// in functions.php
require 'inc/class-my-cool-plugin.php';
new MyCoolPlugin();

// in inc/class-my-cool-plugin.php
class MyCoolPlugin {
    function __construct() {
        // add filter hooks, wp_enqueue_script, etc.

        // To assign a method from your class to a WP 
        // function do something like this
        add_action('admin_menu', array($this, "admin"));
    }

    public function admin() {
        // public methods, for use outside of the class
        // Note that methods used in other WP functions 
        // (such as add_action) should be public
    }

    private function somethingelse() {
        // methods you only use inside this class
    }
}
Rauque
la source
n'utilisez pas new MyCoolPlugin (); Je pense qu'il vaut mieux accrocher WP via Hook: plugins_loaded
bueltge
Pas sûr de ça. Selon le codex plugins_loaded est l’une des toutes premières choses chargées, je pense donc que faire une construction comme celle-ci ou l’ajouter à une action ne fait guère de différence.
Husky
5
Ce n'est qu'une de ces pratiques exemplaires qui rend les choses plus agréables pour tout le monde.
Arlen Beiler
1
Autant que je sache, ajouter un hook dans plugins_loaded n'apporte aucune amélioration, et ce ne serait pas une bonne pratique, car il n'y a pas d'amélioration, s'il y a augmentation de l'utilisation de la mémoire, diminution de la vitesse car elle doit passer à l'action. au lieu des actions en cours d’ajout. De plus, utiliser OO ne devrait pas être considéré comme une pratique exemplaire.
Backie
4
@IanDunn: si vous voulez un support PHP4, mais le support PHP4 a été abandonné depuis 2008, il y a plus de 4 ans. Il n'y a aucune raison d'utiliser encore des contrôles spécifiques à PHP4.
Husky
23

Incluez uniquement les fichiers dont vous avez besoin ...

Si vous êtes au début, n'incluez pas de code lié à la zone d'administration.

Denis de Bernardy
la source
21

Annonce de Data-Loss lors de la désinstallation d'un plugin

Lors de la désinstallation, un plug-in doit inviter l'utilisateur à supprimer ses données et à recevoir une confirmation confirmant que l'utilisateur accepte de supprimer les données avant de le faire. Un plug-in doit également permettre à l'utilisateur de conserver les données lors de la désinstallation. (Cette idée de @EAMann.)

Apparenté, relié, connexe

hakre
la source
3
Wordpress lui-même affiche un message d'avertissement dans l'administrateur, indiquant que cela se produit (au moins dans le coffre actuellement).
hakre
Outre le message d'avertissement affiché par WordPress, il est impossible pour le plug-in d'inviter l'utilisateur car, au moment de la désinstallation, il est déjà désactivé. Mais voir le billet # 20578 .
JD
19

Que le nom du dossier du plugin soit changé

/ plugins / pluginname / {divers}

Le "pluginname" utilisé pour le dossier devrait toujours être modifiable.

Ceci est normalement géré en définissant les constantes et en les utilisant systématiquement dans le plugin.

Inutile de dire que beaucoup de plugins populaires sont des pécheurs.

Apparenté, relié, connexe:

  • plugins_url() pour un lien facile aux ressources, inclus avec le plugin.
AndyBeard
la source
Renommer le dossier du plug-in entraînera la rupture des mises à jour automatisées. Je ne suis donc pas sûr que ce soit la meilleure chose à faire.
Mtekk
De toute façon, vous devrez réactiver le plug-in après avoir effectué le changement (le changement de nom entraînerait probablement la désactivation du plug-in). casser les mises à jour du tout).
T31os
Au lieu d'utiliser une constante, utilisez plugin_basename(__FILE__)pour déterminer le nom local du plugin. Cela est utile pour avoir des copies du même plugin (test, plusieurs comptes ailleurs mais seulement un par plugin, ...).
Raphaël
19

Utiliser WordPress (intégré) Traitement des erreurs

Ne vous contentez pas return;si une entrée utilisateur était fausse. Livrez-leur des informations sur a été fait mal.

function some_example_fn( $args = array() ) 
{
    // If value was not set, build an error message
    if ( ! isset( $args['some_value'] ) )
        $error = new WP_Error( 'some_value', sprintf( __( 'You have forgotten to specify the %1$s for your function. %2$s Error triggered inside %3$s on line %4$s.', TEXTDOMAIN ), '$args[\'some_value\']', "\n", __FILE__, __LINE__ ) );

    // die & print error message & code - for admins only!
    if ( isset( $error ) && is_wp_error( $error ) && current_user_can( 'manage_options' ) ) 
        wp_die( $error->get_error_code(), 'Theme Error: Missing Argument' );

    // Elseif no error was triggered continue...
}

Une erreur (objet) pour tous

Vous pouvez configurer un objet d'erreur globale pour votre thème ou votre plugin pendant l'amorçage:

function bootstrap_the_theme()
{
    global $prefix_error, $prefix_theme_name;
    // Take the theme name as error ID:
    $theme_data = wp_get_theme();
    $prefix_theme_name = $theme_data->Name;
    $prefix_error = new WP_Error( $theme_data->Name );

    include // whatever, etc...
}
add_action( 'after_setup_theme', 'bootstrap_the_theme' );

Plus tard, vous pourrez ajouter un nombre illimité d’erreurs à la demande:

function some_theme_fn( $args )
{
    global $prefix_error, $prefix_theme_name;
    $theme_data = wp_get_theme();
    if ( ! $args['whatever'] && current_user_can( 'manage_options' ) ) // some required value not set
        $prefix_error->add( $prefix_theme_name, sprintf( 'The function %1$s needs the argument %2$s set.', __FUNCTION__, '$args[\'whatever\']' ) );

    // continue function...
}

Ensuite, vous pouvez tous les récupérer à la fin de votre thème. De cette façon, vous n'interrompez pas le rendu de la page et pouvez toujours afficher toutes vos erreurs pour le développement.

function dump_theme_errors()
{
    global $prefix_error, $prefix_theme_name;

    // Not an admin? OR: No error(s)?
    if ( ! current_user_can( 'manage_options' ) ! is_wp_error( $prefix_error ) )
        return;

    $theme_errors = $prefix_error->get_error_messages( $prefix_theme_name );
    echo '<h3>Theme Errors</h3>';
    foreach ( $theme_errors as $error )
        echo "{$error}\n";
}
add_action( 'shutdown', 'dump_theme_errors' );

Vous trouverez de plus amples informations à ce Q . Un ticket associé pour résoudre le "travail ensemble" de WP_Erroret wp_die()est lié à partir de là et un autre ticket suivra. Les commentaires, critiques et autres sont appréciés.

kaiser
la source
Pourquoi instanciez-vous un objet WP_Error si vous accédez uniquement à ses propriétés et ne transmettez jamais l'instance en tant qu'objet?
ProfK
@ProfK Je l'ai retravaillé pour être plus court et le titre / contenu pour wp_die();était incorrect (inversé). A propos de votre Q) Je ne comprends pas tout à fait. Lorsque vous configurez une instance de la classe WP_Error vous avez accès à ses données grâce à des fonctions telles que get_error_code();, get_error_message();, get_error_data();et les versions plurielles. Vous pouvez également l'instancier une seule fois au démarrage de votre thème ou de votre plug-in et simplement l'utiliser $error->add();pour corriger d'autres erreurs et enfin l'afficher dans le pied de page avec $error->get_error_messages();toutes les erreurs .
Kaiser
@ProfK Je posterai les futures mises à jour de ce Q . J'inspecte actuellement le comportement de la classe d'erreur wp et souhaite rédiger un ticket concernant une API d'erreur de thème public (brouillon déjà effectué). Vous trouverez un lien vers un autre ticket qui se rapproche WP_Erroret se wp_die()rapproche (possède déjà un patch) au bas de la Q. Tous les commentaires, suggestions, critiques et autres sont très appréciés.
Kaiser
18

Réduire les noms ajoutés à l'espace de noms global

Un plugin devrait réduire son impact autant que possible en minimisant le nombre de noms qu'il ajoute à l'espace de noms global .

Cela peut être fait en encapsulant les fonctions du plugin dans une classe ou en utilisant la fonction d'espaces de nommage PHP . Tout préfixer peut aussi aider mais n'est pas si flexible.

A côté des fonctions et des classes, un plugin ne doit pas introduire de variables globales. Utiliser des classes les obsolète normalement et cela simplifie la maintenance des plugins.

Apparenté, relié, connexe

hakre
la source
Pouvez-vous s'il vous plaît déplacer le "ne devrait pas introduire des variables globales" à sa propre réponse? Cela est lié séparément de cette question et en fait une question sur laquelle j'aimerais débattre (à la fois parce que je pense que je ne suis peut-être pas d'accord avec ce que je pense, ce sont des cas particuliers et parce que je veux apprendre des opinions des autres.)
MikeSchinkel
17

Commenter avec PhpDoc

La meilleure pratique est proche du style PhpDoc. Si vous n'utilisez pas d'IDE comme "Eclipse", vous pouvez simplement consulter le manuel de PhpDoc .

Vous n'avez pas besoin de savoir exactement comment cela fonctionne. Les développeurs professionnels peuvent quand même lire le code et en ont besoin comme résumé. Les codeurs amateurs et les utilisateurs peuvent apprécier la façon dont vous l'expliquez au même niveau de connaissance.

kaiser
la source
17

Utiliser l'API Settings avant add_option

Au lieu d'ajouter des options à la base de données via la fonction add_option, vous devez les stocker sous forme de tableau avec l'aide de l' API de configuration qui s'occupe de tout pour vous.

Utiliser l'API de modification de thème avant add_option

L' API de modification est une construction assez simple et un moyen sûr qui permet d'ajouter et de récupérer des options. Tout est enregistré en tant que valeur sérialisée dans votre base de données. Facile, sûr et simple.

kaiser
la source
1
Et de plus, utilisez update_optionet jamais add_option, la fonction de mise à jour créera l'option lorsqu'elle n'existe pas .. :)
t31os
3
Je ne dirais jamais ne jamais utiliser add_option. Il existe un bon cas d'utilisation dans add_optionlequel, si l'option est déjà définie, elle n'est pas modifiée. Je l'utilise donc lors de l'activation pour conserver les préférences utilisateur déjà existantes.
ProfK
1
Un autre cas d'utilisation add_optionest lorsque vous souhaitez explicitement désactiver le chargement automatique. update_optionforcera automatiquement le chargement automatique à true, vous voulez donc désactiver le chargement automatique, à utiliser add_optionlors de la création initiale de l'option.
Dave Romsey
16

Protéger la confidentialité des utilisateurs du plugin

(Auparavant: Communication anonyme avec l'API)

Si un plug-in communique avec un système externe ou une API (par exemple, un Webservice), il doit le faire de manière anonyme ou fournir à l'utilisateur une option anonyme garantissant qu'aucune donnée liée à l'utilisateur du plug-in ne fuit à une deuxième partie sans contrôle.

EAMann
la source
15

Plugins hôtes sur WordPress.org

Utilisez le référentiel SVN fourni sur WordPress.org pour héberger des plugins. Cela facilite la mise à jour de l'expérience utilisateur et, si vous n'avez jamais utilisé SVN auparavant, vous comprendrez vraiment en l'utilisant dans un contexte qui le justifie.

MikeSchinkel
la source
15

Fournir un contrôle d'accès à l'aide d'autorisations

Dans de nombreux cas, les utilisateurs ne souhaitent peut-être pas que tout le monde ait accès aux zones créées par votre plug-in, en particulier dans le cas de plug-ins effectuant plusieurs opérations complexes. Une vérification de la fonctionnalité codée en dur peut s'avérer insuffisante.

Ayez au minimum des contrôles de capacité appropriés pour tous les types de procédures pour lesquels votre plugin peut être utilisé.

eddiemoya
la source
12

Paramètres du plug-in d'importation / exportation

Ce n'est pas si commun entre les plugins, mais si votre plugin a (certains) paramètres, il devrait fournir Import / Export de données telles que la configuration et l'entrée utilisateur .

Import / Export améliore la facilité d'utilisation d'un plugin.

Breadcrumb NavXT (plugin Wordpress ) est un exemple de plug-in doté d'une telle fonctionnalité d'importation et d'exportation (ainsi que d'un mécanisme d'annulation ).

Apparenté, relié, connexe

hakre
la source
12

Organiser votre code

Il est toujours difficile de lire du code qui n'est pas écrit dans l'ordre dans lequel il est exécuté. Commencez par inclure / require, define, wp_enqueue_style & _script etc.

Essayez de séparer les éléments tels que css et js dans leurs propres dossiers. Essayez également de le faire avec des fonctions qui ne sont que des aides, comme les aplatissements de tableaux et similaires. Garder le fichier "principal" aussi propre et lisible que possible est un moyen d'aider les utilisateurs, les développeurs et vous-même lorsque vous essayez de mettre à jour votre logiciel dans l'année et que vous n'avez pas vu le code depuis plus longtemps.

Il est également bon d'avoir une structure que vous répétez souvent afin de toujours trouver votre chemin. Développer dans une structure connue sur différents projets vous donnera le temps de l'améliorer et même si votre client passe chez un autre développeur, vous n'entendrez jamais "il a laissé un chaos". Cela renforce votre réputation et devrait être un objectif à long terme.

kaiser
la source
Je crains que cela porte un peu trop sur le style dont les gens pourraient débattre et non sur les meilleures pratiques objectives avec lesquelles toutes les personnes respectées seraient d'accord. Il est très important que nous ne prenions que les meilleures pratiques objectives pour que les gens soient disposés à accepter de "bénir" la liste plutôt que d'avoir des éléments controversés, quelle que soit leur signification.
MikeSchinkel
11

Mourir avec style

mourir de manière décente Toutes les fonctions d'un plugin (et même d'un thème) doivent être utilisées wp_die()dans des endroits critiques pour offrir à l'utilisateur un peu d'informations sur ce qui s'est passé. Les erreurs php sont ennuyeuses et wp_diepeuvent donner à l’utilisateur un joli message stylé sur ce que le plugin (ou eux) a mal fait. De plus, si l'utilisateur a désactivé le débogage, le plug-in sera simplement interrompu.

En utilisant wp_die()également, vos plugins / thèmes sont compatibles avec la suite de tests wordpress .

Apparenté, relié, connexe:
hakre
la source
11

Fournir des écrans d'aide aux utilisateurs

Il est plus agréable de dire RTFM (cliquez sur aide) comme une réponse que de devoir répondre à la question à maintes reprises.

/**
  * Add contextual help for this screen
  * 
  * @param $rtfm
  * @uses get_current_screen
  */ 
  function ContextualHelp( /*string*/ $rtfm) 
  { 
     $current_screen = get_current_screen();
     if ($current_screen->id == $this->_pageid) 
     {
        $rtfm .= '<h3>The WordPress Plugin - Screen A</h3>';
        $rtfm .= '<p>Here are some tips: donate to me ' .
     }
     return $rtfm; 
  }
add_action('contextual_help', array($this,'ContextualHelp'),1,1);

update / note: (voir les commentaires de kaiser): l'exemple ci-dessus doit être utilisé dans une classe

edelwater
la source
Devrait être dans la boîte à outils de tout le monde (tant que vous devez expliquer un écran spécifique administrateur). +1
kaiser
Btw: Vous devriez mentionner que cela est censé résider dans une classe et comment interagir avec $ this -> _ page_id et comment cela se passerait si vous ajoutiez le hook d’action depuis un functions.php ou un fichier plugin sans classe .
Kaiser
10

Offrir des formulaires extensibles

Lorsqu'un plugin offre la possibilité de saisir des données, il doit toujours avoir un point d'accroche à la fin, juste avant le bouton "soumettre" et / ou "réinitialiser", afin que les développeurs puissent facilement étendre le formulaire avec non seulement des champs, mais également des boutons.

Voir: API de paramètres

Apparenté, relié, connexe

hakre
la source
9

inclure la fonction toujours par crochet, pas directement.

Exemple:

  • Ne pas utiliser pour inclure la classe du plugin via new sans hook

  • Utilisez le crochet plugins_loaded

    // add the class to WP                                   
    function my_plugin_start() {                                                               
        new my_plugin();   
    }                                                        
    add_action( 'plugins_loaded', 'my_plugin_start' );

Mise à jour: un petit exemple en direct: Plugin-svn-trunk-page et un pseudo exemple

//avoid direct calls to this file where wp core files not present
if (!function_exists ('add_action')) {
        header('Status: 403 Forbidden');
        header('HTTP/1.1 403 Forbidden');
        exit();
}

if ( !class_exists( 'plugin_class' ) ) {
    class plugin_class {

        function __construct() {
        }

    } // end class

    function plugin_start() {

        new plugin_class();
    }

    add_action( 'plugins_loaded', 'plugin_start' );
} // end class_exists

Vous pouvez également charger via mu_plugins_loaded sur multisite-install, voir le codex pour la référence d’action: http://codex.wordpress.org/Plugin_API/Action_Reference . Ici aussi, vous voyez comment wLcude wP avec ce hook: http: // adambrown. info / p / wp_hooks / hook / plugins_loaded? version = 2.1 & fichier = wp-settings.php J'utilise cela très souvent et ce n'est pas si difficile et précoce, mieux comme une nouvelle classe difficile ();

2 tours
la source
@bueltige --- Pourriez-vous expliquer celui-ci un peu plus
NetConstructor.com
3
un petit exemple live: [plugin-svn-trunk-page] svn.wp-plugins.org/filter-rewrite-rules/trunk/… et un pseudo exemple //avoid direct calls to this file where wp core files not present if (!function_exists ('add_action')) { header('Status: 403 Forbidden'); header('HTTP/1.1 403 Forbidden'); exit(); } if ( !class_exists( 'plugin_class' ) ) { class plugin_class { function __construct() { } } // end class function plugin_start() { new plugin_class(); } add_action( 'plugins_loaded', 'plugin_start' ); } // end class_exists
bueltge le
2
@ Netconstructor.co - J'ai mis à jour le fil, le commentaire est moche pour le code
bueltge
8

Licence Plugins sous une licence compatible GPL

Les plug-ins et les thèmes doivent être concédés sous une licence compatible WordPress. Cela leur permet d'être redistribués avec WordPress en tant que "programme". Une licence recommandée est la GPL . Veillez à ce que toutes les bibliothèques de codes fournies avec le plug-in soient compatibles avec la même licence.

(Cela a été un problème et un sujet de débat sérieux dans le passé et le présent .)

EAMann
la source
Laissons cela avec la compatibilité GPL pour le moment: core.trac.wordpress.org/ticket/14685
hakre
8

La description de votre plugin doit détailler avec précision les fonctions de votre plugin. Il y a 10 plugins postaux en vedette. Tous affichent les articles en vedette, mais beaucoup ont des caractéristiques différentes. Il devrait être facile de comparer votre plugin à des plugins similaires en lisant la description.

Vous devriez éviter de vous vanter de la simplicité de votre plugin, à moins que ce ne soit vraiment très basique. Vous devez inclure des liens utiles dans la description, comme le lien vers les paramètres.

Greg
la source
7

Minimiser les effets secondaires des sources de données et des services Web distants

Un plugin doit mettre en cache / bouclier le service Web et / ou les requêtes XMLRPC / SOAP via une couche de mise en cache / fournisseur de données si vous les utilisez afin de ne pas créer de demandes frontales en attente d'une réponse (lente) du service Web.

Cela inclut le téléchargement de flux RSS et d'autres pages. Concevez vos plugins pour qu’ils demandent des données en arrière-plan.

Une étape possible est la suivante (prenez un message sur ping.fm par exemple): Créez une table tampon, par exemple: ping_fm_buffer_post (date, heure, message, heure soumise, statut)

  1. Pour chaque fois que vous souhaitez soumettre une mise à jour à ping.fm, ajoutez-la à ce tableau.
  2. Maintenant, nous devons créer un plugin pour gérer ces données. Ce plugin sera exécuté via crontab pour vérifier chaque mise à jour non encore soumise.
  3. Comme nous avons ce tableau, nous pouvons également répertorier tous les messages soumis à ping.fm et vérifier le statut de chaque message. Juste au cas où il y aurait un problème du côté de ping.fm, nous pouvons le soumettre à nouveau.
hakre
la source
Je ne comprends pas vraiment où vous vous dirigez exactement avec cela. Pouvez-vous fournir des liens vers des documents complémentaires?
MikeSchinkel
De plus, je ne suis pas tout à fait sûr de ce que sont les "frais généraux" . N'y a-t-il pas un meilleur terme? Si c'est plus clair, ce sera une meilleure règle objective. Et Prevent " est impossible; " Minimize "à la place?
MikeSchinkel
Tu as probablement raison. Mauvaise formulation et prévenir n'est jamais possible, minimiser de meilleurs ajustements.
hakre
7

Testez votre plugin

Nous devrions définitivement avoir des outils de test sur notre environnement de développement de plugins.

Sur la base de cette réponse d’ Ethan Seifert à une question test, voici les bonnes pratiques à suivre:

  • Votre test unitaire doit tester le plus petit comportement qu'une classe puisse effectuer.
  • Lorsque vous atteignez le niveau de test fonctionnel, vous pouvez tester votre code avec des dépendances Wordpress.
  • En fonction de ce que votre plugin fait - envisagez d'utiliser des tests basés sur Selenium qui testent la présence de données dans le DOM à l'aide d'identifiants
Fernando Briano
la source
Bien que les tests soient importants, affirmer que les tests unitaires devraient tester les plus petits au lieu des meilleurs ne semble pas judicieux. Si vous rencontrez des difficultés pour tester les problèmes dépendants de WordPress, alors plongez dans le noyau de WordPress. Vous y trouverez une foule de variables globales internes que vous pouvez utiliser pour voir si les éléments ont fonctionné.
Backie
1
Mais couvrir le plus petit d’abord est fondamental, afin que vous puissiez atteindre les tests fonctionnels avec WordPress comme le dit la réponse, n’est-ce pas?
Fernando Briano
1
Ceci est un plugin et non une application, pouvez-vous tester une application Java sans Java Runtime? Oui, en écrivant Java sous forme de maquette puis en testant votre plugin. Les chances sont les bugs sont dans votre maquette. *) disclaimer ou le compiler en code natif.
Edelwater