✅ Новости WEB и WordPress, темы, плагины. Здесь мы делимся советами и лучшими решениями для веб-сайтов.

Добавить пользовательскую ссылку на экран всех сообщений на основе метаданных сообщений

13

TL;DR: в этой статье описывается код, необходимый для добавления пользовательской ссылки на экран «Все сообщения », которая использует пользовательский фрагмент метаданных сообщения.

Примечание. Несколько месяцев назад я написал статью о том, как добавить пользовательский вид на экран «Все сообщения ». Эта статья не все вместе то же самое, но и не все вместе разные. Думайте об этом как о более подробном и, возможно, более практическом воплощении концепции.


Предположим, что у вас есть стандартный тип записи или пользовательский тип записи, и вы собираетесь просто фильтровать по заголовку, который вы определяете, используя механизм, позволяющий сохранять данные в post_metadataтаблицу.

Например, предположим, что у вас есть сообщение и оно представляет собой часть метаданных с:

  • а meta_keyсо значениемarticle_attribute
  • а meta_valueсо значениемheadline

И вы хотите использовать эту информацию, чтобы добавить новую ссылку «Заголовки », которая автоматически отфильтровывает все, кроме статей с этими метаданными.

Вот как это сделать.

Пользовательская ссылка на экране всех сообщений

Прежде чем начать, стоит отметить, что есть два способа решить эту проблему:

  • Мы могли бы сначала добавить ссылку в верхней части страницы «Все сообщения », а затем добавить функциональность для фильтрации данных,
  • Или мы можем сделать это наоборот, сначала добавим внутреннюю логику, а затем добавим ссылку на страницу «Все сообщения ».

Я собираюсь начать со второго варианта. Нет причин, почему это должно быть сделано именно так. Это мое предпочтение.


Во-первых, мне нужно подключиться к [pre_get_posts](https://developer.wordpress.org/reference/hooks/pre_get_posts/)хуку, предоставленному WordPress. Я не собираюсь использовать в этом примере какие-либо классы с именами или префиксные функции (учитывая, что я достаточно рассмотрел этот контент на этом сайте), но у меня будет демонстрационный плагин для этого, связанный внизу сообщения.

В любом случае, я начну с добавления анонимной функции, прикрепленной к вышеупомянутому хуку:

add_action(
  'pre_get_posts',
  function (WP_Query $query) {

  }
);

Обратите внимание, что анонимная функция принимает единственный аргумент, который является ссылкой на текущий экземпляр WP_Query, работающий на странице. Если вы не знакомы с этим классом, я рекомендую прочитать любую из этих статей или страницу ресурсов для разработчиков .

В функции мне нужно проверить наличие a 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)так как он даст инструкции о том, как добавить данные в базу данных для сообщений, чтобы привязка заголовков действительно работала, а не безоговорочно показывала нулевое значение.

Источник записи: tommcfarlin.com

Этот веб-сайт использует файлы cookie для улучшения вашего опыта. Мы предполагаем, что вы согласны с этим, но вы можете отказаться, если хотите. Принимаю Подробнее