¿Mejores prácticas objetivas para el desarrollo de complementos? [cerrado]

128

Iniciar una wiki de la comunidad para recopilar objetivo mejores prácticas para el desarrollo de complementos. Esta pregunta fue inspirada por los comentarios de @AMAM en los wp-hackers .

La idea es colaborar sobre cuáles podrían ser las mejores prácticas objetivas para que podamos utilizarlas en algún proceso de revisión de la colaboración comunitaria.

ACTUALIZACIÓN: Después de ver las primeras respuestas, queda claro que necesitamos tener solo una idea / sugerencia / mejor práctica por respuesta y las personas deben revisar la lista para asegurarse de que no haya duplicados antes publicación.

    
pregunta MikeSchinkel 17.02.2011 - 17:29

37 respuestas

66

Usar acciones y filtros

Si cree que a la gente le gustaría agregar o alterar algunos datos: proporcione apply_filters () antes de devolver .

  

P.S. Una cosa que encuentro un poco decepcionante y que su pregunta responde es el porcentaje de complementos que están diseñados solo para usuarios finales, es decir, que no tienen ningún gancho propio. ¿Imagina si WordPress fue diseñado como la mayoría de los complementos? Sería inflexible y una solución muy específica.

     

¿Quizás las cosas serían diferentes si WordPress tuviera la capacidad de instalar automáticamente los complementos de los que dependían otros complementos? Tal como es, normalmente tengo que escribir muchas de las funciones que necesito desde cero, porque los clientes quieren las cosas de cierta manera y los complementos disponibles, mientras que el 90% no me permite la flexibilidad para actualizar el 10% restante.

     

Realmente deseo que aquellos que lideran la comunidad de WordPress identifiquen una manera de asegurar que los complementos sean recompensados por seguir las mejores prácticas (como agregar ganchos para otros desarrolladores) al igual que las buenas respuestas se recompensan en un sitio StackExchange.

Tomemos un ejemplo de otra pregunta :

  

Ejemplo: quiero hacer algo en mi complemento cuando alguien retweets un artículo. Si hubiera un gancho personalizado en el popular complemento de retweet que podría conectar y disparar, sería genial. No hay, así que puedo modificar su complemento para incluirlo, pero eso solo funciona para mi copia, y no quiero intentar redistribuir eso.

Relacionado

respondido por el Arlen Beiler 13.04.2017 - 14:37
53

Cargar scripts / CSS con wp_enqueue_script y wp_enqueue_style

Los complementos no deben cargar / intentar cargar versiones duplicadas de archivos JS / CSS, especialmente jQuery y otros archivos JS incluidos en WP Core.

Los complementos siempre deben usar wp_enqueue_script y wp_enqueue_style al vincular archivos JS y CSS y nunca directamente a través de las etiquetas <script> .

Relacionado

respondido por el hakre 13.04.2017 - 14:37
49

Soporte I18n

Todas las cadenas de salida deben estar vinculadas a un dominio de texto adecuado para permitir la internacionalización por parte de las partes interesadas, incluso si el desarrollador no tiene interés en traducir su propio complemento.

Tenga en cuenta que es muy importante cargar los archivos de idioma durante la acción init para que el usuario pueda conectarse a la acción.

Consulte el Codex: I18n para desarrolladores de WordPress

Y también este artículo: Cargando los archivos de idioma WP correctamente .

Desde WordPress 4.6+

WP 4.6 cambió el orden de carga y las ubicaciones verificadas, lo ha hecho mucho más fácil para los desarrolladores y usuarios.

Considerando un complemento con un dominio de texto 'my-plugin', WordPress ahora PRIMERO buscará un archivo de traducción en:
/wp-content/languages/plugins/my-plugin-en_US.mo

Si no encuentra uno, buscará uno donde el complemento le indique que busque (normalmente en la carpeta 'lenguaje' de los pluigns si sigue el códice):
/ wp-content / plugins /my-plugin/languages/my-plugin-en_US.mo

Por último, si no se encuentra un archivo de idioma, se verificará la ubicación predeterminada de:
/wp-content/languages/my-plugin-en_US.mo

