Agregue un enlace personalizado a la pantalla de todas las publicaciones según los metadatos de la publicación
TL; DR: este artículo describe el código necesario para agregar un enlace personalizado en la pantalla Todas las publicaciones que utiliza una pieza personalizada de metadatos de publicación.
Nota: Hace unos meses, escribí un artículo sobre cómo agregar una vista personalizada a la pantalla Todas las publicaciones. Este artículo no es todos juntos iguales, pero tampoco todos juntos diferentes. Piense en ello como una implementación más detallada y quizás más práctica del concepto.
Suponga que tiene un tipo de publicación estándar o un tipo de publicación personalizado y simplemente filtrará por un título que defina mediante un mecanismo que le permita guardar datos en la post_metadatatabla.
Por ejemplo, supongamos que tiene una publicación y es un metadato con:
- a
meta_keycon el valor dearticle_attribute - a
meta_valuecon el valor deheadline
Y desea usar esta información para agregar un nuevo enlace de Titulares que filtre automáticamente todo, excepto los artículos con esos metadatos.
Aquí está cómo hacerlo.
Enlace personalizado en la pantalla Todas las publicaciones
Antes de comenzar, vale la pena señalar que hay dos formas de abordar este problema:
- Podríamos agregar el enlace en la parte superior de la página Todas las publicaciones primero y luego agregar la funcionalidad para filtrar los datos en segundo lugar,
- O podemos hacerlo al revés, donde primero agregamos la lógica de back-end y luego agregamos el enlace de la página Todas las publicaciones.
Voy a optar por empezar con la segunda opción. No hay ninguna razón por la que tenga que hacerse de esta manera. es mi preferencia
Primero, necesito conectarme al [pre_get_posts](https://developer.wordpress.org/reference/hooks/pre_get_posts/)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é un complemento de demostración para esto vinculado en la parte inferior de la publicación.
De todos modos, comenzaré agregando una función anónima adjunta al enlace mencionado anteriormente:
add_action(
'pre_get_posts',
function (WP_Query $query) {
}
);
Tenga en cuenta que la función anónima acepta un solo argumento que es una referencia a la instancia actual de WP_Queryque se está ejecutando en la página. Si no está familiarizado con esa clase, le recomiendo que lea cualquiera de estos artículos o la página de recursos para desarrolladores.
En la función, necesito verificar la presencia de un meta_valueen la cadena de consulta. Esto es fácil de hacer gracias a la [filter_input](https://www.php.net/manual/en/function.filter-input.php)función proporcionada por PHP.
add_action(
'pre_get_posts',
function (WP_Query $query) {
$meta_value = 'headline';
if (filter_input( INPUT_GET, 'meta_value') === $meta_value) {
$query->set( 'meta_key', 'article_attribute' );
$query->set( 'meta_value', $meta_value );
}
}
);
Este enlace buscará si el headlinevalor es clave para la meta_valueclave en la cadena de consulta. Si es así, agrega un meta_keyy meta_valuea la instancia WP_Queryque le indicará a WordPress que recupere todas las publicaciones solo con esos metadatos.
Después de eso, necesito agregar un enlace en la parte superior de la página Todas las publicaciones para activar esta funcionalidad. Para ello, aprovecharé el [views_edit-posts](https://tommcfarlin.com/add-a-custom-view/)anzuelo. Esta función aceptará una serie de anclas que se mostrarán en la parte superior de la página.
Me refiero a estos como $viewsque eso es lo que aceptará la función cuando la apague:
add_action(
'views_edit-post',
function (array $views) {
return $views;
}
);
Tenga en cuenta que es importante devolver la matriz a WordPress para que sepa qué representar incluso si no se realiza ninguna modificación.
Primero, necesito determinar si estoy actualmente en la página personalizada. Si es así, necesito agregar los atributos adecuados al ancla agregada en la parte superior de la página:
$attributes = 'class=""';
if (filter_input(INPUT_GET, 'meta_value') === 'headline') {
$attributes ='class="current aria-current="page"';
}
Después de eso, necesito agregar la vista Titulares a la página. Esto requerirá el uso de varias funciones:
[array_push](https://www.php.net/manual/en/function.array-push.php)por añadir un nuevo enlace a la lista de$views[sprintf](https://www.php.net/manual/en/function.sprintf.php)para agregar de forma segura una nueva cadena[add_query_arg](https://developer.wordpress.org/reference/functions/add_query_arg/)para agregar un conjunto de argumentos de consulta personalizados a la página actual.
La siguiente sección de código se verá así:
array_push(
$views,
sprintf(
'<a href="%1$s" %2$s>%3$s
<span class="count">(%4$s)</span>
</a>
',
add_query_arg([
'post_type' => 'post',
'post_status' => 'all',
'meta_value' => 'headline',
], 'edit.php'),
$attributes
__('Headlines'),
count( );
);
Pero aún no he terminado. Observe específicamente que estoy haciendo una llamada al [count](https://www.php.net/manual/en/function.count.php)final de la función. Esto es para que pueda mostrar correctamente la cantidad de publicaciones que tienen este atributo.
Voy a escribir dos funciones auxiliares para esto y luego regresaré a la sizeofllamada.
Aquí hay una función de ayuda para encontrar la cantidad de resultados que tienen lo especificado meta_keyy meta_valueque tenemos para este tipo de publicación. Tenga en cuenta que estoy usando [$wpdb](https://developer.wordpress.org/reference/classes/wpdb/)para hacer una llamada directa a la base de datos y que estoy usando específicamente [prepare](https://developer.wordpress.org/reference%2Fclasses%2Fwpdb%2Fprepare%2F/)para asegurarme de hacerlo de manera segura.
function get_headline_results(): array {
global $wpdb;
return $wpdb->get_results(
$wpdb->prepare(
"
SELECT post_id FROM $wpdb->postmeta
WHERE meta_key = %s AND meta_value = %s
",
'article_attribute',
'headline'
),
ARRAY_A
);
}
Tenga en cuenta que devuelve todos los resultados (no solo el número) porque este valor se pasará a otra función momentáneamente.
En este punto, podríamos detenernos y simplemente mirar el contenido que se devuelve de la consulta, pero si solo nos preocupa el posttipo de publicación, tendremos que tenerlo en cuenta. Aquí hay una forma de hacerlo:
function filter_posts_from_pages( array $results ): array {
$post_ids = array();
foreach ($results as $result) {
if ('post' === get_post_type( $result['post_type'])) {
$post_ids[] = $result['post_id'];
}
}
return $post_ids;
}
Con eso, podemos devolver este valor a la countfunción anterior.
La versión final del bloque que comenzamos arriba debería verse así:
array_push(
$views,
sprintf(
'<a href="%1$s" %2$s>%3$s <span class="count">(%4$s)</span></a>',
add_query_arg(
array(
'post_type' => 'post',
'post_status' => 'all',
'meta_value' => 'headlines',
),
'edit.php'
),
$attributes,
__( 'Headlines' ),
count(
filter_posts_from_pages( get_headline_results()) )) );
Lo que significa que la versión completa de la función para agregar un nuevo título se parece a esto:
add_action(
'views_edit-post',
function (array $views) {
$attributes = 'class=""';
if (filter_input( INPUT_GET, 'meta_value') === 'headline') {
$attributes = 'class="current aria-current="page"';
}
array_push(
$views,
sprintf(
'<a href="%1$s" %2$s>%3$s <span class="count">(%4$s)</span></a>',
add_query_arg(
array(
'post_type' => 'post',
'post_status' => 'all',
'meta_value' => 'headline',
),
'edit.php'
),
$attributes,
__( 'Headlines' ),
count(
filter_posts_from_pages( get_headline_results()) )) );
return $views;
}
);
Y, como se mencionó desde el principio, este complemento no tiene espacios de nombres ni está organizado de la manera en que normalmente escribo código. En cambio, está destinado a demostrar una forma de lograr algo rápidamente: una especie de prototipo.
Entonces, si está interesado en ver algo como esto en acción, puede consultar el repositorio en GitHub. Tenga en cuenta que es la rama de desarrollo en este momento. Recuerde ver el [README](https://github.com/tommcfarlin/custom-metadata-filter/blob/develop/README.md), ya que le dará instrucciones sobre cómo agregar datos a la base de datos para las publicaciones, de modo que el ancla de Titulares realmente funcione en lugar de mostrar incondicionalmente un valor cero.