Escribiendo Plugins Extensibles Con Acciones y Filtros

Una de las muchas cosas que encontrará al investigar el código fuente de un buen desarrollador de complementos son los enlaces y filtros personalizados que el desarrollador ha colocado a lo largo del complemento. La presencia de estos ganchos y filtros de acción hace que el complemento sea "extensible", lo que significa que otros complementos y temas pueden manipularse o agregarse al comportamiento del complemento..

Escribir complementos extensibles es algo que me gustaría recomendar encarecidamente que hagas. Hay un mucho de grandes razones por las que debe hacerlo, pero muy pocas (si las hay) razones por las que debe evitar esta práctica.

Vamos a ver varios elementos de los complementos extensibles:

  • Una explicación de lo que son los complementos extensibles
  • Razones por las que deberías escribir complementos extensibles
  • Las herramientas básicas que necesitas.
  • Cómo necesitas escribir tus plugins para hacerlos extensibles
  • Ejemplos simples de ganchos y filtros para ilustrar cómo podría usarlos

Una nota importante: este tutorial utilizará técnicas de programación puramente basadas en procedimientos. Todo lo que menciono aquí todavía se aplica cuando se usa Programación Orientada a Objetos (OOP), pero es más sencillo aprender estas técnicas primero en un entorno de procedimiento..


¿Qué es un complemento extensible??

Un complemento extensible puede modificarse y extenderse más allá de su propósito original mediante otro complemento o tema. Cuando un complemento es extensible, otros complementos (o temas) pueden alterar el comportamiento o la salida del complemento. Por ejemplo, los complementos de comercio electrónico permiten pasarelas de pago adicionales que permiten que las compras se procesen a través de sistemas de pago adicionales. Estas pasarelas de pago son complementos separados que simplemente se conectan al complemento central y extienden su funcionalidad.

Cualquiera y todos los complementos pueden ser extensibles, aunque solo una pequeña minoría de los complementos publicados lo son. Para ser extensible, o modular (otro término para la misma cosa), el desarrollador de un plugin debe tomar una decisión consciente para hacerlo de esa manera implementando los elementos necesarios que hacen posible que otros plugins y temas se vinculen al plugin del core. comportamiento.


Por qué escribir complementos extensibles?

Hay muchas buenas razones para escribir complementos extensibles, pero una de las principales razones es que simplemente no hay una buena razón no para escribir sus complementos de esta manera, especialmente cuando los complementos se publican en la comunidad de WordPress, ya sea como complementos gratuitos o de pago.

Cuando escribe complementos extensibles, hace posible que otros desarrolladores extiendan su complemento y lo hagan aún mejor, pero sin cambiar el código fuente principal. También hace que sea mucho más fácil para los desarrolladores y usuarios adaptar el complemento para que se adapte mejor a sus necesidades. Permítame darle un ejemplo: en mi plugin Easy Digital Downloads hay un sistema de códigos de descuento. Los códigos de descuento están restringidos a un solo uso por usuario, por lo que si un usuario intenta aplicar el mismo descuento en dos compras diferentes, recibirá un error. Uno de mis usuarios del mundo real descubrió que no quería limitar los descuentos a un solo uso por usuario, por lo que le asigné la función simple de que introdujo un nuevo complemento personalizado y se eliminó la restricción, sin tocar ningún código principal..

El código extensible también hace que otros desarrolladores se sientan extremadamente felices cuando lo encuentran porque su tarea de adaptar su código es ahora mucho más fácil.


Las herramientas / funciones básicas

Hay varias herramientas clave que necesita para escribir complementos extensibles. Si ha escrito algún complemento o tema antes de leer esto, es probable que esté al menos algo familiarizado con estas funciones, aunque solo sea porque las ha visto usadas..

Antes de mostrarle las funciones que utilizará, hablemos primero de dos conceptos principales: manos y filtros.

Un gancho de acción es un lugar en su complemento que se puede "enganchar" en las funciones (tanto en su complemento como en otros complementos) para que su código se ejecute en ese punto. Cuando se ejecuta un gancho de acción, todas las funciones que están conectadas, o "enganchadas", también se ejecutarán.

Un gancho de filtro también es un lugar en su complemento para que otras funciones se vinculen, pero funcionan de manera ligeramente diferente a las acciones. Los filtros permiten que los datos sean manipulados o modificados antes de ser utilizados.

