{"id":231665,"date":"2023-01-06T11:52:00","date_gmt":"2023-01-06T08:52:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231665"},"modified":"2023-01-06T12:27:30","modified_gmt":"2023-01-06T09:27:30","slug":"agregue-un-enlace-personalizado-a-la-pantalla-de-todas-las-publicaciones-segun-los-metadatos-de-la-publicacion","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/agregue-un-enlace-personalizado-a-la-pantalla-de-todas-las-publicaciones-segun-los-metadatos-de-la-publicacion\/","title":{"rendered":"Agregue un enlace personalizado a la pantalla de todas las publicaciones seg\u00fan los metadatos de la publicaci\u00f3n"},"content":{"rendered":"\n<p><strong>TL; DR<\/strong>: este art\u00edculo describe el c\u00f3digo necesario para agregar un enlace personalizado en la pantalla <strong>Todas<\/strong> las publicaciones que utiliza una pieza personalizada de metadatos de publicaci\u00f3n.<\/p>\n<p><strong>Nota<\/strong>: Hace unos meses, escrib\u00ed un art\u00edculo sobre <a href=\"https:\/\/wordpress.mediadoma.com\/es\/agregar-una-vista-personalizada-a-la-pantalla-todas-las-publicaciones\/\" title=\"c\u00f3mo agregar una vista personalizada a la pantalla Todas las publicaciones\">c\u00f3mo agregar una vista personalizada a la pantalla Todas las publicaciones<\/a>. Este art\u00edculo no es todos juntos iguales, pero tampoco todos juntos diferentes. Piense en ello como una implementaci\u00f3n m\u00e1s detallada y quiz\u00e1s m\u00e1s pr\u00e1ctica del concepto.<\/p>\n<hr \/>\n<p>Suponga que tiene un tipo de publicaci\u00f3n est\u00e1ndar o un tipo de publicaci\u00f3n personalizado y simplemente filtrar\u00e1 por un t\u00edtulo que defina mediante un mecanismo que le permita guardar datos en la <code>post_metadata<\/code>tabla.<\/p>\n<p>Por ejemplo, supongamos que tiene una publicaci\u00f3n y es un metadato con:<\/p>\n<ul>\n<li>a <code>meta_key<\/code>con el valor de<code>article_attribute<\/code><\/li>\n<li>a <code>meta_value<\/code>con el valor de<code>headline<\/code><\/li>\n<\/ul>\n<p>Y desea usar esta informaci\u00f3n para agregar un nuevo enlace de <strong>Titulares<\/strong> que filtre autom\u00e1ticamente todo, excepto los art\u00edculos con esos metadatos.<\/p>\n<p>Aqu\u00ed est\u00e1 c\u00f3mo hacerlo.<\/p>\n<h2>Enlace personalizado en la pantalla Todas las publicaciones<\/h2>\n<p>Antes de comenzar, vale la pena se\u00f1alar que hay dos formas de abordar este problema:<\/p>\n<ul>\n<li>Podr\u00edamos agregar el enlace en la parte superior de la p\u00e1gina <strong>Todas las publicaciones<\/strong> primero y luego agregar la funcionalidad para filtrar los datos en segundo lugar,<\/li>\n<li>O podemos hacerlo al rev\u00e9s, donde primero agregamos la l\u00f3gica de back-end y luego agregamos el enlace de la p\u00e1gina <strong>Todas las publicaciones.<\/strong><\/li>\n<\/ul>\n<p>Voy a optar por empezar con la segunda opci\u00f3n. No hay ninguna raz\u00f3n por la que tenga que hacerse de esta manera. es mi preferencia<\/p>\n<hr \/>\n<p>Primero, necesito conectarme al <code>[pre_get_posts](https:\/\/developer.wordpress.org\/reference\/hooks\/pre_get_posts\/)<\/code>gancho proporcionado por WordPress. No voy a usar ninguna clase con espacio de nombres o funciones prefijadas en este ejemplo (dado que he cubierto ese contenido lo suficiente en este sitio), pero tendr\u00e9 un complemento de demostraci\u00f3n para esto vinculado en la parte inferior de la publicaci\u00f3n.<\/p>\n<p>De todos modos, comenzar\u00e9 agregando una funci\u00f3n an\u00f3nima adjunta al enlace mencionado anteriormente:<\/p>\n<pre><code>add_action(\n  'pre_get_posts',\n  function (WP_Query $query) {\n\n  }\n);<\/code><\/pre>\n<p>Tenga en cuenta que la funci\u00f3n an\u00f3nima acepta un solo argumento que es una referencia a la instancia actual de <code>WP_Query<\/code>que se est\u00e1 ejecutando en la p\u00e1gina. Si no est\u00e1 familiarizado con esa clase, le recomiendo que lea cualquiera de <a href=\"https:\/\/tommcfarlin.com\/?s=wp_query\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">estos art\u00edculos<\/a> o la p\u00e1gina <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">de recursos para desarrolladores<\/a>.<\/p>\n<p>En la funci\u00f3n, necesito verificar la presencia de un <code>meta_value<\/code>en la cadena de consulta. Esto es f\u00e1cil de hacer gracias a la <code>[filter_input](https:\/\/www.php.net\/manual\/en\/function.filter-input.php)<\/code>funci\u00f3n proporcionada por PHP.<\/p>\n<pre><code>add_action(\n  'pre_get_posts',\n  function (WP_Query $query) {\n    $meta_value = 'headline';\n\n    if (filter_input( INPUT_GET, 'meta_value') === $meta_value) {\n      $query-&gt;set( 'meta_key', 'article_attribute' );\n      $query-&gt;set( 'meta_value', $meta_value );\n    }\n  }\n);<\/code><\/pre>\n<p>Este enlace buscar\u00e1 si el <code>headline<\/code>valor es clave para la <code>meta_value<\/code>clave en la cadena de consulta. Si es as\u00ed, agrega un <code>meta_key<\/code>y <code>meta_value<\/code>a la instancia <code>WP_Query<\/code>que le indicar\u00e1 a WordPress que recupere todas las publicaciones solo con esos metadatos.<\/p>\n<hr \/>\n<p>Despu\u00e9s de eso, necesito agregar un enlace en la parte superior de la p\u00e1gina <strong>Todas las publicaciones<\/strong> para activar esta funcionalidad. Para ello, aprovechar\u00e9 el <code>[views_edit-posts](https:\/\/tommcfarlin.com\/add-a-custom-view\/)<\/code>anzuelo. Esta funci\u00f3n aceptar\u00e1 una serie de anclas que se mostrar\u00e1n en la parte superior de la p\u00e1gina.<\/p>\n<p>Me refiero a estos como <code>$views<\/code>que eso es lo que aceptar\u00e1 la funci\u00f3n cuando la apague:<\/p>\n<pre><code>add_action(\n  'views_edit-post',\n  function (array $views) {\n\n    return $views;\n  }\n);<\/code><\/pre>\n<p>Tenga en cuenta que es importante devolver la matriz a WordPress para que sepa qu\u00e9 representar incluso si no se realiza ninguna modificaci\u00f3n.<\/p>\n<p>Primero, necesito determinar si estoy actualmente en la p\u00e1gina personalizada. Si es as\u00ed, necesito agregar los atributos adecuados al ancla agregada en la parte superior de la p\u00e1gina:<\/p>\n<pre><code>\n$attributes = 'class=\"\"';\nif (filter_input(INPUT_GET, 'meta_value') === 'headline') {\n  $attributes ='class=\"current aria-current=\"page\"';\n}<\/code><\/pre>\n<p>Despu\u00e9s de eso, necesito agregar la vista <strong>Titulares<\/strong> a la p\u00e1gina. Esto requerir\u00e1 el uso de varias funciones:<\/p>\n<ul>\n<li><code>[array_push](https:\/\/www.php.net\/manual\/en\/function.array-push.php)<\/code>por a\u00f1adir un nuevo enlace a la lista de<code>$views<\/code><\/li>\n<li><code>[sprintf](https:\/\/www.php.net\/manual\/en\/function.sprintf.php)<\/code>para agregar de forma segura una nueva cadena<\/li>\n<li><code>[add_query_arg](https:\/\/developer.wordpress.org\/reference\/functions\/add_query_arg\/)<\/code>para agregar un conjunto de argumentos de consulta personalizados a la p\u00e1gina actual.<\/li>\n<\/ul>\n<p>La siguiente secci\u00f3n de c\u00f3digo se ver\u00e1 as\u00ed:<\/p>\n<pre><code>\narray_push(\n  $views,\n  sprintf(\n    '&lt;a href=\"%1$s\" %2$s&gt;%3$s \n      &lt;span class=\"count\"&gt;(%4$s)&lt;\/span&gt;\n     &lt;\/a&gt;\n    ',\n    add_query_arg([\n      'post_type'   =&gt; 'post',\n      'post_status' =&gt; 'all',\n      'meta_value'  =&gt; 'headline',\n    ], 'edit.php'),\n    $attributes\n    __('Headlines'),\n    count(  );\n);<\/code><\/pre>\n<p>Pero a\u00fan no he terminado. Observe espec\u00edficamente que estoy haciendo una llamada al <code>[count](https:\/\/www.php.net\/manual\/en\/function.count.php)<\/code>final de la funci\u00f3n. Esto es para que pueda mostrar correctamente la cantidad de publicaciones que tienen este atributo.<\/p>\n<p>Voy a escribir dos funciones auxiliares para esto y luego regresar\u00e9 a la <code>sizeof<\/code>llamada.<\/p>\n<hr \/>\n<p>Aqu\u00ed hay una funci\u00f3n de ayuda para encontrar la cantidad de resultados que tienen lo especificado <code>meta_key<\/code>y <code>meta_value<\/code>que tenemos para este tipo de publicaci\u00f3n. Tenga en cuenta que estoy usando <code>[$wpdb](https:\/\/developer.wordpress.org\/reference\/classes\/wpdb\/)<\/code>para hacer una llamada directa a la base de datos y que estoy usando espec\u00edficamente <code>[prepare](https:\/\/developer.wordpress.org\/reference%2Fclasses%2Fwpdb%2Fprepare%2F\/)<\/code>para asegurarme de hacerlo de manera segura.<\/p>\n<pre><code>function get_headline_results(): array {\n  global $wpdb;\n  return $wpdb-&gt;get_results( \n    $wpdb-&gt;prepare(\n      \"\n      SELECT post_id FROM $wpdb-&gt;postmeta\n      WHERE meta_key = %s AND meta_value = %s\n      \",\n      'article_attribute',\n      'headline'\n    ),\n    ARRAY_A\n  );\n}<\/code><\/pre>\n<p>Tenga en cuenta que devuelve todos los resultados (no solo el n\u00famero) porque este valor se pasar\u00e1 a otra funci\u00f3n moment\u00e1neamente.<\/p>\n<p>En este punto, podr\u00edamos detenernos y simplemente mirar el contenido que se devuelve de la consulta, pero si solo nos preocupa el <code>post<\/code>tipo de publicaci\u00f3n, tendremos que tenerlo en cuenta. Aqu\u00ed hay una forma de hacerlo:<\/p>\n<pre><code>function filter_posts_from_pages( array $results ): array {\n  $post_ids = array();\n\n  foreach ($results as $result) {\n    if ('post' === get_post_type( $result['post_type'])) {\n      $post_ids[] = $result['post_id'];\n    }\n  }\n\n  return $post_ids;\n}<\/code><\/pre>\n<p>Con eso, podemos devolver este valor a la <code>count<\/code>funci\u00f3n anterior.<\/p>\n<hr \/>\n<p>La versi\u00f3n final del bloque que comenzamos arriba deber\u00eda verse as\u00ed:<\/p>\n<pre><code>\narray_push(\n  $views,\n  sprintf(\n    '&lt;a href=\"%1$s\" %2$s&gt;%3$s &lt;span class=\"count\"&gt;(%4$s)&lt;\/span&gt;&lt;\/a&gt;',\n    add_query_arg(\n      array(\n        'post_type'   =&gt; 'post',\n        'post_status' =&gt; 'all',\n        'meta_value'  =&gt; 'headlines', \n      ),\n      'edit.php'\n    ),\n    $attributes,\n    __( 'Headlines' ),\n    count(\n      filter_posts_from_pages( get_headline_results()) )) );<\/code><\/pre>\n<p>Lo que significa que la versi\u00f3n completa de la funci\u00f3n para agregar un nuevo t\u00edtulo se parece a esto:<\/p>\n<pre><code>add_action(\n  'views_edit-post',\n  function (array $views) {\n\n    $attributes = 'class=\"\"';\n    if (filter_input( INPUT_GET, 'meta_value') === 'headline') {\n      $attributes = 'class=\"current aria-current=\"page\"';\n    }\n\n    array_push(\n      $views,\n      sprintf(\n        '&lt;a href=\"%1$s\" %2$s&gt;%3$s &lt;span class=\"count\"&gt;(%4$s)&lt;\/span&gt;&lt;\/a&gt;',\n        add_query_arg(\n          array(\n            'post_type'   =&gt; 'post',\n            'post_status' =&gt; 'all',\n            'meta_value'  =&gt; 'headline', \n          ),\n          'edit.php'\n        ),\n        $attributes,\n        __( 'Headlines' ),\n        count(\n          filter_posts_from_pages( get_headline_results()) )) );\n\n    return $views;\n  }\n);<\/code><\/pre>\n<p>Y, como se mencion\u00f3 desde el principio, este complemento no tiene espacios de nombres ni est\u00e1 organizado de la manera en que normalmente escribo c\u00f3digo. En cambio, est\u00e1 destinado a demostrar una forma de lograr algo r\u00e1pidamente: una especie de prototipo.<\/p>\n<p>Entonces, si est\u00e1 interesado en ver algo como esto en acci\u00f3n, puede consultar el repositorio en GitHub. Tenga en cuenta que es la rama de <strong><a href=\"https:\/\/github.com\/tommcfarlin\/custom-metadata-filter\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">desarrollo<\/a><\/strong> en este momento. Recuerde ver el <code>[README](https:\/\/github.com\/tommcfarlin\/custom-metadata-filter\/blob\/develop\/README.md)<\/code>, ya que le dar\u00e1 instrucciones sobre c\u00f3mo agregar datos a la base de datos para las publicaciones, de modo que el ancla de <strong>Titulares realmente funcione en lugar de mostrar incondicionalmente un valor cero.<\/strong><\/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>Este art\u00edculo describe el c\u00f3digo necesario para agregar un enlace personalizado en la pantalla Todas las publicaciones que utiliza una pieza personalizada de metadatos de publicaci\u00f3n.<\/p>\n","protected":false},"author":1,"featured_media":158583,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[892,716,831,914,800,840,861],"tags":[1172],"class_list":["post-231665","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-desarrollador","category-guia-para-principiantes","category-otro","category-php-2","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/231665","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=231665"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/231665\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/158583"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=231665"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=231665"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=231665"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}