{"id":230983,"date":"2022-12-19T17:13:00","date_gmt":"2022-12-19T14:13:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230983"},"modified":"2022-12-19T17:15:42","modified_gmt":"2022-12-19T14:15:42","slug":"widgets-de-wordpress-refactorizacion-parte-8","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-refactorizacion-parte-8\/","title":{"rendered":"Widgets de WordPress: Refactorizaci\u00f3n, Parte 8"},"content":{"rendered":"\n<p>Cuando se trata de refactorizar el est\u00e1ndar de widgets de WordPress, hemos trabajado mucho para llevar la base del c\u00f3digo a un est\u00e1ndar m\u00e1s orientado a objetos. Adem\u00e1s, hemos introducido una variedad de otras herramientas que nos permiten actualizar nuestro c\u00f3digo a est\u00e1ndares m\u00e1s modernos.<\/p>\n<p>Ahora que hemos pasado tiempo haciendo eso, es hora de volver al c\u00f3digo y comenzar a refactorizarlo de tal manera que permita el uso de <a href=\"https:\/\/wordpress.mediadoma.com\/es\/clases-abstractas-parte-1-comportamiento-de-abstraccion\/\" title=\"clases abstractas\">clases abstractas<\/a> y suscriptores (que funcionan como parte del <a href=\"https:\/\/wordpress.mediadoma.com\/es\/los-fundamentos-de-los-ganchos-de-accion-en-wordpress\/\" title=\"patr\u00f3n de dise\u00f1o basado en eventos\">patr\u00f3n de dise\u00f1o basado en eventos<\/a> ).<\/p>\n<p>Al final del post anterior, escrib\u00ed:<\/p>\n<blockquote>\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<\/blockquote>\n<p>As\u00ed que en esta publicaci\u00f3n, vamos a hacer exactamente eso. Espec\u00edficamente, vamos a comenzar trabajando en un suscriptor para el widget y luego hacer que el widget base se muestre primero en el lado administrativo del sitio.<\/p>\n<h2>El modelo de widget de WordPress: refactorizaci\u00f3n, parte 8<\/h2>\n<p>La raz\u00f3n por la que me interesa centrarme principalmente en el lado administrativo del sitio primero es que nos permite:<\/p>\n<ul>\n<li>obtener una idea de c\u00f3mo funcionan los suscriptores,<\/li>\n<li>ver c\u00f3mo ser\u00e1 necesario organizar la base de c\u00f3digo,<\/li>\n<li>codifique alguna informaci\u00f3n antes de trabajar con la serializaci\u00f3n.<\/li>\n<\/ul>\n<p>Una vez que todo esto est\u00e9 en su lugar, estaremos en una buena posici\u00f3n para centrar nuestra atenci\u00f3n en cosas m\u00e1s avanzadas. Es decir, podremos introducir suscriptores para mostrar informaci\u00f3n en el \u00e1rea de administraci\u00f3n y suscriptores para desinfectar, serializar, recuperar, validar y mostrar datos.<\/p>\n<p>Pero primero, hagamos el trabajo necesario para configurar una nueva clase, configurar el cargador autom\u00e1tico y mostrar contenido en el \u00e1rea administrativa del sitio.<\/p>\n<h3>1 El suscriptor abstracto<\/h3>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-00-abstract-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Primero revisemos<\/a> el suscriptor abstracto, ya que esto es lo que implementar\u00e1n todos los suscriptores.<\/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 WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * An abstract implementation of a subscriber that requires a hook and the ability to\n * start the class.\n *\/\nabstract class AbstractSubscriber\n{\n    \/**\n     * @var string a reference to the hook to which the subscriber should be registered\n     *\/\n    protected $hook;\n\n    \/**\n     * @param string $hook the hook to which the subscriber is registered\n     *\/\n    public function __construct(string $hook)\n    {\n        $this-&gt;hook = $hook;\n    }\n\n    \/**\n     * @return string the hook to which the subscriber is registered\n     *\/\n    public function getHook(): string\n    {\n        return $this-&gt;hook;\n    }\n\n    \/**\n     * Implements the domain logic for the concrete class implementating this subcriber.\n     *\/\n    abstract public function load();\n}\n<\/code><\/pre>\n<p>Tenga en cuenta que tiene dos funciones p\u00fablicas: la construcci\u00f3n que establece el gancho y una funci\u00f3n para recuperar el gancho. Tambi\u00e9n tiene una funci\u00f3n de carga abstracta que es donde cualquier clase que extienda esta clase implementa su funcionalidad espec\u00edfica.<\/p>\n<p>Recuerde que, debido a la forma en que WordPress maneja las acciones y los filtros, todo se adjunta a un gancho espec\u00edfico (ya sean los <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Hooks\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">que define WordPress<\/a> o los ganchos personalizados).<\/p>\n<h3>2 El espacio de nombres de WordPress<\/h3>\n<p>Cada vez que trabajo en una funcionalidad estrechamente relacionada con WordPress, trato de asegurarme de colocarla en un espacio de nombres de WordPress. Esto me indica a m\u00ed y a otros desarrolladores que lo que sea que resida en este espacio de nombres no se puede divorciar de la aplicaci\u00f3n principal.<\/p>\n<p>Entonces, dentro del\u00a0 directorio <strong>src<\/strong>, cree un\u00a0 directorio de <strong>WordPress<\/strong>. Aqu\u00ed es donde residir\u00e1 la clase principal Widget junto con cualquier otra clase que se presente a lo largo de esta serie.<\/p>\n<p>Esto significa que ya no necesitamos la clase en el directorio API. As\u00ed que aseg\u00farese de mover la clase, actualizar su espacio de nombres y eliminar el directorio. Tendr\u00e9 una captura de pantalla y algo de c\u00f3digo para esto un poco m\u00e1s tarde.<\/p>\n<p>Adem\u00e1s, recuerde que anteriormente en la serie colocamos el\u00a0 directorio <strong>Views<\/strong> en la ra\u00edz del\u00a0 directorio <strong>src<\/strong>, pero ahora podemos moverlo al\u00a0 directorio de <strong>WordPress<\/strong>. As\u00ed que adelante y haz eso ahora.<\/p>\n<p>El resultado final deber\u00eda ser algo como esto:<\/p>\n<p>Ahora podemos centrar nuestra atenci\u00f3n en el c\u00f3digo.<\/p>\n<h3>3 Una mirada a la clase de widgets<\/h3>\n<p>Vamos a simplificar un poco la clase de widget principal en esta publicaci\u00f3n. Va a deshacer parte del trabajo que hemos hecho, pero necesit\u00e1bamos ese trabajo previo para llegar a este punto.<\/p>\n<p>Por ahora, nos estamos enfocando en el constructor y la funci\u00f3n para recuperar el slug del widget. Esto es lo que finalmente nos permitir\u00e1 ver algo en el \u00e1rea administrativa de WordPress.<\/p>\n<p>Entonces, primero, aseg\u00farese de que su clase de Widget se vea <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-01-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">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 WordPressWidgetBoilerplateWordPress;\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        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}<\/code><\/pre>\n<p>A continuaci\u00f3n, dado que hemos movido este archivo al\u00a0 espacio de nombres de <strong>WordPress<\/strong>, necesitamos actualizar la secci\u00f3n de carga autom\u00e1tica de <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-02-composer-json\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">nuestro archivo de configuraci\u00f3n de Composer<\/a> :<\/p>\n<pre><code>\"autoload\": {\n    \"psr-4\": {\n        \"WordPressWidgetBoilerplate\": \"src\/\",\n        \"WordPressWidgetBoilerplateUtilities\": \"src\/Utilities\/\",\n        \"WordPressWidgetBoilerplateSubscriber\": \"src\/Subscriber\/\",\n        \"WordPressWidgetBoilerplateWordPress\": \"src\/WordPress\/\"\n    }\n},<\/code><\/pre>\n<p>A continuaci\u00f3n, necesitamos presentar un suscriptor.<\/p>\n<h3>4 Presentaci\u00f3n del suscriptor de widgets<\/h3>\n<p>Cada vez que tengo una clase central de alg\u00fan tipo, generalmente trato de crear un suscriptor simple que instancia la clase central y le permite hacer su trabajo.<\/p>\n<p>Hago esto porque WordPress, como se mencion\u00f3, usa el patr\u00f3n de dise\u00f1o basado en eventos, lo que significa que todo tiene que estar registrado en alg\u00fan tipo de gancho. Y no me gusta mezclar la l\u00f3gica de dominio con la misma clase que se conecta a WordPress. As\u00ed que los separo.<\/p>\n<p>Y eso es lo que hace un suscriptor. Se registra en WordPress y luego invoca la clase responsable de hacer el trabajo.<\/p>\n<p>Dicho esto, dirija su atenci\u00f3n al\u00a0 directorio de <strong>suscriptores<\/strong> y agregue una clase llamada <strong>WidgetSubscriber<\/strong>. En esa clase, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-03-widget-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">agregue el siguiente c\u00f3digo<\/a> :<\/p>\n<pre><code>&lt;?php\n\n&lt;?php\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\nuse WordPressWidgetBoilerplateWordPressWidget;\n\n\/**\n * Initializes the core Widget class that's used by WordPress to instantiate the widget,\n * renders the administrative area, provide serialization functionality, and displays the\n * public-facing view.\n *\/\nclass WidgetSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Registers the core Widget class using the WordPress APIs.\n     *\/\n    public function load()\n    {\n        register_widget(new Widget('widget-name'));\n    }\n}\n<\/code><\/pre>\n<p>El constructor registrar\u00e1 la clase con un gancho espec\u00edfico que revisaremos en un momento; luego usar\u00e1 la API de WordPress para crear una instancia de nuestro widget (que es lo que sucede en la\u00a0 funci\u00f3n de <strong>carga<\/strong> ).<\/p>\n<h3>5 El arranque<\/h3>\n<p>Finalmente, necesitamos actualizar el bootstrap para que:<\/p>\n<ul>\n<li>registra el <strong>WidgetSubscriber<\/strong> con el enlace adecuado,<\/li>\n<li>agrega el suscriptor al <strong>Registro<\/strong> ,<\/li>\n<li>e inicia el complemento (que hemos estado haciendo).<\/li>\n<\/ul>\n<p>El bootstrap, despu\u00e9s de todo esto, deber\u00eda verse <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-04-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed<\/a> :<\/p>\n<pre><code>&lt;?php\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\nuse WordPressWidgetBoilerplatePlugin;\nuse WordPressWidgetBoilerplateSubscriberWidgetSubscriber;\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\/\/ Add the Widget base class to the Registry.\n$registry-&gt;add('widgetSubscriber', new WidgetSubscriber('widgets_init'));\n\n\/\/ Start the machine.\n(new Plugin($registry))-&gt;start();<\/code><\/pre>\n<p>A continuaci\u00f3n, deber\u00eda poder iniciar sesi\u00f3n en WordPress y activar el complemento.<\/p>\n<h2>Una mirada al \u00e1rea administrativa<\/h2>\n<p>En este punto, no hay mucho que ver, pero estamos llegando all\u00ed. Primero, debe notar que el widget ahora aparece en el \u00e1rea que incluye los widgets disponibles:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160941-61e7175c46bcc.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-160941-61e7175c46bcc.png\" alt=\"Widgets de WordPress: Refactorizaci\u00f3n, Parte 8\"><\/a><\/p>\n<p>Y tambi\u00e9n deber\u00eda ver que cuando arrastra el widget a un \u00e1rea widgetizada (o cualquier barra lateral) no tiene opciones disponibles.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160941-61e7175f91557.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-160941-61e7175f91557.png\" alt=\"Widgets de WordPress: Refactorizaci\u00f3n, Parte 8\"><\/a><\/p>\n<p>Dicho esto, estamos en un buen lugar para seguir construyendo sobre lo que tenemos. Siempre puede seguir el seguimiento del desarrollo del modelo <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en GitHub<\/a>.<\/p>\n<h2>Continuando<\/h2>\n<p>A continuaci\u00f3n, continuaremos desarrollando funcionalidades para el \u00e1rea administrativa del widget. Despu\u00e9s de eso, centraremos nuestra atenci\u00f3n en el lado p\u00fablico del widget, as\u00ed como en la funcionalidad de serializaci\u00f3n.<\/p>\n<p>Deber\u00eda poder ver c\u00f3mo las cosas comienzan a tomar forma a medida que comenzamos a separar la l\u00f3gica en sus diversos componentes. Sin embargo, si no es as\u00ed, no se preocupe, hay mucho m\u00e1s por venir.<\/p>\n<p>Y la versi\u00f3n final de Boilerplate, por supuesto, demostrar\u00e1 todos los principios que estamos construyendo a lo largo de esta serie de publicaciones.<\/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>Comenzaremos desglosando los diversos componentes que forman parte de los widgets de WordPress, comenzando con el \u00e1rea administrativa.<\/p>\n","protected":false},"author":1,"featured_media":234945,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[716,840,861],"tags":[1172],"class_list":["post-230983","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollador","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230983","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=230983"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230983\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/234945"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230983"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230983"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230983"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}