Prácticas Objetivas Recomendadas para el Desarrollo de Plugins?
Comenzando un wiki comunitario para recopilar las mejores prácticas objetivas para el desarrollo de plugins. Esta pregunta fue inspirada por los comentarios de @EAMann en wp-hackers.
La idea es colaborar en definir cuáles podrían ser las mejores prácticas objetivas para que eventualmente podamos usarlas en algún proceso de revisión colaborativa de la comunidad.
ACTUALIZACIÓN: Después de ver las primeras respuestas, queda claro que debemos 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 de publicar.

Usar Acciones y Filtros
Si crees que a los usuarios les gustaría añadir o modificar algún dato: proporciona apply_filters() antes de devolverlo.
P.D. Algo que me parece un poco decepcionante y que tu pregunta aborda es el porcentaje de plugins que están diseñados solo para usuarios finales, es decir, que no tienen sus propios hooks. ¿Te imaginas si WordPress estuviera diseñado como la mayoría de los plugins? Sería inflexible y una solución muy limitada.
Quizás las cosas serían diferentes si WordPress tuviera la capacidad de instalar automáticamente plugins de los que otros dependen. Tal como está, normalmente tengo que desarrollar gran parte de la funcionalidad que necesito desde cero porque los clientes quieren las cosas de cierta manera y los plugins disponibles, aunque cubren el 90%, no me permiten la flexibilidad de ajustar el 10% restante.
Realmente desearía que los líderes de la comunidad WordPress encontraran una forma de garantizar que los plugins sean recompensados por seguir las mejores prácticas (como incluir hooks para otros desarrolladores), similar a cómo las buenas respuestas son recompensadas en un sitio StackExchange.
Tomemos un ejemplo de otra pregunta:
Ejemplo: Quiero hacer algo en mi plugin cuando alguien retuitea un artículo. Si hubiera un hook personalizado en el plugin de retuits más popular al que pudiera engancharme y disparar mi código, sería genial. Pero no lo hay, así que puedo modificar su plugin para incluirlo, pero eso solo funciona para mi copia y no quiero intentar redistribuir eso.
Relacionado

Cargar Scripts/CSS con wp_enqueue_script
y wp_enqueue_style
Los plugins no deben cargar/intentar cargar versiones duplicadas de archivos JS/CSS, especialmente jQuery y otros archivos JS incluidos en el núcleo de WordPress.
Los plugins siempre deben usar wp_enqueue_script
y wp_enqueue_style
al vincular archivos JS y CSS, y nunca directamente mediante etiquetas <script>
.
Relacionado

Sugerencia: Podría valer la pena incluir una pequeña nota sobre el uso de dependencias (ya que es parte del sistema de encolado).

Correcto, pero lo mejor es que registres los estilos y scripts primero y luego los encoles mediante su ID. Esto es muy útil para que otros desarrolladores puedan modificar los scripts o usarlos en plugins personalizados. También facilita cambiar el orden o crear un archivo resumen.

Además, carga los scripts y estilos solo en las páginas donde se necesiten. http://scribu.net/wordpress/optimal-script-loading.html

Soporte para I18n
Todas las cadenas de salida deben estar vinculadas a un dominio de texto apropiado para permitir la internacionalización por parte de interesados, incluso si el desarrollador no tiene interés en traducir su propio plugin.
Ten en cuenta que es muy importante cargar los archivos de idioma durante la acción init
para que el usuario pueda engancharse a la acción.
Consulta el Codex: I18n para desarrolladores de WordPress
Y también este artículo: Cargando archivos de idioma de 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 desarrolladores y usuarios.
Considerando un plugin 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 allí, entonces buscará donde el plugin le indique (usualmente en la carpeta 'language' del plugin si sigue el codex):
/wp-content/plugins/my-plugin/languages/my-plugin-en_US.mo
Por último, si no se encuentra ningún archivo de idioma, verificará la ubicación predeterminada de:
/wp-content/languages/my-plugin-en_US.mo
La primera verificación fue añadida en 4.6 y les da a los usuarios un lugar definido para añadir un archivo de idioma, ya que antes necesitaban saber dónde el desarrollador añadió el archivo de idioma, ahora el usuario solo necesita conocer el dominio de texto del plugin: /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 personalizados del usuario desde WP_LANG_DIR antes de cargar los archivos de idioma que vienen con el plugin. Cuando se cargan múltiples archivos .mo para el mismo dominio, se usará la primera traducción encontrada. De esta manera, los archivos de idioma proporcionados por el plugin servirán como respaldo para cadenas no traducidas por el usuario.
public function load_plugin_textdomain()
{
$domain = 'my-plugin';
// El filtro "plugin_locale" también se usa en 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/'
);
}

