Domanda

Avvio di una comunità wiki per raccogliere fino oggettivi le migliori pratiche per lo sviluppo del plugin. Questa domanda è stata ispirata da @ di EAMann commenti su wp-hacker .

L'idea è quella di collaborare a ciò che le migliori pratiche oggettive potrebbero essere in modo che possiamo potenzialmente eventualmente utilizzarli in qualche processo di revisione di collaborazione della comunità.

UPDATE: Dopo aver visto le prime risposte, diventa chiaro che abbiamo bisogno di avere una sola idea / suggerimento / best-practice per ogni risposta e la gente dovrebbe rivedere l'elenco al fine di garantire non ci sono duplicati prima distacco.

È stato utile?

Soluzione

utilizzare le azioni e filtri

Se si pensa che la gente vorrebbe aggiungere o modificare alcuni dati: apply_filters () prima di tornare .

P.S. Una cosa che ho trovato un po 'deludente e che i vostri indirizzi domanda è la percentuale di plugin che sono stati progettati esclusivamente per gli utenti finali, vale a dire che non hanno ganci dei loro propri. Immaginate se WordPress sono stati progettati come la maggior parte dei plugin? Sarebbe inflessibile e una soluzione di nicchia molto.

Forse le cose sarebbero diverse se WordPress dovesse avere la capacità di plug-in auto-install su cui altri plugin dipendevano? Come è solito ho dovuto scrivere un sacco di funzionalità che ho bisogno da zero, perché i clienti vogliono cose in un certo modo e i plugin disponibili, mentre il 90% lì, non mi consentono la flessibilità necessaria per aggiornare il restante 10%.

io davvero vogliono coloro che guidano la comunità WordPress sarebbe identificare un modo per garantire che i plugin sono ricompensati per i seguenti migliori pratiche (come l'aggiunta di ganci per altri sviluppatori) molto simile a buone risposte sono ricompensati in un sito StackExchange.

Facciamo un esempio da un'altra domanda :

Esempio: voglio fare qualcosa nel mio plug-in quando qualcuno retweet un articolo. Se ci fosse un gancio personalizzato in qualunque plugin Retweet popolare è che ho potuto agganciare a sparare e di, che sarebbe grande. Non c'è, in modo da poter modificare il proprio plugin per includerlo, ma che funziona solo per la mia copia, e non voglio cercare di ridistribuire questo.

correlati

Altri suggerimenti

Script di carico / CSS con wp_enqueue_script e wp_enqueue_style

Plugin non dovrebbe caricare / tentare di caricare le versioni duplicate di file JS / CSS, in particolare jQuery e altri JS file inclusi nel WP Nucleo.

Plugin deve sempre usare wp_enqueue_script e wp_enqueue_style durante il collegamento file JS e CSS e mai direttamente tramite tag <script>.

correlati

I18n supportare

Tutte le stringhe di uscita deve essere collegato a un dominio testo appropriato per consentire l'internazionalizzazione delle parti interessate, anche se lo sviluppatore non ha alcun interesse a tradurre i propri plug-in.

Si noti che è molto importante per caricare i file di lingua durante l'azione init così l'utente può agganciare in azione.

Vedere la Codex: I18n per WordPress sviluppatori

E anche questo articolo: Caricamento WP deposita la corretta <. / p>

Dal momento che WordPress 4.6 +

WP 4.6 ha cambiato l'ordine di caricamento e le posizioni controllati, ha reso molto più facile per gli sviluppatori e gli utenti.

Considerando un plugin con un textdomain 'my-plugin', WordPress ora per prima cosa un file di traduzione in:
/wp-content/languages/plugins/my-plugin-en_US.mo

Se non riesce a trovare uno ci sarà poi cercare uno in cui il plugin dice di guardare (quando arrivavano in 'lingua' dei pluigns cartella se in seguito il codice):
/wp-content/plugins/my-plugin/languages/my-plugin-en_US.mo

Infine, se non viene trovato alcun file di lingua che controllerà il percorso predefinito:
/wp-content/languages/my-plugin-en_US.mo

Il primo controllo è stato aggiunto in 4.6 e offre agli utenti un luogo definito per aggiungere un file di lingua, come in precedenza avrebbero bisogno di sapere dove lo sviluppatore ha aggiunto il file della lingua, ora l'utente ha solo bisogno di conoscere textdomain del plugin: /wp-content/languages/plugins/TEXTDOMAIN-LOCAL.mo


Di seguito è riportato il vecchio modo (non rilevante dal WP 4.6 +)

[...]
Infine, vorrei sottolineare che è importante per carico personalizzati file di lingua dell'utente da WP_LANG_DIR prima di caricare i file di lingua forniti con il plugin . Quando più mo-file vengono caricati per lo stesso dominio, verrà utilizzata la prima traduzione trovato. In questo modo i file di lingua forniti dal plugin serviranno come ripiego per le stringhe non tradotte da parte dell'utente.

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/' 
    );
}

