Додайте спеціальне посилання на екран усіх публікацій на основі метаданих публікації
TL;DR: у цій статті описано код, необхідний для додавання спеціального посилання на екран «Усі публікації», яке використовує спеціальну частину метаданих публікації.
Примітка. Кілька місяців тому я написав статтю про те, як додати спеціальне подання до екрана «Усі публікації». Ця стаття не вся разом однакова, але й не вся разом різна. Подумайте про це як про більш детальну і, можливо, більш практичну реалізацію концепції.
Припустімо, що у вас є стандартний тип публікації або настроюваний тип публікації, і ви збираєтеся просто фільтрувати за заголовком, який ви визначаєте, використовуючи механізм, який дозволяє зберігати дані в post_metadataтаблиці.
Наприклад, припустімо, що у вас є публікація, яка є частиною метаданих із:
- a
meta_keyзі значеннямarticle_attribute - a
meta_valueзі значеннямheadline
І ви хочете використати цю інформацію, щоб додати нове посилання Headlines, яке автоматично відфільтровує все, крім статей із такими метаданими.
Ось як це зробити.
Спеціальне посилання на екрані «Усі публікації».
Перш ніж почати, варто зазначити, що є два шляхи вирішення цієї проблеми:
- Спершу ми можемо додати посилання у верхній частині сторінки «Усі публікації », а потім додати функцію фільтрації даних,
- Або ми можемо зробити це навпаки, спочатку додавши логіку серверної частини, а потім додавши посилання на сторінку «Усі публікації».
Я збираюся почати з другого варіанту. Немає причин, чому це має бути зроблено таким чином. Це моя перевага.
По-перше, мені потрібно підключитися до [pre_get_posts](https://developer.wordpress.org/reference/hooks/pre_get_posts/)гачка, наданого WordPress. У цьому прикладі я не використовуватиму жодних класів із простором імен чи функцій із префіксом (враховуючи, що я достатньо розглянув цей вміст на цьому сайті), але у мене буде посилання на демонстраційний плагін для цього внизу публікації.
У будь-якому випадку, я почну з додавання анонімної функції, приєднаної до вищезгаданого хука:
add_action(
'pre_get_posts',
function (WP_Query $query) {
}
);
Зверніть увагу, що анонімна функція приймає єдиний аргумент, який є посиланням на поточний екземпляр, WP_Queryщо виконується на сторінці. Якщо ви не знайомі з цим класом, я рекомендую прочитати будь-яку з цих статей або сторінку ресурсів розробника.
У функції мені потрібно перевірити наявність meta_valueу рядку запиту. Це легко зробити завдяки [filter_input](https://www.php.net/manual/en/function.filter-input.php)функції 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 );
}
}
);
Цей хук перевіряє, чи є headlineзначення ключем для meta_valueключа в рядку запиту. Якщо так, він додає meta_keyі meta_valueдо екземпляра WP_Queryякого вказує WordPress отримати всі публікації лише з цими метаданими.
Після цього мені потрібно додати посилання вгору сторінки «Усі публікації », щоб запустити цю функцію. Для цього я скористаюся [views_edit-posts](https://tommcfarlin.com/add-a-custom-view/)гачком. Ця функція прийматиме масив прив’язок, які відображатимуться у верхній частині сторінки.
Я називаю це $viewsтак, що функція прийме, коли я її заглушу:
add_action(
'views_edit-post',
function (array $views) {
return $views;
}
);
Зауважте, що важливо повернути масив назад до WordPress, щоб він знав, що потрібно відобразити, навіть якщо не було зроблено жодних змін.
По-перше, мені потрібно визначити, чи перебуваю я зараз на спеціальній сторінці. Якщо так, то мені потрібно додати належні атрибути до прив’язки, доданої у верхній частині сторінки:
$attributes = 'class=""';
if (filter_input(INPUT_GET, 'meta_value') === 'headline') {
$attributes ='class="current aria-current="page"';
}
Після цього мені потрібно фактично додати до сторінки перегляд заголовків. Для цього буде потрібно використовувати кілька функцій:
[array_push](https://www.php.net/manual/en/function.array-push.php)для додавання нового посилання до списку$views[sprintf](https://www.php.net/manual/en/function.sprintf.php)для безпечного додавання нового рядка[add_query_arg](https://developer.wordpress.org/reference/functions/add_query_arg/)для додавання набору настроюваних аргументів запиту до поточної сторінки.
Наступний розділ коду виглядатиме так:
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( );
);
Але я ще не закінчив. Зверніть увагу, зокрема, що я роблю виклик [count](https://www.php.net/manual/en/function.count.php)у кінці функції. Це для того, щоб я міг належним чином відображати кількість публікацій, які мають цей атрибут.
Я збираюся написати дві допоміжні функції для цього, а потім повернуся до sizeofвиклику.
Ось допоміжна функція для пошуку кількості результатів, які мають вказане значення meta_keyта meta_valueякі ми маємо для цього типу публікацій. Зверніть увагу, що я використовую [$wpdb](https://developer.wordpress.org/reference/classes/wpdb/)для здійснення прямого виклику бази даних і що я спеціально використовую [prepare](https://developer.wordpress.org/reference%2Fclasses%2Fwpdb%2Fprepare%2F/), щоб переконатися, що роблю це безпечно.
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
);
}
Зверніть увагу, що він повертає всі результати (а не лише число), оскільки це значення буде миттєво передано іншій функції.
На цьому ми можемо зупинитись і просто переглянути вміст, отриманий із запиту, але якщо нас цікавить лише postтип публікації, нам потрібно це врахувати. Ось один із способів зробити це:
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;
}
З цим ми можемо повернути це значення назад до countфункції вище.
Остаточна версія блоку, яку ми почали вище, має виглядати приблизно так:
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()) )) );
Це означає, що повна версія функції для додавання нового заголовка виглядає приблизно так:
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;
}
);
І, як згадувалося з самого початку, цей плагін не має простору імен і не організований так, як я зазвичай пишу код. Натомість він призначений для демонстрації способу швидкого досягнення чогось – свого роду прототипу.
Отже, якщо вам цікаво побачити щось подібне в дії, ви можете перевірити репозиторій на GitHub. Зауважте, що на даний момент це гілка розробки . Не забудьте переглянути, [README](https://github.com/tommcfarlin/custom-metadata-filter/blob/develop/README.md)оскільки він надасть інструкції щодо додавання даних до бази даних для публікацій, щоб прив’язка заголовків справді працювала, а не безумовно показувала нульове значення.