Para mí el más importante. No es mucho trabajo extra hacerlo, pero es una de las cosas que puede hacer que tu plugin sea más útil para los millones de usuarios que no tienen el inglés como primer idioma. Ni siquiera tienes que traducir ninguna palabra tú mismo, sino preparar todo para que sea traducible.

Asegúrate de que los Plugins No Generen Errores con WP_DEBUG
Siempre prueba tus plugins con WP_DEBUG
activado y, idealmente, mantenlo activado durante todo tu proceso de desarrollo. Un plugin no debería generar NINGÚN error con WP_DEBUG
activado. Esto incluye avisos de funciones obsoletas e índices no verificados.
Para activar el modo de depuración, edita tu archivo wp-config.php
de modo que la constante WP_DEBUG
esté establecida en true
. Consulta la Guía de Depuración en el Codex para más detalles.

Por favor, revisa la ACTUALIZACIÓN sobre tener solo una mejor práctica por respuesta; ¿puedes dividirlo en múltiples respuestas?

Gracias, y no fue tu descuido, fue el mío. Revisé la pregunta para solicitar una mejor práctica por respuesta basado en la pregunta de @hakre sobre duplicados y cómo hacer que esto funcione.

Primero Usa Funciones Existentes en el Núcleo de WordPress
Si puedes: usa funciones existentes incluidas en el núcleo de WordPress en lugar de escribir las tuyas propias. Solo desarrolla funciones PHP personalizadas cuando no exista una función apropiada preexistente en el núcleo de WordPress.
Un beneficio es que puedes usar "log deprecated notices" para monitorear fácilmente funciones que deberían ser reemplazadas. Otro beneficio es que los usuarios pueden ver la documentación de la función en el Codex y entender mejor lo que hace el plugin incluso si no son desarrolladores PHP experimentados.
Relacionado

Uno de los mayores problemas aquí es descubrir que existe una función apropiada ya existente. Sería útil tener un lugar donde publicar código y/o necesidades de funcionalidad para que la comunidad pueda comentar sobre qué función utilizar. ¿Quizás StackExchange podría usarse para esto?

Uf. Eso sería bastante difícil y supongo que sería una tarea interminable. Creo que extender el codex de esta manera sería lo mejor, porque ya existe.

Supongo que extender el codex y quizás enlazar desde allí a hilos relacionados en StackExchange sería suficiente.

Un problema con eso es que gran parte del núcleo no está realmente diseñado estructuralmente para reutilización. Acabo de tener que copiar y modificar ligeramente la mitad de las funciones de manipulación de imágenes/metadatos para crear mi propio tipo de publicación que se comporte como un adjunto, simplemente porque una función como downsize() llama a alguna función que incluye una verificación codificada para post-type='attachment'. Hay muchos casos así, como el inflexible wp_count_posts() siendo otro ejemplo. Antes de que realmente puedas reutilizar el núcleo, WordPress necesita una refactorización completa.

La desinstalación debe eliminar todos los datos de un plugin
Al ser eliminado de una instalación de WordPress, un plugin debe borrar todos los archivos, carpetas, entradas de base de datos y tablas que haya creado, así como los valores de opciones que haya generado.
Los plugins pueden ofrecer una opción para exportar/importar configuraciones, de modo que los ajustes puedan guardarse fuera de WordPress antes de la eliminación.
Relacionado

Este debería ser el comportamiento predeterminado, sí, pero también debería preguntarle al usuario si desea conservar algunos datos... como cuando al desinstalar un videojuego te pregunta si quieres eliminar partidas guardadas y material descargado. Un usuario podría estar desactivando el plugin solo para pruebas y no querría tener que volver a configurar sus opciones cuando lo reactive.

Solo me refiero a cuando un plugin se elimina por completo, no cuando se desactiva.

Entiendo eso... pero a veces elimino plugins para poder volver a añadirlos manualmente desde una copia de seguridad o una versión beta que aún no está alojada en el repositorio...