La primera comprobación se agregó en 4.6 y les da a los usuarios un lugar definido para agregar un archivo de idioma, ya que antes de que necesitaran saber dónde agregó el desarrollador el archivo de idioma, ahora el usuario solo necesita saber el dominio de texto del complemento: /wp-content/languages/plugins/TEXTDOMAIN-LOCAL.mo

A continuación se muestra la forma antigua (no relevante desde WP 4.6+)

  

[...]
  Finalmente, me gustaría señalar que es importante cargar archivos de idioma de usuario personalizados desde WP_LANG_DIR antes de cargar los archivos de idioma que vienen con el complemento . Cuando se cargan varios archivos mo para el mismo dominio, se utilizará la primera traducción encontrada. De esta manera, los archivos de idioma proporcionados por el complemento servirán como respaldo para las cadenas no traducidas por el usuario.

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/' 
    );
}
    
respondido por el Stiofan O'Connor 04.05.2017 - 20:59
45

Asegúrese de que los complementos no generen errores con WP_DEBUG

Siempre pruebe sus complementos con WP_DEBUG activado e idealmente tenerlo encendido a lo largo de su proceso de desarrollo. Un complemento no debería lanzar CUALQUIER error con WP_DEBUG activado. Esto incluye avisos desaprobados e índices sin marcar.

Para activar la depuración, edite el archivo wp-config.php para que la constante WP_DEBUG esté configurada en true . Consulte el Codex en depuración para obtener más detalles.

    
respondido por el John P Bloch 25.08.2010 - 22:13
40

Primero use las funciones existentes en WordPress Core

Si puede: utilizar las funciones existentes incluidas en el núcleo de WordPress en lugar de escribir las suyas. Solo desarrolle funciones PHP personalizadas cuando no haya una función preexistente apropiada en el núcleo de WordPress.

Uno de los beneficios es que puede usar "avisos de desaprobación de registros" para monitorear fácilmente las funciones que deben reemplazarse. Otro beneficio es que los usuarios pueden ver la documentación de la función en el Codex y comprender mejor lo que hace el complemento incluso si no son desarrolladores de PHP con experiencia.

Relacionado

respondido por el hakre 13.04.2017 - 14:37
33

Evitar la inyección SQL con datos de entrada

Un complemento debería desinfectar todas las entradas del usuario recuperadas directa o indirectamente (por ejemplo, a través de $_POST o $_GET ) antes de usar los valores de entrada para consultar la base de datos MySQL.

Consulte: Formateo de sentencias de SQL .

    
respondido por el hakre 25.08.2010 - 21:00
33

La desinstalación debe eliminar todos los datos de un complemento

Al ser eliminado de una instalación de WordPress, un complemento debe eliminar todos los archivos, carpetas, entradas de la base de datos y tablas que creó así como los valores de las opciones que creó. .

Los complementos pueden ofrecer una opción para exportar / importar configuraciones, para que las configuraciones se puedan guardar fuera de WordPress antes de eliminarlas.

Relacionado

respondido por el hakre 13.04.2017 - 14:37
30

Utilice una clase y un código PHP5 orientado a objetos

No hay razón para no escribir código PHP5 limpio y orientado a objetos. El soporte de PHP4 se eliminará gradualmente después del próximo lanzamiento (WP 3.1). Por supuesto, puede prefijar todos los nombres de sus funciones para terminar con endlessly_long_function_names_with_lots_of_underscores, pero es mucho más fácil escribir una clase simple y agrupar todo en eso. Además, ponga su clase en un archivo separado y asígnele el nombre correspondiente para que pueda extenderlo y mantenerlo fácilmente:

// 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
    }
}
    
respondido por el Husky 01.09.2010 - 16:58
29

Prefijo todos los elementos del espacio de nombres global

Un complemento debe prefijar correctamente TODOS los elementos del espacio de nombres globales (constantes, funciones, clases, variables, incluso cosas como taxonomías personalizadas, tipos de publicaciones, widgets, etc.). Por ejemplo, no cree una función llamada init() ; en su lugar, nombre algo como jpb_init() .

