{"id":229134,"date":"2022-11-04T12:29:00","date_gmt":"2022-11-04T09:29:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229134"},"modified":"2022-11-09T05:42:42","modified_gmt":"2022-11-09T02:42:42","slug":"creacion-rapida-de-prototipos-de-prototipo-a-codigo-parte-2","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/creacion-rapida-de-prototipos-de-prototipo-a-codigo-parte-2\/","title":{"rendered":"Creaci\u00f3n r\u00e1pida de prototipos: de prototipo a c\u00f3digo, parte 2"},"content":{"rendered":"\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/es\/creacion-rapida-de-prototipos-prototipo-a-codigo-parte-1\/\" title=\"La publicaci\u00f3n anterior\" >La publicaci\u00f3n anterior<\/a> demuestra mucho trabajo al tomar algo que alguna vez fue un prototipo r\u00e1pido y convertir ese prototipo en c\u00f3digo. Si no ha estado siguiendo, hemos hecho lo siguiente:<\/p>\n<ol>\n<li>habl\u00f3 y construy\u00f3 un prototipo para un complemento,<\/li>\n<li>diagramado, un enfoque orientado a objetos puede funcionar,<\/li>\n<li>y refactorizamos nuestro prototipo al c\u00f3digo real.<\/li>\n<\/ol>\n<p>En este punto, hay algunas cosas m\u00e1s que podemos hacer para mejorar nuestro c\u00f3digo. Es decir, podemos introducir el concepto de espacios de nombres. Esto lleva a la organizaci\u00f3n un paso m\u00e1s all\u00e1 y puede pagar dividendos para proyectos m\u00e1s grandes.<\/p>\n<p>As\u00ed que aqu\u00ed hay un vistazo a c\u00f3mo se desarrolla esto en nuestro proyecto actual.<\/p>\n<h2>Prototipo a c\u00f3digo: espacios de nombres<\/h2>\n<p>He cubierto los espacios de nombres en profundidad en publicaciones anteriores. Si no lo has le\u00eddo, <a href=\"https:\/\/wordpress.mediadoma.com\/es\/espacios-de-nombres-y-carga-automatica-en-wordpress\/\" title=\"te lo recomiendo\" >te lo recomiendo<\/a>. Luego regresa y mira el resto de la publicaci\u00f3n.<\/p>\n<p>Si opta por omitir el art\u00edculo, aqu\u00ed hay <a href=\"https:\/\/php.net\/manual\/en\/language.namespaces.rationale.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">una breve definici\u00f3n de un espacio de nombres<\/a> :<\/p>\n<blockquote>\n<p>Los espacios de nombres est\u00e1n dise\u00f1ados para resolver dos problemas que encuentran los autores de bibliotecas y aplicaciones al crear elementos de c\u00f3digo reutilizables, como clases o funciones&#8230;<\/p>\n<\/blockquote>\n<p>Y la idea general es que organizamos nuestras clases en base a una relaci\u00f3n l\u00f3gica que tienen entre s\u00ed.<\/p>\n<p>Adem\u00e1s, tambi\u00e9n organizamos los archivos dentro de directorios que coinciden con el espacio de nombres. Esto no es algo que deba hacerse, pero creo que es \u00fatil tener las clases organizadas l\u00f3gicamente en el disco de la forma en que est\u00e1n organizadas virtualmente en el espacio de nombres.<\/p>\n<p>Dicho esto, organicemos los archivos.<\/p>\n<h3>Organizar los archivos<\/h3>\n<p>En lugar de comenzar con el archivo del complemento principal, comencemos organizando nuestros archivos primero.<\/p>\n<ul>\n<li>Los archivos Meta Box y Meta Box Display residir\u00e1n en un directorio llamado <strong>Display<\/strong>. Esto es completamente arbitrario, pero dado que eso es lo que hacen esos archivos, parece tener sentido que all\u00ed residan.<\/li>\n<li>Tambi\u00e9n podemos colocar los archivos <strong>message-description.php<\/strong> y <strong>no-post-list.php<\/strong> en ese directorio, pero col\u00f3quelos en un subdirectorio llamado <strong>Vistas<\/strong>. Es posible que desee llamar a esto <strong>Plantillas<\/strong> o <strong>Parciales<\/strong> o algo similar.<\/li>\n<li>A continuaci\u00f3n, tenemos las clases responsables de consultar la base de datos y la clase responsable de coordinar la mensajer\u00eda. Coloquemos cada uno de estos en <strong>Utilidad.<\/strong> Hay otros lugares a los que podr\u00edan ir, claro, pero recuerde que el prop\u00f3sito es demostrar c\u00f3mo usar los espacios de nombres. Entonces, si se siente tan inclinado, si\u00e9ntase libre de ajustar sus archivos para que se adapten a sus gustos.<\/li>\n<\/ul>\n<p>Si ha seguido lo que tenemos arriba, entonces deber\u00eda tener una estructura de directorios que se vea as\u00ed:<\/p>\n<p>Una forma de organizar sus archivos.<\/p>\n<p>Ahora es el momento de definir espacios de nombres para cada una de las clases. Dado que los hemos organizado todos en sus directorios, ser\u00e1 f\u00e1cil especificar un espacio de nombres; sin embargo, es importante reconocer que necesitaremos usar la\u00a0 palabra clave <strong><a href=\"https:\/\/php.net\/manual\/en\/language.namespaces.importing.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">use<\/a><\/strong> cuando usemos clases ubicadas en otros espacios de nombres.<\/p>\n<p>Repasemos cada uno de nuestros archivos comenzando con los archivos en <strong>Utility<\/strong>. Primero, comenzaremos con <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-00-post-messenger-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Post Messenger<\/a> :<\/p>\n<pre><code>&lt;?php\n\/**\n * Display content for the meta box when requested.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\n\nnamespace McFarlinTRPUtility;\nuse McFarlinTRPUtilityPost_Query;\n\n\/**\n * Retrieves information from the class responsible for querying the database and\n * renders it in the context of our meta box when called via the Meta Box Display.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Post_Messenger {\n  \/\/ Snip for brevity. \n}<\/code><\/pre>\n<p>Notar\u00e1 que el espacio de nombres del archivo aparece en el encabezado junto con una declaraci\u00f3n para usar la\u00a0 clase <strong>Post Query<\/strong> que creamos. He agregado el nombre de la clase al final del espacio de nombres, por lo que no tengo que usarlo en todo el c\u00f3digo base.<\/p>\n<p>Observe que el constructor ahora se ve <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-01-post-messenger-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Instantiates the class by setting a reference to the query.\n *\n * @param string $plugin_dir The path to the root of the plugin directory.\n *\/\npublic function __construct( $plugin_dir) {\n\n    $this-&gt;query      = new Post_Query();\n    $this-&gt;plugin_dir = trailingslashit( $plugin_dir );\n}<\/code><\/pre>\n<p>He agregado un\u00a0 argumento <strong>$plugin_dir<\/strong> porque necesitamos usarlo para mostrar correctamente los resultados de la consulta. Y dado que ahora residen en un \u00e1rea diferente de la aplicaci\u00f3n, las funciones se ven <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-02-post-messenger-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Displays the description of the content of the meta box.\n *\n * @access private\n *\/\nprivate function get_post_message() {\n    include_once $this-&gt;plugin_dir. 'Display\/Views\/post-list.php';\n}\n\n\/**\n * Displays the description of the content of the meta box.\n *\n * @access private\n *\/\nprivate function get_description() {\n    include_once $this-&gt;plugin_dir. 'Display\/Views\/message-description.php';\n}\n\n\/**\n * Displays a message of there are no recent posts.\n *\n * @access private\n *\/\nprivate function get_no_posts_message() {\n    include_once $this-&gt;plugin_dir. 'Display\/Views\/no-post-list.php';\n}<\/code><\/pre>\n<p>A continuaci\u00f3n, veamos la\u00a0 clase <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-03-post-query-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Post Query<\/a>. No ha cambiado mucho en esta clase, excepto que le hemos dado un espacio de nombres, y tambi\u00e9n hemos actualizado la consulta solo para retirar tres publicaciones (seg\u00fan <a href=\"https:\/\/tommcfarlin.com\/prototype-to-code-1\/#comment-911828\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">este comentario<\/a> ).<\/p>\n<pre><code>&lt;?php\n\nnamespace McFarlinTRPUtility;\n\n\/**\n * Queries the database for three most recent posts. Returns the query to the\n * caller so that it can be interrogates for posts or not.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Post_Query {\n\n  \/\/ Snip for brevity.\n\n    private function get_posts() {\n\n        $args = array(\n            'post_type'        =&gt; 'post',\n            'post_status'      =&gt; 'publish',\n            'posts_per_page' =&gt; 3,\n            'orderby'          =&gt; 'date',\n            'order'            =&gt; 'desc',\n        );\n        $this-&gt;query = new WP_Query( $args );\n\n        return $this-&gt;query;\n    }\n}<\/code><\/pre>\n<p>Observe en el c\u00f3digo que tambi\u00e9n <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/WP_Query\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">prefij\u00e9 WP_Query<\/a> con una barra inclinada porque es parte del espacio de nombres global.<\/p>\n<p>Vayamos al\u00a0 directorio <strong>Display<\/strong> y echemos un vistazo a <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-04-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la clase Meta Box<\/a>. A esto tambi\u00e9n se le ha asignado un espacio de nombres y tambi\u00e9n est\u00e1 usando el nombre completo de la\u00a0 clase <strong>Meta Box Display<\/strong> que veremos en un momento.<\/p>\n<pre><code>&lt;?php\n\n namespace McFarlinTRPDisplay;\n use McFarlinTRPDisplayMeta_Box_Display;\n\n\/**\n * Registers the Meta Box with WordPress. Defines the ID, title, display function,\n * and the post type on which it will live.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Meta_Box {\n\n    \/**\n     * A reference to the class that will display the contents in the meta box.\n     *\n     * @access private\n     * @var    Meta_Box_Display\n     *\/\n    private $meta_box_display;\n\n    \/**\n     * Instantiates the class by setting its property equal to a reference to its display.\n     *\n     * @param string $plugin_dir A reference to the root of the plugin's directory.\n     *\/\n    public function __construct( $plugin_dir) {\n        $this-&gt;meta_box_display = new Meta_Box_Display( $plugin_dir );\n    }\n\n    \/\/ Snip for brevity.\n}<\/code><\/pre>\n<p>Tenga en cuenta que este constructor tambi\u00e9n acepta el directorio del complemento como argumento y lo pasa tambi\u00e9n a la\u00a0 clase <strong>Meta Box Display<\/strong>. Esto es para que las funciones encargadas de mostrar los mensajes se puedan encontrar correctamente en su ubicaci\u00f3n en el\u00a0 directorio <strong>Vistas<\/strong>.<\/p>\n<p>Finalmente, revisemos la\u00a0 clase <strong>Meta Box Display<\/strong>. Esta es una clase simple que incluye el espacio de nombres y hace referencia al <strong>Post Messenger<\/strong> que hemos revisado anteriormente.<\/p>\n<pre><code>&lt;?php\n\/**\n * Defines the display for the meta box.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\n\nnamespace McFarlinTRPDisplay;\nuse McFarlinTRPUtilityPost_Messenger;\n\n\/**\n * Defines the display for the meta box that will render the content in the\n * context of its meta box.\n *\n * @author Tom McFarlin\n * @since  0.2.0\n *\/\nclass Meta_Box_Display {\n\n    \/**\n     * A reference to the class that will display the contents in the meta box.\n     *\n     * @access private\n     * @var    Post_Messenger\n     *\/\n    private $messenger;\n\n    \/**\n     * Instantiates the object by setting a property equal to that of the class\n     * responsible for rendering the messages from the post query.\n     *\n     * @param string $plugin_dir A reference to the root of the plugin's directory.\n     *\/\n    public function __construct( $plugin_dir) {\n        $this-&gt;messenger = new Post_Messenger( $plugin_dir );\n    }\n\n    \/**\n     * If there are posts to display, renders them in the metabox. Otherwise, displays\n     * a note that there are no posts to display.\n     *\/\n    public function display() {\n        $this-&gt;messenger-&gt;get_message();\n    }\n}\n<\/code><\/pre>\n<p>En este punto, hemos cerrado el c\u00edrculo a trav\u00e9s del complemento. Con una excepci\u00f3n: el archivo de arranque. Le hemos agregado un espacio de nombres y tenemos que actualizar la forma <a href=\"https:\/\/gist.github.com\/tommcfarlin\/38c72277ddbd0fa70a74c03598070703#file-06-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en que se instancia<\/a> :<\/p>\n<pre><code>&lt;?php\n\nnamespace McFarlinTRP;\nuse McFarlinTRPDisplayMeta_Box;\n\ninclude 'Display\/class-meta-box.php';\ninclude 'Display\/class-meta-box-display.php';\ninclude 'Utility\/class-post-messenger.php';\ninclude 'Utility\/class-post-query.php';\n\nadd_action( 'add_meta_boxes', __NAMESPACE__. 'trp_start' );\n\/**\n * Starts the plugin.\n *\/\nfunction trp_start() {\n\n    $meta_box = new Meta_Box( dirname( __FILE__) );\n    $meta_box-&gt;init();\n}<\/code><\/pre>\n<p>Es decir, hemos:<\/p>\n<ul>\n<li>defini\u00f3 el espacio de nombres,<\/li>\n<li>hacer referencia a la ubicaci\u00f3n de la\u00a0 clase <strong>Meta Box<\/strong> ,<\/li>\n<li>actualiz\u00f3 las rutas para incluir d\u00f3nde encontrar los archivos (que en \u00faltima instancia se puede hacer con un cargador autom\u00e1tico),<\/li>\n<li>y actualiz\u00f3 la\u00a0 llamada <strong>add_action<\/strong>.<\/li>\n<\/ul>\n<p>Esto es lo que pasa con la llamada de acci\u00f3n de agregar: dado que WordPress necesita ubicar esta funci\u00f3n y la funci\u00f3n reside en un espacio de nombres, se debe identificar el nombre completo de la funci\u00f3n para que WordPress pueda invocarla. De ah\u00ed la necesidad de <strong><a href=\"https:\/\/php.net\/manual\/en\/language.namespaces.nsconstants.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">NAMESPACE<\/a><\/strong> en el nombre de la funci\u00f3n.<\/p>\n<h2>Ahora estamos organizados (con una excepci\u00f3n)<\/h2>\n<p>Como puede ver, los espacios de nombres y los directorios que coinciden con ellos agregan mucha organizaci\u00f3n a un proyecto. Es m\u00e1s f\u00e1cil de seguir, m\u00e1s f\u00e1cil de entender a d\u00f3nde van las cosas (tanto para los archivos existentes como para los nuevos). Y da menos sensaci\u00f3n acumular muchos archivos en un solo lugar.<\/p>\n<p>Incluso si una clase es un poco monol\u00edtica, a\u00fan puede organizarse de tal manera que facilite el mantenimiento.<\/p>\n<p>Dicho esto, todav\u00eda hay algo que cambiar\u00eda sobre este complemento: pasar el directorio del complemento de esta manera no es algo que ayude con la baja cohesi\u00f3n y une m\u00e1s estrechamente las clases porque el archivo de arranque tiene que pasar un valor en una clase que lo pasa a otra clase que lo usa para cargar archivos y as\u00ed sucesivamente.<\/p>\n<p>Entonces, \u00bfhay formas de arreglar esto? Absolutamente. Y tal vez le demos un vistazo a eso en la publicaci\u00f3n final.<\/p>\n<p>Hasta entonces, recuerde que la versi\u00f3n m\u00e1s reciente del complemento est\u00e1 disponible <a href=\"https:\/\/github.com\/tommcfarlin\/three-recent-posts\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en la rama maestra, etiquetada como 0.3.0, en GitHub<\/a>.<\/p>\n<h2>Publicaciones de la serie<\/h2>\n<ol>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/es\/creacion-rapida-de-prototipos-con-wordpress-del-concepto-al-complemento\/\" title=\"Creaci\u00f3n r\u00e1pida de prototipos con WordPress: del concepto al complemento\">Creaci\u00f3n r\u00e1pida de prototipos con WordPress: del concepto al complemento<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/es\/prototipos-rapidos-con-wordpress-analisis-de-concepto\/\" title=\"Prototipos R\u00e1pidos con WordPress: An\u00e1lisis de Concepto\">Prototipos R\u00e1pidos con WordPress: An\u00e1lisis de Concepto<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/es\/creacion-rapida-de-prototipos-prototipo-a-codigo-parte-1\/\" title=\"Creaci\u00f3n r\u00e1pida de prototipos: Prototipo a c\u00f3digo, Parte 1\">Creaci\u00f3n r\u00e1pida de prototipos: Prototipo a c\u00f3digo, Parte 1<\/a><\/li>\n<li><a href=\"https:\/\/tommcfarlin.com\/prototype-to-code-2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Creaci\u00f3n r\u00e1pida de prototipos: de prototipo a c\u00f3digo, parte 2<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/es\/creacion-rapida-de-prototipos-introduccion-a-la-carga-automatica\/\" title=\"Creaci\u00f3n r\u00e1pida de prototipos: Introducci\u00f3n a la carga autom\u00e1tica\">Creaci\u00f3n r\u00e1pida de prototipos: Introducci\u00f3n a la carga autom\u00e1tica<\/a><\/li>\n<\/ol>\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>En el esfuerzo continuo por pasar del prototipo al c\u00f3digo, tomar\u00e9 el complemento en progreso e implementar\u00e9 interfaces para la organizaci\u00f3n.<\/p>\n","protected":false},"author":1,"featured_media":223922,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[716,914,840],"tags":[1172],"class_list":["post-229134","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollador","category-otro","category-tutoriales","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229134","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=229134"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229134\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/223922"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=229134"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=229134"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=229134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}