@EAMann: Para eso y para migrar plugins a otro servidor, un plugin debería proporcionar un mecanismo para exportar e importar configuraciones.

@MikeSchinkel: Hecho: http://wordpress.stackexchange.com/questions/715/objective-best-practices-for-plugin-development/925#925

Esto se pasa por alto con tanta frecuencia. Ayer mismo encontré configuraciones y tablas enteras inflando mi base de datos. ¡Es tan molesto!

No estoy completamente seguro de estar de acuerdo. Si el plugin crea sus propias tablas de base de datos, sí, pero con los nuevos tipos de posts personalizados usándose para todo, pronto (esperemos) tendremos plugins compartiendo tipos de posts y demás. Esto puede hacer que el "borrado de datos" sea un tema bastante complicado.

He visto algunos plugins que ofrecen un botón de "Desinstalar" en sus configuraciones con grandes advertencias en rojo de que borrará todos los datos. Esto es independiente de la desactivación, y creo que es una gran manera de manejarlo. No todo el mundo usa el botón "Eliminar" para quitar un plugin.

Entonces, ¿cuál es la mejor práctica cuando un plugin crea un tipo de publicación personalizada e ingresa datos en ese tipo de publicación? ¿Deberían eliminarse esos datos o no? Si no es así, ¿hay algún plugin que podamos usar como guía para implementar el mismo botón de 'desinstalación'?

Prevenir Inyección SQL con Datos de Entrada
Un plugin debería sanitizar toda la entrada de usuario obtenida directa o indirectamente (ej. vía $_POST
o $_GET
) antes de usar los valores de entrada para consultar la base de datos MySQL.

También deberías sanitizar los datos que salen de la base de datos. Básicamente, nunca confíes en ningún dato que no esté hardcodeado. http://codex.wordpress.org/Data_Validation también es una buena referencia.

Usa una clase y código PHP orientado a objetos
No hay razón para no escribir código PHP limpio y orientado a objetos. PHP4 no es compatible desde 2008. Por supuesto, podrías prefijar todos tus nombres de funciones para terminar con nombres_de_funciones_interminablemente_largos_con_muchos_guiones_bajos
, pero es mucho más fácil simplemente escribir una clase simple y agrupar todo allí. Además, coloca tu clase en un archivo separado y nómbralo adecuadamente para que puedas extenderlo y mantenerlo fácilmente:
// en functions.php
require 'inc/class-mi-plugin-genial.php';
new MiPluginGenial();
// en inc/class-mi-plugin-genial.php
class MiPluginGenial {
function __construct() {
// añadir filtros, wp_enqueue_script, etc.
// Para asignar un método de tu clase a una función
// de WP, haz algo como esto
add_action('admin_menu', [$this, "admin"]);
}
public function admin() {
// métodos públicos, para usar fuera de la clase
// Nota que los métodos usados en otras funciones de WP
// (como add_action) deben ser públicos
}
private function algo_mas() {
// métodos que solo usas dentro de esta clase
}
}

no uses new MyCoolPlugin(); creo que es mejor que te enganches a WP mediante el Hook: plugins_loaded

No estoy seguro de eso. Según el codex, plugins_loaded es una de las primeras cosas que se cargan, así que creo que hay poca diferencia entre hacer un constructor así o añadirlo como una acción.

es solo una de esas mejores prácticas que hacen las cosas más agradables para todos.

Hasta donde puedo ver, agregar un hook a plugins_loaded no genera ninguna mejora, y no sería una mejor práctica ya que no hay ningún beneficio, más bien podría haber un aumento en el uso de memoria y una disminución en la velocidad ya que tiene que pasar por una acción en lugar de simplemente agregar las acciones. Además, el uso de OO no debería considerarse una mejor práctica.

¿Hay consenso sobre cómo crear el objeto, debería ser mediante un hook o no?

Esta es una gran idea, pero hay que tener cuidado de incluir el archivo de clase solo si el servidor es PHP5. Consulta https://github.com/iandunn/WordPress-Plugin-Skeleton/blob/master/bootstrap.php para ver un ejemplo.