Es común usar un prefijo de tres o cuatro letras delante de los nombres o hacer uso del PHP Característica del espacio de nombres . Compare: ¿Prefijo de una sola letra para las constantes de clase de PHP?

Relacionado

respondido por el hakre 23.05.2017 - 14:40
25

La desactivación no debe provocar pérdida de datos

Un complemento no debería eliminar ninguno de sus datos en deactivation .

Relacionado

respondido por el MikeSchinkel 13.04.2017 - 14:37
23

Incluya solo los archivos que necesite ...

Si estás en la parte delantera, no incluyas el código relacionado con el área de administración.

    
respondido por el Denis de Bernardy 13.01.2011 - 23:05
21

Anunciar pérdida de datos en la desinstalación del complemento

Al desinstalar un complemento debería solicitar a un usuario que borre sus datos y recibir una confirmación de que el usuario está de acuerdo con la eliminación los datos antes de hacerlo y un complemento deben también permiten al usuario la opción de mantener los datos en la desinstalación. (Esta idea de @EAMann.)

Relacionado

respondido por el hakre 13.04.2017 - 14:37
19

Permitir que se cambie el nombre de la carpeta del complemento

/ plugins / pluginname / {various}

El "nombre de plugin" utilizado para la carpeta siempre debe ser modificable.

Esto normalmente se maneja definiendo constantes y usándolas consistentemente en todo el complemento.

No hace falta decir que muchos complementos populares son pecadores.

Relacionado:

  • plugins_url() para vincular fácilmente los recursos, incluido con el complemento.
respondido por el AndyBeard 10.01.2011 - 08:39
18

Usa WordPress (incorporado) Manejo de errores

No solo return; si alguna entrada del usuario fue incorrecta. Entregarles algo de información se hizo 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...
}

Un error (objeto) para todos

Puede configurar un objeto de error global para su tema o complemento durante el arranque:

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

Más tarde, puedes agregar errores ilimitados a pedido:

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

Luego puedes buscarlos todos al final de tu tema. De esta manera, no interrumpe el procesamiento de la página y aún puede generar todos sus errores para el desarrollo

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

Puede encontrar más información en esta Q . Un ticket relacionado para corregir el "trabajo conjunto" de WP_Error y wp_die() se enlaza desde allí y seguirá otro ticket. Comentarios, críticas y amp; tal es apreciado.

    
respondido por el kaiser 13.04.2017 - 14:37
17

Minimizar los nombres agregados al espacio de nombres global

Un complemento debería reducir su impacto tanto como sea posible al minimizar la cantidad de nombres que agrega al espacio de nombres global .

Esto se puede hacer encapsulando las funciones del complemento en una clase o usando característica de espacios de nombres de PHP . Prefijar todo también puede ayudar, pero no es tan flexible.

Junto a las funciones y clases, un complemento no debería introducir variables globales. El uso de clases normalmente las deja obsoletas y simplifica el mantenimiento de los complementos.

Relacionado

respondido por el hakre 13.04.2017 - 14:37
16

Proteger la privacidad de los usuarios del complemento

(Anteriormente: Comunicación de API anónima)

Si un complemento se comunica con un sistema externo o API (por ejemplo, algún servicio web), debe hacerlo de forma anónima o proporcionar al usuario una opción anónima que garantice que no se filtre a un segundo ningún dato relacionado con el usuario del complemento. fiesta sin control.

    
respondido por el EAMann 23.08.2010 - 22:17
16

Comentar usando PhpDoc

La mejor práctica es cercana al estilo PhpDoc. Si no usa un IDE como "Eclipse", puede echar un vistazo a en PhpDoc Manual .

No tienes que saber exactamente cómo funciona esto. Los desarrolladores profesionales pueden leer el código de todos modos y solo necesitan esto como un resumen. Los codificadores y usuarios de Hobby pueden apreciar la forma en que lo explicas en el mismo nivel de conocimiento.

    
respondido por el kaiser 25.08.2010 - 22:00
16