Assicurare Plugin non generano errori con WP_DEBUG

Verificare sempre i tuoi plugin con WP_DEBUG acceso e idealmente averlo acceso per tutto il processo di sviluppo. Un plugin non dovrebbe gettare eventuali errori con WP_DEBUG on. Questo include le comunicazioni deprecate e gli indici non controllati.

Per attivare il debugging, modificare il file wp-config.php in modo che la costante WP_DEBUG è impostato su true. Vedere la Codice sul debug per maggiori dettagli.

Primo Usa esistente funzioni in WordPress core

Se è possibile: Utilizza esistente funzioni incluse nel nucleo WordPress invece di scrivere il proprio. sviluppare Solo funzioni PHP personalizzati quando non c'è un adeguato funzione di pre-esistente nel nucleo di WordPress.

Un vantaggio è che si può usare "log comunicazioni deprecate" per monitorare facilmente le funzioni che devono essere sostituiti. Un altro vantaggio è l'utente può visualizzare la documentazione funzione nel Codex e capire meglio che cosa il plugin fa, anche se non sono un esperto sviluppatore PHP.

correlati

disinstallazione dovrebbe rimuovere tutti i dati di un plug-in

Dopo essere stato rimosso da un'installazione di WordPress, un plugin dovrebbe eliminare tutti i file, cartelle, voci di database e tabelle , che esso ha creato, così come i valori ha creato .

Plugin può offrire la possibilità di impostazioni di esportazione / importazione, in modo che le impostazioni possono essere salvate al di fuori di WordPress prima eliminazione.

correlati

Iniezione Prevenire SQL con inserimento

Un plugin dovrebbe disinfettare tutti gli input dell'utente recuperate direttamente o indirettamente (per esempio tramite $_POST o $_GET ) prima di utilizzare i valori di ingresso per interrogare il database MySQL.

See: formattazione SQL

.

Prefisso Tutti globale dei nomi Voci

Un plugin dovrebbe correttamente tutti gli elementi prefisso namespace globale (costanti, funzioni, classi, variabili, cose anche come tassonomie personalizzati, tipi di messaggi, widget, etc.). Per esempio, non creare una funzione chiamata init(); invece, il nome è qualcosa di simile a jpb_init().

Il suo comune dovrebbe usare un tre o quattro lettere prefisso davanti nomi o di utilizzare il PHP Namespace Caratteristica . Confronto: singola lettera prefisso per costanti di classe PHP

correlati

Utilizzare un codice di classe e orientato agli oggetti PHP5

Non c'è alcun motivo per non scrivere, il codice PHP5 pulito orientata agli oggetti. Supporto PHP4 sarà gradualmente dopo il prossimo rilascio (WP 3.1). Naturalmente, è possibile far precedere tutti i nomi delle funzioni per finire con endlessly_long_function_names_with_lots_of_underscores, ma è molto più facile scrivere solo una semplice classe e fagotto tutto in quella. Inoltre, mettere la classe in un file separato e il nome di conseguenza in modo da poter facilmente estendere e mantenerla:

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

La disattivazione non dovrebbero provocare la perdita di dati

Un plugin non dovrebbe eliminare uno qualsiasi dei suoi dati su disattivazione .

correlati

includere solo i file di cui avete bisogno ...

Se siete nel front-end, non includere il codice che si riferisce al settore amministrativo.

Annunciare la perdita di dati su Plugin disinstallazione

Al momento della disinstallazione un plugin dovrebbe utente un messaggio che sarà eliminarlo di dati e ricevere una conferma che l'utente è d'accordo con la cancellazione i dati prima di farlo e un plugin dovrebbe anche consentire all'utente la possibilità di conservare i dati su di disinstallazione. (Questa idea da @EAMann.)

correlati

Let plug-in del nome della cartella essere modificato

/ plugins / pluginName / {vari}

Il "pluginName" utilizzato per la cartella deve essere sempre mutevole.

Questo è normalmente gestito attraverso la definizione di costanti e tutte ugualmente il loro utilizzo in tutto il plugin.

Inutile dire che molti plugin popolari sono peccatori.

correlati:

  • plugins_url() per un facile collegamento alle risorse, incluso con il plugin.

Usa WordPress (integrato) Gestione degli errori

Non basta return; se qualche input da parte dell'utente è stato sbagliato. Fornire loro alcune informazioni circa era stato torto fatto.

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

Un errore (oggetto) per tutti

È possibile impostare un oggetto di errore globale per il tema o il plug-in durante il bootstrap:

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' );

In seguito è possibile aggiungere un numero illimitato di errori su richiesta:

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