Prefijar todos los elementos del espacio de nombres global
Un plugin debe prefijar correctamente TODOS los elementos del espacio de nombres global (constantes, funciones, clases, variables, e incluso cosas como taxonomías personalizadas, tipos de post, widgets, etc.). Por ejemplo, no crees una función llamada init()
; en su lugar, nómbrala algo como jpb_init()
.
Es común usar un prefijo de tres o cuatro letras delante de los nombres o hacer uso de la Función de Espacios de Nombres (Namespaces) de PHP. Compara: ¿Prefijo de una sola letra para constantes de clase en PHP?
Relacionado

La desactivación no debe provocar pérdida de datos
Un plugin no debería eliminar ninguno de sus datos al desactivarse.
Relacionado

Anunciar Pérdida de Datos al Desinstalar un Plugin
Al desinstalar un plugin debería notificar al usuario que se eliminarán sus datos y recibir una confirmación de que el usuario está de acuerdo con la eliminación de los datos antes de proceder. Además, un plugin debería ofrecer al usuario la opción de conservar los datos durante la desinstalación. (Esta idea proviene de @EAMann.)
Relacionado

El propio WordPress muestra un mensaje de advertencia en el administrador, de que esto sucede (al menos en la versión trunk actualmente).

Además del mensaje de advertencia que muestra WordPress, es imposible que el plugin solicite confirmación al usuario, ya que al momento de la desinstalación ya está desactivado. Pero consulta el ticket #20578.

Permitir que el nombre de la carpeta del plugin sea cambiado
/plugins/nombreplugin/{varios}
El "nombreplugin" utilizado para la carpeta siempre debería poder cambiarse.
Esto normalmente se maneja definiendo constantes y usándolas consistentemente a lo largo del plugin.
No hace falta decir que muchos plugins populares pecan en esto.
Relacionado:
plugins_url()
para enlazar fácilmente a recursos incluidos con el plugin.

Renombrar la carpeta del plugin hará que las actualizaciones automáticas dejen de funcionar, así que no estoy seguro de que sea lo mejor que se puede hacer.

De todos modos tendrías que volver a activar el plugin después de hacer el cambio (el cambio de nombre probablemente desactivaría el plugin), momento en el cual WordPress volverá a crear o actualizar las entradas apropiadas en la base de datos relacionadas con los plugins (así que no rompería las actualizaciones en absoluto).

Minimizar los Nombres Agregados al Espacio de Nombres Global
Un plugin debería reducir su impacto tanto como sea posible minimizando el número de nombres que agrega al espacio de nombres global.
Esto se puede lograr encapsulando las funciones del plugin en una clase o utilizando la característica de espacios de nombres de PHP. Prefijar todo también puede ayudar, pero no es tan flexible.
Además de funciones y clases, un plugin no debería introducir variables globales. El uso de clases normalmente las hace obsoletas y simplifica el mantenimiento del plugin.
Relacionado

¿Puedes mover "no debería introducir variables globales" a su propia respuesta? Eso está relacionado pero separado de esta pregunta y en realidad es uno que me gustaría debatir (tanto porque creo que puedo estar en desacuerdo en casos especiales como porque quiero aprender de las opiniones de otros).