La diferencia clave entre las acciones y los filtros es que las acciones se usan generalmente para ejecutar funciones y los filtros se usan para manipular datos.

A menos que ya esté muy familiarizado con las acciones y los filtros, le recomiendo encarecidamente que vaya a leer la entrada del Codex en ellos..

Para las acciones hay cuatro funciones principales:

  • acción_ () - Esto define una ubicación enganchable para acciones.
  • add_action () - esto adjunta una función a un gancho creado con acción_ ()
  • has_action () - Esto verifica si una acción ha sido registrada con acción_ ()
  • remove_action () - Esto elimina una acción que se estableció con add_action ()

De estos cuatro, usarás acción_ () y add_action () lo mas.

Para los filtros también hay cuatro funciones principales:

  • apply_filters () - esto crea una ubicación enganchable para que los filtros personalizados se unan a
  • Añadir filtro() - esto adjunta un filtro personalizado a un gancho creado con apply_filters ()
  • has_filter () - Esto comprueba si un filtro ha sido registrado con apply_filters ()
  • remove_filter () - Esto elimina un filtro previamente conectado a apply_filters ()

Como con las acciones, apply_filters () y Añadir filtro() son los dos que más usarás.

Si está confundido en este punto, no se preocupe, veremos cómo usarlos en la próxima sección..


Implementación en tus propios plugins

Para que su complemento sea realmente extensible, debe utilizar las funciones clave mencionadas anteriormente en todo el complemento. Al principio, puede que le resulte difícil, engorroso, molesto o muchos otros adjetivos aplicables, colocar constantemente estas funciones adicionales en todo su código, especialmente cuando no ve un beneficio o uso inmediato para ellas..

Sin embargo, lo que encontrará es que una vez que tenga la costumbre de escribir sus complementos con todas estas funciones en mente, se convertirá en una segunda naturaleza incluirlos..

Hay algunos escenarios principales en los que usarás filtros en tus complementos:

  • Cuando los arreglos están configurados. Los filtros se agregarán aquí para que otros complementos puedan modificar los datos antes de que se usen..
  • Cuando los objetos de datos están configurados. Al igual que con los arrays, utilizará un filtro en los objetos para que otros desarrolladores puedan alterar el objeto antes de usarlo..
  • Cuando las cadenas de datos están configuradas. Con un filtro disponible en una cadena, otros desarrolladores pueden cambiar la cadena completa, alterar partes de ella o agregarla.

De los escenarios anteriores, es más común usar filtros cuando se devuelven datos o justo antes de usarlos. Por ejemplo, si tiene un complemento que realiza una consulta de publicaciones, es mejor pasar la matriz de argumentos de consulta a través de un filtro antes de pasarlos a get_posts () o WP_Query Para que otros puedan manipular la consulta antes de realizarla..

Cuando se trata de acciones, también hay varias instancias principales en las que los colocará:

  • Antes de que se ejecute una tarea.
  • Después de que se ejecuta una tarea.
  • Dentro de su marcado para permitir que se inserte un marcado adicional.

Consideremos algunos ejemplos ahora.

1. Visualización de HTML con un código corto

Los códigos cortos que generan HTML son extremadamente comunes (en realidad son probablemente los más comunes de todos los códigos cortos), y una de las maneras en que podemos hacer que los códigos cortos de nuestros complementos sean más amigables para otros desarrolladores es proporcionarles una manera de alterar el contenido de los códigos. código abreviado, pero sin necesidad de que se cancele el registro y se vuelva a registrar.

Todos los códigos cortos devuelven en lugar de hacer eco de su contenido, lo que significa que los datos que se envían a la pantalla tendrán la forma de una cadena antes de que se devuelvan. Debido a que toda la salida HTML tiene la forma de una cadena, puede pasar la cadena a través de un filtro antes de devolverla. Si lo hace, será posible que otros desarrolladores alteren el HTML de su código corto.

Es posible que un desarrollador desee agregar un marcado adicional antes y después del HTML predeterminado: con el filtro en su lugar, pueden hacerlo.

Su shortcode puede verse algo como esto:

 función wptp_sample_shortcode (atts, $ content = null) $ html = '
'; $ html. = '

Contenidos del código abreviado de muestra.

'; $ html. = '
'; devuelve $ html;