Use la API de configuración antes de add_option

En lugar de agregar opciones a la base de datos a través de la función add_option, debe almacenarlas como una matriz con el uso de la API de configuración que se encarga de todo por ti.

Use la API de modificaciones de tema antes de add_option

La API de Modificaciones es una construcción bastante simple y una forma segura que permite agregar y recuperar opciones. Todo se guarda como valor serializado en su base de datos. Fácil, seguro y amp; simple.

    
respondido por el kaiser 28.10.2011 - 11:51
14

Host Plugins en WordPress.org

Use el repositorio SVN proporcionado en WordPress.org para hospedar complementos. Facilita la actualización de la experiencia de usuario y, si nunca ha usado SVN antes, le permite entender realmente al usarlo en un contexto que lo justifique.

    
respondido por el MikeSchinkel 25.08.2010 - 21:45
14

Proporcionar control de acceso mediante el uso de permisos

En muchos casos, es posible que los usuarios no quieran que todos tengan acceso a las áreas creadas por su complemento, especialmente con complementos que realizan múltiples operaciones complejas, por lo que una sola verificación de capacidad codificada en forma no es suficiente.

Como mínimo, haga las comprobaciones de capacidad adecuadas para todos los diferentes tipos de procedimientos para los que se puede usar su complemento.

    
respondido por el eddiemoya 25.08.2010 - 21:47
12

Configuración del complemento de importación / exportación

No es tan común entre los complementos, pero si su complemento tiene (algunos) ajustes, debería proporcionar Importación / Exportación de datos como la configuración y la entrada del usuario .

Importar / Exportar mejora la usabilidad de un complemento.

Un ejemplo de complemento que tiene una funcionalidad de importación y exportación (y un mecanismo de deshacer) es Breadcrumb NavXT ( Wordpress Plugin) (revelación completa: un poco de código escrito por mí, la mayoría lo ha hecho mtekk).

Relacionado

respondido por el hakre 13.04.2017 - 14:37
12

Organiza tu código

Siempre es difícil leer el código que no está escrito en el orden en que se ejecuta. Primero incluya / requiera, defina, wp_enqueue_style & _script, etc., luego las funciones que necesita el complemento / tema y, por último, el generador (por ejemplo, la pantalla de administración, las cosas que se integran en el tema, etc.).

Intenta separar cosas como css y js en sus propias carpetas. También intente hacer esto con funciones que solo sean ayudantes, como aplanadores de matrices y similares. Mantener el archivo "principal" tan limpio y fácil de leer como sea posible es una manera que ayuda a los usuarios, a los desarrolladores y a usted, cuando intenta actualizar en un año y no ha visto el código por más tiempo.

También es bueno tener una estructura que repites a menudo, para que siempre encuentres tu camino. El desarrollo en una estructura conocida en diferentes proyectos le dará tiempo para mejorarlo e incluso si su cliente cambia a otro desarrollador, nunca escuchará que "dejó un caos". Esto construye su reputación y debe ser un objetivo a largo plazo.

    
respondido por el kaiser 06.01.2011 - 22:12
11

Muere con estilo

muere de una manera decente Todas las funciones de los complementos (e incluso temas) deben usar wp_die() en lugares críticos para ofrecer al usuario un poco de información sobre lo que sucedió. Los errores de php son molestos y wp_die puede dar al usuario un mensaje de estilo agradable sobre lo que el complemento (o) hicieron mal. Además, si el usuario ha desactivado la depuración, el complemento simplemente se romperá.

El uso de wp_die() también ayuda a que sus complementos / temas sean compatibles con wordpress testsuite .

Relacionado:
respondido por el hakre 13.04.2017 - 14:37
10

Ofrecer formularios extensibles

Cuando un complemento ofrece la posibilidad de ingresar datos, siempre debe tener un enlace al final, justo antes del botón "enviar" y / o "restablecer", para que los desarrolladores puedan extender fácilmente el formulario no solo con campos, sino botones también.

Consulte: API de configuración

Relacionado