Usa el manejo de errores integrado en WordPress
No simplemente hagas return;
si algún dato del usuario está incorrecto. Proporciónales información sobre lo que salió mal.
function some_example_fn( $args = array() )
{
// Si el valor no fue establecido, construye un mensaje de error
if ( ! isset( $args['some_value'] ) )
$error = new WP_Error( 'some_value', sprintf( __( 'Has olvidado especificar el %1$s para tu función. %2$s Error generado en %3$s, línea %4$s.', TEXTDOMAIN ), '$args[\'some_value\']', "\n", __FILE__, __LINE__ ) );
// Finaliza e imprime el mensaje de error y código - ¡solo para administradores!
if ( isset( $error ) && is_wp_error( $error ) && current_user_can( 'manage_options' ) )
wp_die( $error->get_error_code(), 'Error del Tema: Argumento Faltante' );
// Si no se generó ningún error, continúa...
}
Un objeto de error para todos
Puedes configurar un objeto de error global para tu tema o plugin durante el arranque:
function bootstrap_the_theme()
{
global $prefix_error, $prefix_theme_name;
// Toma el nombre del tema como ID de error:
$theme_data = wp_get_theme();
$prefix_theme_name = $theme_data->Name;
$prefix_error = new WP_Error( $theme_data->Name );
include // lo que sea, etc...
}
add_action( 'after_setup_theme', 'bootstrap_the_theme' );
Luego puedes añadir errores ilimitados bajo demanda:
function some_theme_fn( $args )
{
global $prefix_error, $prefix_theme_name;
$theme_data = wp_get_theme();
if ( ! $args['whatever'] && current_user_can( 'manage_options' ) ) // algún valor requerido no establecido
$prefix_error->add( $prefix_theme_name, sprintf( 'La función %1$s necesita el argumento %2$s establecido.', __FUNCTION__, '$args[\'whatever\']' ) );
// continúa la función...
}
Luego puedes recuperarlos todos al final de tu tema. De esta manera no interrumpes la renderización de la página y aún puedes mostrar todos tus errores para desarrollo
function dump_theme_errors()
{
global $prefix_error, $prefix_theme_name;
// ¿No es administrador? O: ¿No hay error(es)?
if ( ! current_user_can( 'manage_options' ) ! is_wp_error( $prefix_error ) )
return;
$theme_errors = $prefix_error->get_error_messages( $prefix_theme_name );
echo '<h3>Errores del Tema</h3>';
foreach ( $theme_errors as $error )
echo "{$error}\n";
}
add_action( 'shutdown', 'dump_theme_errors' );
Puedes encontrar más información en esta pregunta. Un ticket relacionado para corregir el "funcionamiento conjunto" de WP_Error
y wp_die()
está enlazado desde allí y otro ticket seguirá. Comentarios, críticas y similares son apreciados.

¿Por qué creas una instancia de un objeto WP_Error si solo accedes a sus propiedades y nunca pasas la instancia como objeto?

@ProfK Lo rehice para que sea más corto y el título/contenido para wp_die();
estaba incorrecto (invertido). Respecto a tu pregunta) No lo entiendo completamente. Cuando configuras una instancia de la clase WP_Error tienes acceso completo a sus datos mediante funciones como get_error_code();
, get_error_message();
, get_error_data();
y sus versiones en plural. También podrías instanciarlo solo una vez durante el bootstrap de tu tema o plugin y simplemente usar $error->add();
para agregar otros errores y finalmente mostrarlos en el footer con $error->get_error_messages();
para capturarlos todos.

@ProfK Publicaré actualizaciones futuras en esta pregunta. Actualmente estoy investigando el comportamiento de la clase wp error y quiero escribir un ticket sobre una API pública de errores para temas (ya tengo un borrador hecho). Encontrarás un enlace a otro ticket que acerca WP_Error
y wp_die()
(ya tiene un parche) al final de la pregunta. Cualquier comentario, sugerencia, crítica y demás es muy apreciado.

Usa la API de Configuración antes que add_option
En lugar de agregar opciones a la base de datos mediante la función add_option, deberías almacenarlas como un array usando la API de Configuración que se encarga de todo por ti.
Usa la API de Modificaciones de Tema antes que add_option
La API de Modificaciones es una estructura bastante simple y una forma segura que permite agregar y recuperar opciones. Todo se guarda como valor serializado en tu base de datos. Fácil, seguro y simple.

Además, usa update_option
y nunca add_option
, la función de actualización creará la opción cuando no exista.. :)

No diría que nunca uses add_option
. Hay un buen caso de uso para add_option
donde si la opción ya está establecida, no se modifica, así que lo uso en la activación para preservar posibles preferencias de usuario ya existentes.

Comentar usando PhpDoc
La mejor práctica es seguir el estilo de PhpDoc. Si no utilizas un IDE como "Eclipse", puedes echar un vistazo al Manual de PhpDoc.
No es necesario que sepas 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 aficionados y los usuarios podrían apreciar la forma en que lo explicas al mismo nivel de conocimiento.

Proteger la Privacidad de los Usuarios del Plugin
(Anteriormente: Comunicación API Anónima)
Si un plugin 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 filtren datos relacionados con el usuario del plugin a un tercero sin control.

Aloja plugins en WordPress.org
Utiliza el repositorio SVN proporcionado en WordPress.org para alojar plugins. Ofrece una mejor experiencia de usuario para las actualizaciones y, si nunca has usado SVN antes, te permite entenderlo al usarlo en un contexto que lo justifica.