Podemos mejorar esto agregando un filtro a la devolución, así:

 función wptp_sample_shortcode (atts, $ content = null) $ html = '
'; $ html. = '

Contenidos del código abreviado de muestra.

'; $ html. = '
'; devolver apply_filters ('wptp_shortcode_html', $ html);

El HTML en nuestro código corto ahora se puede modificar de esta manera:

 función wptp_modify_html ($ html) return '
'. $ html. '
'; add_filter ('wptp_shortcode_html', 'wptp_modify_html');

Esto dará como resultado que el HTML original creado en el shortcode se incluya con otro div etiqueta.

2. Consultando mensajes

Realizar consultas personalizadas en complementos es una práctica común. Supongamos por un momento que ha escrito un complemento que registra un tipo de publicación personalizada llamada "libros", y en su complemento hay una función para mostrar los libros creados. Su función para consultar los libros podría ser algo como esto:

 función wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5); $ books = new WP_Query ($ query_args); if ($ books-> have_posts ()): while ($ books-> have_posts ()): $ books-> the_post () // muestra información sobre cada libro aquí mientras tanto; terminara si; wp_reset_postdata (); 

Pero, ¿qué sucede si un usuario desea modificar los tipos de libros que se devolvieron, tal vez seleccionando solo libros de una categoría específica? Puedes hacer esto mucho más fácil para ellos haciendo esto:

 función wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args)); if ($ books-> have_posts ()): while ($ books-> have_posts ()): $ books-> the_post () // muestra información sobre cada libro aquí mientras tanto; terminara si; wp_reset_postdata (); 

El único cambio que hice fue agregar un filtro alrededor del $ query_args, lo que significa que otros desarrolladores (o usuarios) pueden modificar los argumentos de consulta antes de pasarlos a WP_Query. Por ejemplo, podríamos configurar la consulta para que solo muestre libros del autor 3 de esta manera:

 función wptp_alter_books_query ($ args) $ args ['author'] = 3; devuelve $ args;  add_filter ('wptp_books_query', 'wptp_alter_books_query');

3. Extendiendo el marcado

Vamos a extender el ejemplo número 2 ahora y hacerlo aún mejor. Ya agregamos un filtro que permite a los usuarios modificar la consulta, ahora vamos a agregar algunos enlaces para permitirnos modificar el HTML que se crea..

Primero modificaremos un poco nuestro HTML original:

 función wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args); if ($ books-> have_posts ()): echo '
'; while ($ books-> have_posts ()): $ books-> the_post () echo '
'; eco '

'. get_the_title (). '

'; eco '
'; al final eco '
'; terminara si; wp_reset_postdata ();

Ahora nos gustaría hacer posible que los desarrolladores agreguen marcas adicionales en varios puntos, como los siguientes:

  • Antes de que se genere cualquier HTML
  • Después del final HTML
  • Antes del título de cada libro.
  • Después del título de cada libro.

Puedes imaginar un escenario en el que un usuario quisiera agregar una miniatura antes o después del título del libro. Para hacer esto posible, usamos acción_ () para crear ubicaciones enganchables, como esto:

 función wptp_show_books () $ query_args = array ('post_type' => 'books', 'posts_per_page' => 5, 'author' => 3); $ books = new WP_Query (apply_filters ('wptp_books_query', $ query_args)); if ($ books-> have_posts ()): do_action ('wptp_books_before'); eco '
'; while ($ books-> have_posts ()): $ books-> the_post () echo '
'; do_action ('wptp_before_book_title', get_the_ID ()); eco '

'. get_the_title (). '

'; do_action ('wptp_after_book_title', get_the_ID ()); eco '
'; al final eco '
'; do_action ('wptp_books_after'); terminara si; wp_reset_postdata ();

Tenga en cuenta que los dos ganchos interiores (que rodean el título) tienen un segundo parámetro de get_the_ID (). Esta variable, que será el ID del libro, estará disponible como un parámetro para cualquier función enganchada. Para agregar una miniatura de un libro, por ejemplo, podemos hacer esto:

 función wptp_show_book_image ($ book_id) echo get_the_post_thumbnail ($ book_id, 'thumbnail');  add_action ('wptp_before_book_title', 'wptp_show_book_image');

Ejemplos del mundo real

Ahora me gustaría mostrarle algunos ejemplos reales de complementos que son extensibles, incluyendo ejemplos de algunas de sus funciones extensibles..