Poi si può andare a prendere tutti alla fine del vostro tema. In questo modo non interrompono il rendering della pagina e può ancora uscita tutti i tuoi errori per lo sviluppo

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' );

E 'possibile trovare maggiori informazioni sul questo Q . Un biglietto correlate a fissare il "insieme di lavoro" di WP_Error e wp_die() è legata da lì e un altro biglietto seguirà. Commenti, critiche e tale è apprezzato.

Minimizzare nomi aggiunti al namespace globale

Un plugin dovrebbe ridurre il suo impatto il più possibile da riducendo al minimo il numero di nomi si aggiunge al namespace globale .

Questo può essere fatto incapsulando le funzioni del plugin in una classe o utilizzando il namespace PHP dispongono . Anteponendo tutto può aiutare pure, ma non è così flessibile.

Accanto a funzioni e classi, un plugin non dovrebbe introdurre variabili globali. Utilizzo di classi normalmente li rende obsoleta e semplifica la manutenzione plugin.

correlati

Commento utilizzando PHPDoc

Le migliori pratiche è vicino allo stile PHPDoc. Se non si utilizza un IDE come "Eclipse", si può semplicemente dare un'occhiata al PHPDoc Manuale .

Non c'è bisogno di sapere esattamente come funziona. Professionale Gli sviluppatori possono leggere il codice in ogni caso e solo bisogno di questo come una sintesi. codificatori Hobby e gli utenti potrebbero apprezzare il modo in cui si spiega sullo stesso livello di conoscenza.

utilizzare le impostazioni API prima add_option

Invece di aggiungere opzioni al DB tramite la funzione add_option, si dovrebbe memorizzarli come un array con l'utilizzo del Impostazioni API che si prende cura di tutto per voi.

Utilizzare il tema Modifiche API prima add_option

Il Modifiche API è un costrutto semplice bella e un modo sicuro che permette l'aggiunta e il recupero di opzioni. Tutto viene salvato come valore serializzato nel database. Facile, sicuro e semplice.

Protect Plugin Utenti Privacy

(precedentemente: Anonimo API Comunicazione)

Se A comunica plugin con un sistema esterno o API (ad esempio alcuni Webservice), dovrebbe modo anonimo o fornire all'utente un'opzione anonima che assicura che nessun dato relativo all'utente delle perdite di plugin per una seconda partito non controllata.

Plugin Host su WordPress.org

Utilizza il SVN repository previsto su WordPress.org per ospitare i plugin. Si fa per una più facile aggiornamento user-experience e se non hai mai usato prima di SVN, si arriva a capire realmente usandolo in un contesto che lo giustifichi.

fornire il controllo dell'accesso utilizzando le autorizzazioni

In molti casi, gli utenti potrebbero non voler a tutti di avere accesso alle aree create dal vostro plugin soprattutto con plugin che fanno molteplici operazioni complesse, un unico controllo capacità hardcoded potrebbe non essere sufficiente.

Per lo meno, hanno opportune verifiche capacità per tutti i diversi tipi di procedure vostro plugin può essere usato per.

Import Export Settings / plugin

Non è che comune a tutti i plugin, ma se il plugin ha (alcuni) le impostazioni, è dovrebbe fornire Import / Export dei dati come la configurazione e l'input dell'utente .

Importa / Esporta migliora l'usabilità di un plugin.

Un esempio-plugin che ha una funzionalità quali l'importazione e l'esportazione (e pure un meccanismo di undo) è vi trovate in NavXT (Wordpress Plugin) (full disclosure: un po 'po' di codice da me in là, la maggior parte è stato fatto da mtekk).

correlati

Organizza il tuo codice

E 'sempre puntuale difficile leggere il codice che non è scritto nell'ordine che ottiene di eseguiti. In primo luogo include / richiedono, definire, wp_enqueue_style & _script, ecc, allora le funzioni che le esigenze plugin / a tema e finalmente il costruttore (es. Schermata di amministrazione, roba che integra nel tema, ecc).

Prova a cose separate come CSS e JS nelle proprie cartelle. Anche provare a fare questo con le funzioni che sono solo aiutanti, come flatteners matrice e simili. Mantenere il file "principale" il più pulito e di facile lettura possibile è un modo che aiuta gli utenti, sviluppatori e voi, quando si tenta di aggiornare in un anno e non hanno visto il codice per un tempo più lungo.

E 'bene avere anche una struttura che si ripete spesso, in modo da trovare sempre la strada attraverso. Lo sviluppo in una struttura nota su diversi progetti vi darà il tempo per renderlo migliore e anche se il cliente passa a un altro sviluppatore, non si sarà mai sentire "ha lasciato un caos". Questo si basa la vostra reputazione e dovrebbe essere un obiettivo a lungo termine.

Die con lo stile