Proporcionar control de acceso mediante permisos
En muchos casos, los usuarios pueden no querer que todos tengan acceso a las áreas creadas por tu plugin, especialmente con plugins que realizan múltiples operaciones complejas, una única verificación de capacidad codificada puede no ser suficiente.
Como mínimo, implementa verificaciones de capacidades apropiadas para todos los diferentes tipos de procedimientos para los que se puede utilizar tu plugin.

Organiza tu código
Siempre es difícil leer código que no está escrito en el orden en que se ejecuta. Primero los include/require, definiciones, wp_enqueue_style & _script, etc., luego las funciones que el plugin/theme necesita y al final el constructor (ej. pantalla de administración, cosas que se integran en el theme, etc.).
Intenta separar cosas como css y js en sus propias carpetas. También intenta hacer esto con funciones que son solo ayudantes, como aplanadores de arrays y similares. Mantener el archivo "principal" lo más limpio y fácil de leer posible es una forma que ayuda a los usuarios, desarrolladores y a ti mismo, cuando intentas actualizar en un año y no has visto el código durante mucho tiempo.
También es bueno tener una estructura que repitas a menudo, para que siempre encuentres tu camino. Desarrollar en una estructura conocida en diferentes proyectos te dará tiempo para mejorarla e incluso si tu cliente cambia a otro desarrollador, nunca escucharás "dejó un caos". Esto construye tu reputación y debería ser un objetivo a largo plazo.

Temo que esto sea un poco demasiado sobre estilo que la gente debatiría y no sobre mejores prácticas objetivas con las que todas las personas respetadas estarían de acuerdo. Es muy importante que solo abordemos las mejores prácticas objetivas para que las personas estén dispuestas a aceptar "bendecir" la lista en lugar de tener elementos controvertidos, sin importar cuán bien intencionados sean.

Importar / Exportar Configuraciones del Plugin
No es muy común entre los plugins, pero si tu plugin tiene (algunas) configuraciones, debería proporcionar Importar/Exportar datos como configuración e información del usuario.
Importar/Exportar mejora la usabilidad de un plugin.
Un ejemplo de plugin que tiene esta funcionalidad de importación y exportación (y también un mecanismo de deshacer) es Breadcrumb NavXT (Plugin de WordPress) (transparencia total: hay algo de código mío ahí, aunque la mayoría fue hecho por mtekk).
Relacionado

Morir con estilo
morir de manera adecuada
Todas las funciones de los plugins (e incluso los temas) deberían utilizar wp_die()
en lugares críticos para ofrecer al usuario un poco de información sobre lo que ha ocurrido. Los errores de PHP son molestos y wp_die
puede dar al usuario un mensaje bien diseñado sobre lo que el plugin (o ellos) hicieron mal. Además, si el usuario tiene desactivado el modo de depuración, el plugin simplemente fallará.
Usar wp_die()
también ayuda a que tus plugins/temas sean compatibles con el conjunto de pruebas de WordPress.

Proporcionar pantallas de ayuda para los usuarios
Es mejor responder RTFM (haz clic en ayuda) que tener que contestar la misma pregunta una y otra vez.
/**
* Añadir ayuda contextual para esta pantalla
*
* @param $rtfm
* @uses get_current_screen
*/
function ContextualHelp( /*string*/ $rtfm)
{
$current_screen = get_current_screen();
if ($current_screen->id == $this->_pageid)
{
$rtfm .= '<h3>El Plugin de WordPress - Pantalla A</h3>';
$rtfm .= '<p>Aquí hay algunos consejos: dona para mí ' .
}
return $rtfm;
}
add_action('contextual_help', array($this,'ContextualHelp'),1,1);
actualización / nota: (ver comentarios de kaiser): el ejemplo anterior debe usarse dentro de una clase

Debería estar en la caja de herramientas de todos (siempre que tengas que explicar una pantalla específica de la interfaz de administración). +1

Ofrece Formularios Extensibles
Cuando un plugin ofrece la posibilidad de introducir datos, siempre debe incluir un hook al final, justo antes del botón de "enviar" y/o "reiniciar", para que los desarrolladores puedan extender fácilmente el formulario no solo con campos, sino también con botones.
Ver: API de Configuración
Relacionado

