{"id":230969,"date":"2022-12-18T19:28:00","date_gmt":"2022-12-18T16:28:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230969"},"modified":"2022-12-18T19:30:30","modified_gmt":"2022-12-18T16:30:30","slug":"widgets-de-wordpress-refactorizacion-parte-7","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-refactorizacion-parte-7\/","title":{"rendered":"Widgets de WordPress: Refactorizaci\u00f3n, Parte 7"},"content":{"rendered":"\n<p>En las \u00faltimas publicaciones, hemos trabajado mucho para llevar el c\u00f3digo al punto de refactorizaci\u00f3n que se tratar\u00e1 en este art\u00edculo.<\/p>\n<p>Espec\u00edficamente, hemos cubierto:<\/p>\n<ul>\n<li>manos,<\/li>\n<li>un <a href=\"https:\/\/tommcfarlin.com\/wordpress-widgets-part-4\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">registro<\/a> ,<\/li>\n<li>y <a href=\"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-refactorizacion-parte-3\/\" title=\"Suscriptores\">Suscriptores<\/a>.<\/li>\n<\/ul>\n<p>Todos estos van a desempe\u00f1ar un papel en lo que vamos a hacer hoy.<\/p>\n<h2>El modelo de widget de WordPress: refactorizaci\u00f3n, parte 7<\/h2>\n<p>Para aquellos que est\u00e1n familiarizados con la <a href=\"https:\/\/codex.wordpress.org\/Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de widgets de WordPress<\/a>, es probable que sepan que no ha cambiado mucho en los \u00faltimos a\u00f1os.<\/p>\n<p>Adem\u00e1s, en realidad solo consta de cuatro funciones (una de las cuales es el constructor):<\/p>\n<ol>\n<li>El constructor es responsable de establecer varias propiedades en el widget, m\u00e1s com\u00fanmente su nombre y su descripci\u00f3n.<\/li>\n<li>La funci\u00f3n de widget es responsable de representar el contenido del widget.<\/li>\n<li>La funci\u00f3n de formulario es responsable de mostrar el formulario en el \u00e1rea de administraci\u00f3n de WordPress cuando se trabaja con el widget.<\/li>\n<li>La funci\u00f3n de actualizaci\u00f3n es responsable de actualizar las opciones que se guardan en la base de datos (o inicializar y luego guardar las opciones que pueden no existir a\u00fan en la base de datos).<\/li>\n<\/ol>\n<p>Lo bueno es que este enfoque particular se logra al heredar una funcionalidad para la clase <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WP_Widget<\/a>.<\/p>\n<p>Sin embargo, el problema es que es mucho trabajo para una sola clase.<\/p>\n<p>En cambio, deber\u00edamos separar cada una de las funciones en su propia \u00e1rea de funcionalidad.<\/p>\n<p>Al igual que con cualquier cosa en la programaci\u00f3n, habr\u00e1 formas en las que algunas cosas est\u00e9n claras sobre c\u00f3mo se pueden hacer y luego habr\u00e1 algunas cosas que se pueden hacer de varias maneras.<\/p>\n<p>Lo que voy a presentar es c\u00f3mo lo estoy abordando por ahora. Esto podr\u00eda cambiar en el futuro, o tal vez no, y otros pueden tener una opini\u00f3n diferente al respecto.<\/p>\n<p>Independientemente, la implementaci\u00f3n estar\u00e1 mucho m\u00e1s orientada a objetos y le dar\u00e1 a cada clase su propio conjunto de responsabilidades.<\/p>\n<p>La primera pregunta, sin embargo, es \u00bfc\u00f3mo dividimos una clase con cuatro funciones y que hereda de una clase principal?<\/p>\n<h3>Actualizaci\u00f3n de Bootstrap<\/h3>\n<p>Primero, hay algunas cosas que debemos ajustar en el arranque del complemento. Es decir, tenemos que hacer lo siguiente:<\/p>\n<ol>\n<li>instanciar el Registro y ponerlo a disposici\u00f3n a trav\u00e9s del proyecto,<\/li>\n<li>actualizar la clase Plugin para que acepte un registro y cargue los suscriptores,<\/li>\n<li>revisar el arranque<\/li>\n<\/ol>\n<p>He aqu\u00ed un vistazo a los tres de los anteriores.<\/p>\n<h3>1 Instanciar el Registro<\/h3>\n<p>Dado que ya hemos cubierto esto anteriormente en la serie, deber\u00eda quedar claro c\u00f3mo hacerlo.<\/p>\n<p>Primero, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-00-instantiate-the-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">vea el siguiente c\u00f3digo<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('wpwBoilerplateRegistry', function() use ($registry) {\n    return $registry;\n});<\/code><\/pre>\n<p>A continuaci\u00f3n, tenga en cuenta que estamos instanciando el Registro (hablaremos de su espacio de nombres en un momento) y luego lo conectamos a un filtro personalizado que nos permite acceder a \u00e9l a trav\u00e9s del complemento cuando lo deseemos.<\/p>\n<h3>2 Actualizar la clase de complemento<\/h3>\n<p>A continuaci\u00f3n, debemos actualizar la clase de complemento principal (que reside en el\u00a0 directorio <strong>src<\/strong>) para que haga referencia al registro y cargue <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-01-update-the-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">a los suscriptores registrados<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\n\n\/**\n * The base class for this plugin. Maintains a copy of the registry and starts\n * all of the objects that should hook into WordPress.\n *\/\nclass Plugin\n{\n    \/**\n     * @var Registry a reference to the simple container used to maintain plugin objects\n     *\/\n    private $registry;\n\n    \/**\n     * @param Registry $registry a reference to the simple container used to maintain plugin objects\n     *\/\n    public function __construct(Registry $registry)\n    {\n        $this-&gt;registry = $registry;\n    }\n\n    \/**\n     * Iterates through each of the subscribers maintained in the registry and registers them\n     * to the proper WordPress hook.\n     *\/\n    public function start()\n    {\n        array_map(function ($subscriber) {\n            add_action($subscriber-&gt;getHook(), [$subscriber, 'load']);\n        }, $this-&gt;registry-&gt;getRegisteredSubscribers());\n    }\n}<\/code><\/pre>\n<p>Tenga en cuenta, sin embargo, que todav\u00eda no hemos configurado ning\u00fan suscriptor. Comenzamos esto anteriormente en la serie y ahora es el momento de volver a \u00e9l, pero lo haremos m\u00e1s tarde.<\/p>\n<p>Sin embargo, necesitamos <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-03-new-registry-function-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">agregar una funci\u00f3n<\/a>, incluso si es temporal, para que podamos agregar clases que no son suscriptores de eventos expl\u00edcitos:<\/p>\n<pre><code>&lt;?php\n\/**\n * @return array all of the the objects that aren't subscribers registered with WordPress\n *\/\npublic function getRegisteredObjects()\n{\n    $objects = [];\n    foreach ($this-&gt;registry as $object) {\n        if (!$object instanceof AbstractSubscriber) {\n            $objects[] = $object;\n        }\n    }\n\n    return array_filter($objects);\n}<\/code><\/pre>\n<p>Esto se reelaborar\u00e1 m\u00e1s adelante, ya que convertiremos las clases principales en suscriptores m\u00e1s adelante.<\/p>\n<h3>3 Revisar el Bootstrap<\/h3>\n<p>Antes de continuar, creo que es importante revisar el arranque. Aunque su encabezado y documentaci\u00f3n pueden variar, es importante tener en cuenta que estamos haciendo lo siguiente:<\/p>\n<ul>\n<li>espacio de nombres del arranque,<\/li>\n<li>impidiendo que se acceda al archivo,<\/li>\n<li>llamando al cargador autom\u00e1tico,<\/li>\n<li>configurar el registro,<\/li>\n<li>e iniciar el complemento.<\/li>\n<\/ul>\n<p>Parece mucho, pero <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-02-the-current-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">el c\u00f3digo es bastante corto<\/a> :<\/p>\n<pre><code>&lt;?php\n\/**\n * WordPress Widget Boilerplate\n *\n * The WordPress Widget Boilerplate is an organized, maintainable boilerplate for building\n * widgets using WordPress best practices.\n *\n * @package   WordPressWidgetBoilerplate\n * @author    Your Name &lt;email@example.com&gt;\n * @license   GPL-3.0+\n * @link      http:\/\/example.com\n * @copyright 2018 - 2019 Your Name or Company Name\n *\n * @wordpress-plugin\n * Plugin Name:       WordPress Widget Boilerplate\n * Plugin URI:        https:\/\/github.com\/tommcfarlin\/wordpress-widget-boilerplate\n * Description:       An object-oriented foundation for building WordPress Widgets.\n * Version:           1.0.0\n * Author:            Tom McFarlin\n * Author URI:        https:\/\/tommcfarlin.com\n * Text Domain:       widget-name\n * License:           GPL-3.0+\n * License URI:       http:\/\/www.gnu.org\/licenses\/gpl-3.0.txt\n * Domain Path:       \/lang\n *\/\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\nuse WordPressWidgetBoilerplatePlugin;\n\n\/\/ Prevent this file from being called directly.\ndefined('WPINC') || die;\n\n\/\/ Include the autoloader.\nrequire_once __DIR__. '\/vendor\/autoload.php';\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('wpwBoilerplateRegistry', function() use ($registry) {\n    return $registry;\n});\n\n\/\/ Start the machine.\n(new Plugin($registry))-&gt;start();\n<\/code><\/pre>\n<p>En este punto, sin embargo, es hora de ver c\u00f3mo es dividir la clase secundaria de la <a href=\"https:\/\/codex.wordpress.org\/Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">API de Widgets<\/a> est\u00e1ndar en algo que encaje con el modelo de c\u00f3digo con el que estamos trabajando.<\/p>\n<h2>Dividir una clase infantil<\/h2>\n<p>Es probable que esta parte abarque algunas publicaciones, ya que hay un poco de trabajo por hacer, pero comenzaremos creando nuestra propia clase de widget que heredar\u00e1 de la clase base de Widget.<\/p>\n<p>Primero, contin\u00fae y cree un\u00a0 directorio <strong>API<\/strong> en el\u00a0 directorio <strong>src<\/strong> y agregue un archivo llamado <strong>Widget.php<\/strong>. Aqu\u00ed es donde residir\u00e1n los conceptos b\u00e1sicos del widget. Nos ocuparemos de las hojas de estilo administrativas y p\u00fablicas y los archivos JavaScript en la pr\u00f3xima publicaci\u00f3n.<\/p>\n<p>En este punto, los conceptos b\u00e1sicos del archivo deber\u00edan <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-04-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">verse as\u00ed<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateAPI;\n\nuse WP_Widget;\n\nclass Widget extends WP_Widget\n{\n    \/**\n     * @var string unique identifier for your widget\n     *\/\n    protected $widgetSlug;\n\n    \/**\n     * Initializes the plugin by setting its properties and calling the parent class with the description.\n     *\n     * @param mixed $widgetSlug\n     *\/\n    public function __construct($widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n\n        \/\/ TODO: update description\n        parent::__construct(\n            $this-&gt;getWidgetSlug(),\n            __('Widget Name', $this-&gt;getWidgetSlug()),\n            [\n                'classname' =&gt; $this-&gt;getWidgetSlug().'-class',\n                'description' =&gt; __('Short description of the widget goes here.', $this-&gt;getWidgetSlug()),\n            ]\n        );\n    }\n\n    \/**\n     * Return the widget slug.\n     *\n     * @return string slug variable\n     *\/\n    public function getWidgetSlug()\n    {\n        return $this-&gt;widgetSlug;\n    }\n\n    \/**\n     * TODO: This is a temporary message to show that the Boilerplate has loaded.\n     *\/\n    public function load()\n    {\n        $html = '&lt;p style=\"text-align:center; background: #fff; padding: 1em; border: 1px dotted gray; margin: 2em 2em 2em 14em;\"&gt;';\n        $html .= 'The Widget Boilerplate is loaded.';\n        $html .= '&lt;\/p&gt;';\n        echo $html;\n    }\n}\n<\/code><\/pre>\n<p>Tenga en cuenta que se necesita un solo argumento. He usado el nombre del widget, pero puedes usar lo que quieras siempre que represente tu widget.<\/p>\n<p>Esto es para mostrar que la clase se est\u00e1 instanciando y cargando correctamente cuando se activa el complemento. Si no ve esto, entonces algo no est\u00e1 bien (lo cual revisaremos en un momento).<\/p>\n<p>A continuaci\u00f3n, es importante asegurarse de que esta clase se agregue al Registro. As\u00ed que agregue las siguientes l\u00edneas del c\u00f3digo <a href=\"https:\/\/gist.github.com\/tommcfarlin\/9c39ba3635c823f85447d0378c8976d2#file-05-add-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en el arranque:<\/a><\/p>\n<pre><code>&lt;?php\n\n\/\/ Add the Widget base class to the Registry.\n$registry-&gt;add('widget', new Widget('widget-name'));<\/code><\/pre>\n<p>Y ahora, cuando active el complemento, deber\u00eda ver lo siguiente:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160983-61e7189c9c671.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160983-61e7189c9c671.png\" alt=\"Widgets de WordPress: Refactorizaci\u00f3n, Parte 7\"><\/a><\/p>\n<p>De lo contrario, aseg\u00farese de revisar el c\u00f3digo en <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la rama de desarrollo<\/a> para asegurarse de que tiene todo lo que se describe en esta publicaci\u00f3n.<\/p>\n<h2>Implementaci\u00f3n de suscriptores<\/h2>\n<p>En las pr\u00f3ximas publicaciones, veremos c\u00f3mo podemos implementar suscriptores para el lado p\u00fablico del sitio (es decir, donde se muestra el contenido del widget). Y haremos lo mismo para el \u00e1rea de administraci\u00f3n del sitio.<\/p>\n<p>Finalmente, centraremos nuestra atenci\u00f3n en el c\u00f3digo responsable de proteger y serializar los datos (l\u00e9ase: actualizar nuestro widget) y luego ver c\u00f3mo se ve la versi\u00f3n final de un modelo actualizado.<\/p>\n<p>Sin embargo, en esta publicaci\u00f3n, la estrategia principal que estamos empleando es dividir una clase secundaria para que a\u00fan pueda usarse con otras clases usando interfaces y clases base que ya est\u00e1n definidas en el c\u00f3digo base.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>El problema con WP_Widget es que es mucho trabajo para una sola clase. Entonces comenzaremos a refactorizarlo ahora.<\/p>\n","protected":false},"author":1,"featured_media":236064,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[716],"tags":[1172],"class_list":["post-230969","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollador","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230969","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230969"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230969\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236064"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230969"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230969"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230969"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}