{"id":230437,"date":"2022-12-06T13:14:00","date_gmt":"2022-12-06T10:14:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230437"},"modified":"2022-11-09T22:23:25","modified_gmt":"2022-11-09T19:23:25","slug":"una-guia-simple-para-organizar-clases-centradas-en-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/una-guia-simple-para-organizar-clases-centradas-en-wordpress\/","title":{"rendered":"Una gu\u00eda simple para organizar clases centradas en WordPress"},"content":{"rendered":"\n<p>Una de las cosas en las que he estado haciendo un esfuerzo mucho m\u00e1s concertado, probablemente m\u00e1s que nunca antes, es gestionar la separaci\u00f3n de preocupaciones entre las clases responsables de la interfaz con WordPress y las responsables de trabajar con el dominio del problema.<\/p>\n<p>Por ejemplo, supongamos que est\u00e1 trabajando en un complemento y se comunicar\u00e1 con una API de terceros. Adem\u00e1s, este complemento tambi\u00e9n ofrecer\u00e1 men\u00fas, tipos de publicaciones, taxonom\u00edas, etc. dentro del \u00e1rea de administraci\u00f3n de WordPress.<\/p>\n<p>Aqu\u00ed hay dos \u00e1reas de responsabilidad:<\/p>\n<ol>\n<li>el \u00e1rea responsable de la soluci\u00f3n general del problema,<\/li>\n<li>el \u00e1rea responsable de la interfaz con WordPress.<\/li>\n<\/ol>\n<p>Puede argumentar que es importante realizar pruebas unitarias en las \u00e1reas que se comunican con WordPress, pero tambi\u00e9n s\u00e9 que estas son API probadas y verdaderas que tienen su propio conjunto de pruebas.<\/p>\n<p>En su lugar, deber\u00edamos centrarnos en las pruebas unitarias y separar nuestra l\u00f3gica empresarial de WordPress.<\/p>\n<p>Pero ese no es el punto de esta publicaci\u00f3n. En cambio, se trata m\u00e1s de una forma de dise\u00f1ar potencialmente un proyecto cuando una parte de \u00e9l se conectar\u00e1 con WordPress.<\/p>\n<p>He hablado sobre la importancia y las ventajas de los espacios de nombres en publicaciones anteriores para no profundizar demasiado en esa discusi\u00f3n aqu\u00ed.<\/p>\n<p>En cambio, me interesa hablar sobre la organizaci\u00f3n de archivos a nivel de sistema de archivos y de espacio de nombres, para que est\u00e9n claramente separados en sus \u00e1reas de especializaci\u00f3n y para que podamos asegurarnos de que estamos, digamos, enfocando nuestras pruebas unitarias (y otras pruebas) en las \u00e1reas que son m\u00e1s cr\u00edticas.<\/p>\n<h3>Abstracci\u00f3n de metacajas<\/h3>\n<p>Me gusta asegurarme de que mi estructura de directorios y archivos refleje la de mis espacios de nombres. Claro, ayuda con la organizaci\u00f3n de archivos, pero tambi\u00e9n con una organizaci\u00f3n conceptual.<\/p>\n<p>Es decir, si voy a trabajar con metaboxes, entonces s\u00e9 que probablemente pueda encontrar los archivos de metaboxes en un directorio anidado con el directorio principal de <strong>WordPress<\/strong> y luego dentro de un subdirectorio <strong>Admin<\/strong> seguido de un directorio <strong>MetaBox<\/strong>.<\/p>\n<p>Con ese fin, \u00bfc\u00f3mo se ver\u00eda un conjunto de clases dise\u00f1adas para trabajar con cajas meta si escribimos c\u00f3digo para ellas de manera reutilizable? Teniendo en cuenta lo que sabemos sobre los metaboxes, sabemos que probablemente necesitaremos lo siguiente:<\/p>\n<ul>\n<li>una clase abstracta que define el tipo de publicaci\u00f3n a la que se vincular\u00e1 cada metabox,<\/li>\n<li>dos funciones para el cuadro meta: una para registrarlo, otra para mostrar el contenido,<\/li>\n<li>un directorio para contener la vista o la presentaci\u00f3n del meta box,<\/li>\n<li>un archivo que servir\u00e1 como dicha vista.<\/li>\n<\/ul>\n<p>Teniendo en cuenta los puntos anteriores, quiz\u00e1s la estructura del directorio se ver\u00eda as\u00ed:<\/p>\n<\/p>\n<p>A continuaci\u00f3n, tenemos un c\u00f3digo que refleja esta estructura. Es decir, dentro de nuestro directorio de <strong>WordPress<\/strong>, tendr\u00edamos el subdirectorio <strong>Admin<\/strong> ya que el cuadro meta se muestra dentro del \u00e1rea de administraci\u00f3n de WordPress, y tendr\u00edamos el subdirectorio <strong>Ver<\/strong> que contendr\u00eda el archivo responsable de mostrar la informaci\u00f3n.<\/p>\n<p>Esto nos deja con la necesidad de crear algunas clases como se indica arriba. Quiz\u00e1s la clase base abstracta se <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-00-abstract-metabox-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ver\u00eda as\u00ed:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeWordPressAdminMetaBox;\n\nabstract class AbstractMetaBox\n{\n    protected $postType;\n\n    public function __construct()\n    {\n        $this-&gt;postType = 'acme_post_type';\n    }\n\n    abstract public function render();\n    abstract public function display();\n}\n<\/code><\/pre>\n<p>Luego, una implementaci\u00f3n concreta extender\u00eda la clase y se <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-01-acme-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ver\u00eda as\u00ed:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeWordPressAdminMetaBox;\n\nclass AcmeMetaBox extends AbstractMetaBox\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function render()\n    {\n        add_meta_box(\n            'acme-product-image',\n            'Product Image',\n            [$this, 'display'],\n            $this-&gt;postType,\n            'side',\n            'default'\n        );\n    }\n\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function display()\n    {\n        include_once plugin_dir_path(__FILE__).'Views\/acme-product-image.php';\n    }\n}\n<\/code><\/pre>\n<p>Y finalmente, la vista de la clase contendr\u00eda cualquier marca y c\u00f3digo de plantilla <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-02-acme-product-image-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">para representar la informaci\u00f3n<\/a><\/strong> :<\/p>\n<pre><code>&lt;div class=\"product-image-metabox\"&gt;\n    &lt;p&gt;\n        &lt;img src=\"&lt;?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?&gt;\" alt=\"&lt;?= esc_attr(get_the_title()); ?&gt;\" \/&gt;\n        &lt;input type=\"text\" value=\"&lt;?= esc_html(get_post_meta(get_the_ID(), 'product_image', true)); ?&gt;\" \/&gt;\n    &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>Esto nos brinda exactamente lo que necesitamos de una manera bien organizada y reutilizable para trabajar con metaboxes. Tambi\u00e9n se puede repetir para elementos como men\u00fas, tipos de publicaciones, taxonom\u00edas, etc.<\/p>\n<p>Pero yo divago.<\/p>\n<h3>Una palabra sobre las pruebas unitarias (con PHPUnit)<\/h3>\n<p>Como mencion\u00e9 anteriormente en la publicaci\u00f3n, creo que las clases de pruebas unitarias que resuelven problemas exclusivos de nuestro espacio de problemas son importantes. Esto significa que necesitar\u00eda decirle a su archivo de configuraci\u00f3n de PHPUnit que excluya sus archivos centrados en WordPress.<\/p>\n<p>La ventaja de lo que he expuesto anteriormente es que esto se vuelve trivialmente f\u00e1cil. En pocas palabras, puede <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/2fd7f50706c3f1767dc8b5c2b7deefff#file-03-phpunit-xml\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">agregar esto<\/a><\/strong> a su archivo <strong>phpunit.xml<\/strong> :<\/p>\n<pre><code>&lt;testsuites&gt;\n  &lt;testsuite name=\"Plugin\"&gt;\n    &lt;directory&gt;.\/tests&lt;\/directory&gt;\n    &lt;exclude&gt;.\/tests\/phpunit&lt;\/exclude&gt;\n    &lt;exclude&gt;.\/src\/WordPress&lt;\/exclude&gt;\n  &lt;\/testsuite&gt;\n&lt;\/testsuites&gt;<\/code><\/pre>\n<p>Esto le brinda la capacidad de concentrarse en escribir pruebas espec\u00edficamente para su espacio problem\u00e1tico mientras se asegura de que est\u00e1 escribiendo c\u00f3digo escalable, mantenible y reutilizable basado en WordPress.<\/p>\n<p>Actualmente estoy escribiendo un libro electr\u00f3nico (junto con una variedad de otro contenido premium). Si est\u00e1s interesado, <a href=\"https:\/\/tommcfarlin.com\/registration-info\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">echa un vistazo a lo que obtienes<\/a>.<\/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>Organizar el c\u00f3digo para las clases centradas en WordPress nos ayuda a centrarnos m\u00e1s en nuestro dominio tanto en t\u00e9rminos de resolver el problema como en t\u00e9rminos de escribir pruebas unitarias.<\/p>\n","protected":false},"author":1,"featured_media":236089,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[716],"tags":[1172],"class_list":["post-230437","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\/230437","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=230437"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230437\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236089"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230437"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230437"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230437"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}