morire in un modo decente Tutto ad un plugin (e temi anche) funzioni dovrebbe usare wp_die() in luoghi critici per offrire all'utente un po 'di informazioni su quello che era successo. Php errori sono fastidiosi e wp_die possono dare all'utente un bel messaggio in stile su ciò che il plug-in (o loro) ha sbagliato. Inoltre, se l'utente ha debug disattivato il plugin basta rompere.

Utilizzando wp_die() aiuta anche che i vostri plugins / temi sono compatibili con il wordpress testsuite .

Relazionato:

Fornire Maschere di aiuto per gli utenti

E 'bello dire RTFM (click aiuto) come una risposta di dover rispondere alla domanda di volta in volta.

/**
  * 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);

Aggiornamento / Nota: (vedi commenti da kaiser): l'esempio di cui sopra è da utilizzare in una classe

Offrire Forms estendibili

Quando un plugin offre la possibilità di abilitare i dati di input, si dovrebbero sempre avere un gancio alla fine, a destra prima del "invia" e / o il pulsante "reset", quindi gli sviluppatori possono facilmente estendere il form con non solo i campi, ma pulsanti troppo.

See: Impostazioni API

correlati

includere la funzione sempre via Hook, non direttamente.

Esempio:

  • Non uso per includere la classe del plugin tramite nuova senza gancio

  • utilizzare il gancio plugins_loaded

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

Aggiornamento: un piccolo esempio dal vivo: Plugin-svn-tronco-page e un esempio di pseudo

//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

Si può anche caricare tramite mu_plugins_loaded su multisito-installazione, vedere il codice di riferimento dell'azione: http://codex.wordpress.org / Plugin_API / Action_Reference Anche qui vedete, come inlcude wP con questo gancio: http: // adambrown.info/p/wp_hooks/hook/plugins_loaded?version=2.1&file=wp-settings.php I utilizza molto spesso e non è così difficile e presto, meglio come una nuova classe difficile ();

Plugins Licenza sotto una licenza compatibile GPL

Plug-in e temi dovrebbe essere concesso in licenza sotto una licenza WordPress-compatibili. Ciò consente loro di essere ri-distribuiti con WordPress come un "programma". Una licenza raccomandata è GPL . fare in modo che tutte le librerie di codice inclusi con il plug-in sono compatibili con la stessa licenza.

(Questo ha stato un problema serio e point del dibattito sia nel passato e presente .)

La tua descrizione plugin dovrebbe accuratamente dettaglio le funzioni del vostro plugin. Ci sono 10 i plugin Articolo distaccato. Tutti loro visualizzare i messaggi in vetrina, ma molti hanno caratteristiche diverse. Dovrebbe essere facile per confrontare il tuo plugin per plugin simili leggendo la descrizione.

Si dovrebbe evitare di vantarsi di quanto sia semplice il tuo plugin è a meno che non è davvero molto semplice. È necessario includere link utili nella descrizione, come il collegamento alle impostazioni.

Minimizzare Gli effetti collaterali di Datasources remoti e Webservices

Un plugin dovrebbe Cache Shield Webservice / e / o richieste di XMLRPC / SOAP attraverso uno strato di cache / dati del provider se li usate in modo da non fare front-le richieste in attesa di (lenta) risposta webservice.

che include il download di feed RSS e di altre pagine. Progetta il tuo plugin che chiedono i dati in background.

Una possibile passo è (Prendere annuncio a ping.fm come esempio): Creare una tabella di buffer, diciamo: ping_fm_buffer_post ( data, ora, un messaggio, submitted_time, lo stato )

  1. Per ogni volta che si desidera inviare aggiornamento ping.fm, aggiungerlo a questa tabella.
  2. Ora, abbiamo bisogno di creare un plugin per gestire tali dati. Questo plugin verrà eseguito tramite crontab per verificare ogni aggiornamento che non è ancora presentato
  3. Perché abbiamo questa tabella, possiamo anche elencare ogni messaggio inviato a Ping.fm e verificare lo stato di ogni post. Nel caso in cui ci sia problema dalla parte di ping.fm, siamo in grado di ri-inviarlo.

Metti alla prova il plugin

dovrebbe definitivamente avere alcuni strumenti di test sul nostro ambiente di sviluppo plugin.

In base a questa risposta di Ethan Seifert ad una domanda di prova, queste sono le buone pratiche da seguire:

  • il test dell'unità dovrebbe testare la più piccola quantità di comportamento che una classe può eseguire.
  • Quando si arriva fino al livello di collaudo funzionale questo è dove è possibile testare il vostro codice con dipendenze Wordpress.
  • A seconda di cosa il vostro plugin fa - considerare l'utilizzo di test Selenium-based che prova per la presenza di dati nel DOM utilizzando gli ID
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a wordpress.stackexchange
scroll top