Incluye siempre las funciones mediante Hook, no directamente.
Ejemplo:
No uses para incluir la clase del plugin via new sin hook
Usa el Hook plugins_loaded
// añade la clase a 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 ejemplo pseudo
//evita llamadas directas a este archivo donde no estén presentes los archivos core de WP
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() {
}
} // fin de la clase
function plugin_start() {
new plugin_class();
}
add_action( 'plugins_loaded', 'plugin_start' );
} // fin de class_exists
También puedes cargar via mu_plugins_loaded en instalaciones multisite, mira el codex para referencia de acciones: http://codex.wordpress.org/Plugin_API/Action_Reference Aquí también puedes ver cómo incluir WP con este hook: http://adambrown.info/p/wp_hooks/hook/plugins_loaded?version=2.1&file=wp-settings.php Yo uso esto muy a menudo y no es tan difícil y es temprano, mejor que un hard new class();

un pequeño ejemplo en vivo: [Plugin-svn-trunk-page]http://svn.wp-plugins.org/filter-rewrite-rules/trunk/filter-rewrite-rules.php y un ejemplo pseudo-código
`//evitar llamadas directas a este archivo cuando los archivos core de WP no estén presentes 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() { }
} // fin de la clase
function plugin_start() {
new plugin_class(); }
add_action( 'plugins_loaded', 'plugin_start' ); } // fin de class_exists`

La descripción de tu plugin debe detallar con precisión las funciones del mismo. Existen 10 plugins de publicaciones destacadas. Todos ellos muestran publicaciones destacadas, pero muchos tienen características diferentes. Debería ser fácil comparar tu plugin con otros similares al leer la descripción.
Debes evitar presumir de lo simple que es tu plugin a menos que realmente sea muy básico. Debes incluir enlaces útiles en la descripción, como el enlace a la configuración.

Plugins con Licencia Compatible con GPL
Los plugins y temas deberían estar licenciados bajo una licencia compatible con WordPress. Esto permite que puedan ser redistribuidos con WordPress como un "programa". Una licencia recomendada es la GPL. Asegúrate de que todas las bibliotecas de código incluidas con el plugin sean compatibles con la misma licencia.
(Esto ha sido un problema y un serio punto de debate tanto en el pasado como en el presente.)

Dejemos eso sobre la compatibilidad con GPL por el momento: http://core.trac.wordpress.org/ticket/14685

Minimizar los efectos secundarios de fuentes de datos remotos y servicios web
Un plugin debería cachear/proteger servicios web y/o solicitudes XMLRPC/SOAP a través de una capa de caché/proveedor de datos si los utiliza, para evitar que las solicitudes frontales esperen respuestas (lentas) del servicio web.
Esto incluye la descarga de feeds RSS y otras páginas. Diseña tus plugins para que soliciten datos en segundo plano.
Un posible PASO es (tomando como ejemplo el envío a ping.fm): Crear una tabla buffer, por ejemplo: ping_fm_buffer_post( fecha, hora, mensaje, tiempo_envio, estado )
- Cada vez que quieras enviar una actualización a ping.fm, añádela a esta tabla.
- Ahora, necesitamos crear un plugin para manejar estos datos. Este plugin se ejecutará mediante crontab para verificar cada actualización que aún no se haya enviado
- Como tenemos esta tabla, también podemos listar 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 reenviarlo.

Realmente no entiendo exactamente hacia dónde vas con esto. ¿Puedes proporcionar algunos enlaces a material de apoyo?

Además, no estoy completamente seguro de qué es exactamente "Net Overhead". ¿No hay un término mejor? Si fuera más claro, sería una regla objetiva mejor. Y "Prevent" es imposible; ¿"Minimize" en su lugar?

Usa los Estándares de Codificación de WordPress
http://codex.wordpress.org/WordPress_Coding_Standards
¿Sabes lo mucho más fácil que es actualizar código en el que has trabajado versus el código que otra persona ha creado? Los estándares de codificación facilitan que cualquier desarrollador que trabaje en un proyecto pueda entender rápidamente lo que está pasando.
Sabemos que tu plugin o tema es tuyo, y la forma en que rompes tus líneas y añades tus llaves es una expresión de tu individualidad. Cada sangrado es una declaración cuidadosamente pensada. Pero con tu código personalizado, estás contribuyendo a WordPress, incluso si tu código no está en la aplicación principal. Los estándares de codificación ayudan a los desarrolladores a familiarizarse rápidamente con tu código.