respondido por el hakre 13.04.2017 - 14:37
10

Proporcionar pantallas de ayuda para los usuarios

Es mejor decir RTFM (ayuda de clic) como respuesta que tener que responder la pregunta una y otra vez.

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

actualización / nota: (vea los comentarios de kaiser): el ejemplo anterior debe usarse en una clase

    
respondido por el edelwater 04.12.2013 - 11:09
9

incluir la función siempre a través de Hook, no directamente.

Ejemplo:

  • No utilice para incluir la clase del complemento a través de un nuevo sin gancho

  • Utilice los complementos de Hook_loaded

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

Actualización: un pequeño ejemplo en vivo: Plugin-svn-trunk-page y un pseudo ejemplo

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

También puede cargar a través de mu_plugins_loaded en multisite-install, ver el códice para referencia de acción: enlace También aquí puedes ver cómo incluir wP con este gancho: enlace Lo utilizo muy a menudo y no es tan difícil y temprano, mejor como una nueva clase ();

    
respondido por el bueltge 14.02.2011 - 22:13
8

Complementos de licencia bajo una licencia compatible con GPL

Los complementos y temas deben tener licencia bajo una licencia compatible con WordPress. Esto les permite ser redistribuidos con WordPress como un "programa". Una licencia recomendada es la GPL . Tenga cuidado de que todas las bibliotecas de códigos incluidas con el complemento sean compatibles con la misma licencia.

(Esto ha sido un problema y es grave point of debate tanto en el pasado como present .)

    
respondido por el EAMann 13.04.2017 - 14:37
8

La descripción de su complemento debe detallar con precisión las funciones de su complemento. Hay 10 complementos de post destacados. Todos ellos muestran publicaciones destacadas, sin embargo, muchos tienen características diferentes. Debería ser fácil comparar su complemento con complementos similares leyendo la descripción.

Debes evitar presumir de lo simple que es tu complemento a menos que sea realmente muy básico. Debe incluir enlaces útiles en la descripción, como el enlace a la configuración.

    
respondido por el Greg 30.08.2010 - 05:41
7

Minimizar los efectos secundarios de las fuentes de datos remotos y los servicios web

Un complemento debería Servicio web de caché / escudo y / o Solicitudes de XMLRPC / SOAP a través de una capa de almacenamiento de datos / caché si los usa por lo tanto, para no realizar solicitudes anticipadas a la espera de una respuesta (lenta) del servicio web.

Eso incluye la descarga de RSS y otras páginas. Diseñe sus complementos para que soliciten datos en segundo plano.

Un PASO posible es (tome la publicación en ping.fm como ejemplo): Crea una tabla de búfer, digamos: ping_fm_buffer_post ( fecha, hora, mensaje, hora de envío, estado )

  1. Para cada vez que desee enviar una actualización a ping.fm, agréguela a esta tabla.
  2. Ahora, necesitamos crear un complemento para manejar estos datos. Este complemento se ejecutará a través de crontab para verificar todas las actualizaciones que aún no se hayan enviado
  3. Como tenemos esta tabla, también podemos enumerar todos los mensajes enviados a ping.fm y verificar el estado de cada publicación. En caso de que haya un problema en el lado de ping.fm, podemos volver a enviarlo.
respondido por el hakre 30.08.2010 - 04:53
7

Prueba tu plugin

Definitivamente deberíamos tener algunas herramientas de prueba en nuestro entorno de desarrollo de complementos.

Basado en esta respuesta por Ethan Seifert a una pregunta de prueba, estas son buenas prácticas a seguir:

  • La prueba de unidad debe probar la menor cantidad de comportamiento que una clase puede realizar.
  • Cuando llegas al nivel de las pruebas funcionales, aquí es donde puedes probar tu código con las dependencias de Wordpress.
  • Dependiendo de lo que haga su complemento, considere usar pruebas basadas en Selenium que prueben la presencia de datos en el DOM mediante el uso de ID
respondido por el Fernando Briano 13.04.2017 - 14:37

Lea otras preguntas en las etiquetas