1. soliloquio

Soliloquy es un potente plugin de control deslizante de imagen sensible a WordPress que hace que la creación y el mantenimiento de controles de imagen receptivos, eficientes, seguros y amigables con SEO sean una brisa.

Casi todo en este plugin es extensible. Aquí hay un solo ejemplo:

 $ labels = apply_filters ('tgmsp_post_type_labels', array ('name' => __ ('Soliloquy', 'soliloquy'), 'singular_name' => __ ('Soliloquy', 'soliloquy'), 'add_new' => __ ( 'Add New', 'soliloquy'), 'add_new_item' => __ ('Add New Soliloquy Slider', 'soliloquy'), 'edit_item' => __ ('Edit Soliloquy Slider', 'soliloquy'), 'new_item' => __ ('New Soliloquy Slider', 'soliloquy'), 'view_item' => __ ('View Soliloquy Slider', 'soliloquy'), 'search_items' => __ ('Search Soliloquy Sliders', 'soliloquy') , 'not_found' => __ ('No Soliloquy Sliders found', 'soliloquy'), 'not_found_in_trash' => __ ('No Soliloquy Sliders found in trash', 'soliloquy'), 'parent_item_colon' => ", menu_name '=> __ (' Soliloquy ',' soliloquy '))); $ args = apply_filters (' tgmsp_post_type_args ', array (' labels '=> $ labels,' public '=> true, exclude_from_search' => true, ' show_ui '=> true,' show_in_admin_bar '=> false,' rewrite '=> false,' query_var '=> false,' menu_position '=> 100,' menu_icon '=> plugins_url (' css / images / menu-icon.png ', dirname (__FILE__)),' support '=> array (' title ')));

Así es como Thomas Griffin (el desarrollador del complemento) configura los argumentos para las etiquetas y atributos personalizados de tipo de publicación. La presencia de sus dos filtros., tgmsp_post_type_labels y tgmsp_post_type_args, que sea muy sencillo para otros desarrolladores cambiar el nombre del tipo de publicación del control deslizante o cambiar lo que el tipo de publicación admite.

2. bbPresione

De lejos, uno de mis complementos favoritos personales de todos los tiempos, bbPress es un complemento de foro con todas las funciones para WordPress. El complemento completo es un ejemplo perfecto de cómo hacer que sus complementos sean extensibles, ya que literalmente tiene acciones y filtros en todas partes. Tiene un filtro en particular que se aplica al recuperar el contenido de un foro:

 función bbp_get_forum_content ($ forum_id = 0) $ forum_id = bbp_get_forum_id ($ forum_id); // Compruebe si se requiere contraseña si (post_password_required ($ forum_id)) devuelve get_the_password_form (); $ content = get_post_field ('post_content', $ forum_id); devolver apply_filters ('bbp_get_forum_content', $ content, $ forum_id); 

Antes de que se devuelva el contenido del foro, se pasa a través de un filtro llamado bbp_get_forum_content eso hace posible que un desarrollador modifique el contenido antes de que se muestre.

3. Descargas digitales fáciles

Easy Digital Downloads, o EDD, es uno de mis complementos que fue creado para hacer que sea excepcionalmente fácil vender productos digitales a través de WordPress. Al igual que con la mayoría de los complementos de comercio electrónico, EDD tiene un proceso de pago que el comprador realiza para que puedan ingresar sus datos personales y de pago. Después de recopilar toda esa información, todo va a una pasarela de pago (un sistema para procesar el pago), pero antes de ir a la pasarela, se aplica un filtro que permite que los datos se manipulen antes de que el pago los utilice. sistema:

 $ purchase_data = apply_filters ('edd_purchase_data_before_gateway', $ purchase_data, $ valid_data);

La presencia de este filtro hace posible ajustar los montos de compra (quizás para descuentos especiales), agregar impuestos, quizás agregar o eliminar productos de la compra, y mucho, mucho más.


Conclusión

Los complementos extensibles benefician a todos: el desarrollador original, otros desarrolladores y los propios usuarios.

Hay tantas razones por las que debes escribir tus complementos teniendo en cuenta el código extensible, así que, ¿por qué no lo haces??

Las herramientas presentadas aquí son todo lo que necesita para comenzar. ¿Tener preguntas? Preguntar lejos!