{"id":231397,"date":"2023-01-06T11:50:00","date_gmt":"2023-01-06T08:50:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231397"},"modified":"2023-01-06T12:10:05","modified_gmt":"2023-01-06T09:10:05","slug":"dodaj-niestandardowy-link-do-ekranu-wszystkich-postow-na-podstawie-metadanych-postow","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/dodaj-niestandardowy-link-do-ekranu-wszystkich-postow-na-podstawie-metadanych-postow\/","title":{"rendered":"Dodaj niestandardowy link do ekranu wszystkich post\u00f3w na podstawie metadanych post\u00f3w"},"content":{"rendered":"\n<p><strong>TL; DR<\/strong>: w tym artykule opisano kod potrzebny do dodania niestandardowego linku na ekranie <strong>Wszystkie posty<\/strong>, kt\u00f3ry u\u017cywa niestandardowego fragmentu metadanych posta.<\/p>\n<p><strong>Uwaga<\/strong>: kilka miesi\u0119cy temu napisa\u0142em artyku\u0142 o <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/dodaj-niestandardowy-widok-do-ekranu-wszystkich-postow\/\" title=\"tym, jak doda\u0107 niestandardowy widok do ekranu Wszystkie posty\">tym, jak doda\u0107 niestandardowy widok do ekranu Wszystkie posty<\/a>. Ten artyku\u0142 nie jest taki sam, ale nie wszystkie razem r\u00f3\u017cni\u0105 si\u0119. Pomy\u015bl o tym jako o bardziej szczeg\u00f3\u0142owym i by\u0107 mo\u017ce bardziej praktycznym wdro\u017ceniu koncepcji.<\/p>\n<hr \/>\n<p>Za\u0142\u00f3\u017cmy, \u017ce masz standardowy typ posta lub niestandardowy typ posta i zamierzasz po prostu filtrowa\u0107 wed\u0142ug nag\u0142\u00f3wka, kt\u00f3ry definiujesz za pomoc\u0105 mechanizmu, kt\u00f3ry pozwala na zapisywanie danych w <code>post_metadata<\/code>tabeli.<\/p>\n<p>Za\u0142\u00f3\u017cmy na przyk\u0142ad, \u017ce masz post i jest on cz\u0119\u015bci\u0105 metadanych z:<\/p>\n<ul>\n<li>a <code>meta_key<\/code>o warto\u015bci<code>article_attribute<\/code><\/li>\n<li>a <code>meta_value<\/code>o warto\u015bci<code>headline<\/code><\/li>\n<\/ul>\n<p>I chcesz wykorzysta\u0107 te informacje, aby doda\u0107 nowy link <strong>Nag\u0142\u00f3wki<\/strong>, kt\u00f3ry automatycznie odfiltruje wszystko z wyj\u0105tkiem artyku\u0142\u00f3w z tymi metadanymi.<\/p>\n<p>Oto jak to zrobi\u0107.<\/p>\n<h2>Niestandardowy link na ekranie wszystkich post\u00f3w<\/h2>\n<p>Przed rozpocz\u0119ciem warto zauwa\u017cy\u0107, \u017ce istniej\u0105 dwa sposoby rozwi\u0105zania tego problemu:<\/p>\n<ul>\n<li>Mo\u017cemy najpierw doda\u0107 link u g\u00f3ry strony <strong>Wszystkie posty<\/strong>, a nast\u0119pnie doda\u0107 funkcj\u0119 filtrowania danych po drugie,<\/li>\n<li>Lub mo\u017cemy to zrobi\u0107 na odwr\u00f3t, gdzie najpierw dodamy logik\u0119 zaplecza, a nast\u0119pnie dodamy link do strony <strong>Wszystkie posty<\/strong>.<\/li>\n<\/ul>\n<p>Zamierzam zacz\u0105\u0107 od drugiej opcji. Nie ma powodu, dla kt\u00f3rego mia\u0142oby si\u0119 to odbywa\u0107 w ten spos\u00f3b. To moja preferencja.<\/p>\n<hr \/>\n<p>Najpierw musz\u0119 podpi\u0105\u0107 si\u0119 pod <code>[pre_get_posts](https:\/\/developer.wordpress.org\/reference\/hooks\/pre_get_posts\/)<\/code>hak dostarczony przez WordPressa. W tym przyk\u0142adzie nie b\u0119d\u0119 u\u017cywa\u0142 \u017cadnych klas z przestrzeni\u0105 nazw ani funkcji z prefiksami (bior\u0105c pod uwag\u0119, \u017ce wystarczaj\u0105co om\u00f3wi\u0142em t\u0119 zawarto\u015b\u0107 na tej stronie), ale b\u0119d\u0119 mia\u0142 do tego wtyczk\u0119 demonstracyjn\u0105 do\u0142\u0105czon\u0105 na dole postu.<\/p>\n<p>W ka\u017cdym razie zaczn\u0119 od dodania anonimowej funkcji do\u0142\u0105czonej do wspomnianego haka:<\/p>\n<pre><code>add_action(\n  'pre_get_posts',\n  function (WP_Query $query) {\n\n  }\n);<\/code><\/pre>\n<p>Zauwa\u017c, \u017ce funkcja anonimowa akceptuje pojedynczy argument, kt\u00f3ry jest odwo\u0142aniem do bie\u017c\u0105cego wyst\u0105pienia <code>WP_Query<\/code>dzia\u0142aj\u0105cego na stronie. Je\u015bli nie znasz tej klasy, polecam przeczytanie dowolnego z <a href=\"https:\/\/tommcfarlin.com\/?s=wp_query\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tych artyku\u0142\u00f3w<\/a> lub strony z <a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_query\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">zasobami dla programist\u00f3w<\/a>.<\/p>\n<p>W funkcji musz\u0119 sprawdzi\u0107 obecno\u015b\u0107 <code>meta_value<\/code>w ci\u0105gu zapytania. Jest to \u0142atwe dzi\u0119ki <code>[filter_input](https:\/\/www.php.net\/manual\/en\/function.filter-input.php)<\/code>funkcji dostarczonej przez 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>Ten zaczep b\u0119dzie sprawdza\u0142, czy <code>headline<\/code>warto\u015b\u0107 jest kluczem dla <code>meta_value<\/code>klucza w ci\u0105gu zapytania. Je\u015bli tak, dodaje a <code>meta_key<\/code>i <code>meta_value<\/code>do wyst\u0105pienia, <code>WP_Query<\/code>kt\u00f3re poinstruuje WordPress, aby pobra\u0107 wszystkie posty z tylko tymi metadanymi.<\/p>\n<hr \/>\n<p>Nast\u0119pnie musz\u0119 doda\u0107 link na g\u00f3rze strony <strong>Wszystkie posty<\/strong>, aby uruchomi\u0107 t\u0119 funkcj\u0119. Aby to zrobi\u0107, u\u017cyj\u0119 <code>[views_edit-posts](https:\/\/tommcfarlin.com\/add-a-custom-view\/)<\/code>haka. Ta funkcja zaakceptuje tablic\u0119 kotwic, kt\u00f3ra b\u0119dzie wy\u015bwietlana u g\u00f3ry strony.<\/p>\n<p>Odnosz\u0119 si\u0119 do nich jako <code>$views<\/code>do tego, co funkcja zaakceptuje, gdy j\u0105 odci\u0119:<\/p>\n<pre><code>add_action(\n  'views_edit-post',\n  function (array $views) {\n\n    return $views;\n  }\n);<\/code><\/pre>\n<p>Zwr\u00f3\u0107 uwag\u0119, \u017ce wa\u017cne jest, aby zwr\u00f3ci\u0107 tablic\u0119 z powrotem do WordPressa, aby wiedzia\u0142a, co renderowa\u0107, nawet je\u015bli nie zostanie dokonana \u017cadna modyfikacja.<\/p>\n<p>Najpierw musz\u0119 ustali\u0107, czy aktualnie jestem na stronie niestandardowej. Je\u015bli tak, to musz\u0119 doda\u0107 odpowiednie atrybuty do kotwicy dodanej na g\u00f3rze strony:<\/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>Nast\u0119pnie musz\u0119 doda\u0107 widok <strong>Nag\u0142\u00f3wki<\/strong> do strony. B\u0119dzie to wymaga\u0142o u\u017cycia kilku funkcji:<\/p>\n<ul>\n<li><code>[array_push](https:\/\/www.php.net\/manual\/en\/function.array-push.php)<\/code>za dodanie nowego linku do listy<code>$views<\/code><\/li>\n<li><code>[sprintf](https:\/\/www.php.net\/manual\/en\/function.sprintf.php)<\/code>za bezpieczne dodanie nowego ci\u0105gu<\/li>\n<li><code>[add_query_arg](https:\/\/developer.wordpress.org\/reference\/functions\/add_query_arg\/)<\/code>do dodawania zestawu niestandardowych argument\u00f3w zapytania do bie\u017c\u0105cej strony.<\/li>\n<\/ul>\n<p>Nast\u0119pna sekcja kodu b\u0119dzie wygl\u0105da\u0107 tak:<\/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>Ale jeszcze nie sko\u0144czy\u0142em. Zauwa\u017c konkretnie, \u017ce wykonuj\u0119 wywo\u0142anie <code>[count](https:\/\/www.php.net\/manual\/en\/function.count.php)<\/code>na ko\u0144cu funkcji. Dzieje si\u0119 tak, abym m\u00f3g\u0142 poprawnie wy\u015bwietli\u0107 liczb\u0119 post\u00f3w, kt\u00f3re maj\u0105 ten atrybut.<\/p>\n<p>Napisz\u0119 do tego dwie funkcje pomocnicze, a potem wr\u00f3c\u0119 do <code>sizeof<\/code>wywo\u0142ania.<\/p>\n<hr \/>\n<p>Oto funkcja pomocnicza do znajdowania liczby wynik\u00f3w, kt\u00f3re maj\u0105 okre\u015blony <code>meta_key<\/code>i <code>meta_value<\/code>kt\u00f3re mamy dla tego typu postu. Zauwa\u017c, \u017ce u\u017cywam <code>[$wpdb](https:\/\/developer.wordpress.org\/reference\/classes\/wpdb\/)<\/code>do bezpo\u015bredniego wywo\u0142ania bazy danych i \u017ce specjalnie u\u017cywam <code>[prepare](https:\/\/developer.wordpress.org\/reference%2Fclasses%2Fwpdb%2Fprepare%2F\/)<\/code>, aby upewni\u0107 si\u0119, \u017ce robi\u0119 to bezpiecznie.<\/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>Zauwa\u017c, \u017ce zwraca wszystkie wyniki (nie tylko liczb\u0119), poniewa\u017c ta warto\u015b\u0107 zostanie chwilowo przekazana do innej funkcji.<\/p>\n<p>W tym momencie mogliby\u015bmy zatrzyma\u0107 si\u0119 i po prostu spojrze\u0107 na tre\u015b\u0107 zwr\u00f3con\u0105 z zapytania, ale je\u015bli interesuje nas tylko <code>post<\/code>typ posta, musimy to uwzgl\u0119dni\u0107. Oto jeden spos\u00f3b, aby to zrobi\u0107:<\/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>Dzi\u0119ki temu mo\u017cemy przywr\u00f3ci\u0107 t\u0119 warto\u015b\u0107 z powrotem do <code>count<\/code>funkcji powy\u017cej.<\/p>\n<hr \/>\n<p>Ostateczna wersja bloku, kt\u00f3ry zacz\u0119li\u015bmy powy\u017cej, powinna wygl\u0105da\u0107 mniej wi\u0119cej tak:<\/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>Oznacza to, \u017ce pe\u0142na wersja funkcji dodawania nowego nag\u0142\u00f3wka wygl\u0105da mniej wi\u0119cej tak:<\/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>I, jak wspomniano na pocz\u0105tku, ta wtyczka nie ma przestrzeni nazw ani nie jest zorganizowana w spos\u00f3b, w jaki zwykle pisz\u0119 kod. Zamiast tego ma zademonstrowa\u0107 spos\u00f3b na szybkie osi\u0105gni\u0119cie czego\u015b \u2013 swego rodzaju prototyp.<\/p>\n<p>Wi\u0119c je\u015bli chcesz zobaczy\u0107 co\u015b takiego w akcji, mo\u017cesz sprawdzi\u0107 repozytorium na GitHub. Zauwa\u017c, \u017ce w tej chwili jest to <strong><a href=\"https:\/\/github.com\/tommcfarlin\/custom-metadata-filter\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ga\u0142\u0105\u017a<\/a><\/strong> deweloperska. Pami\u0119taj, aby zobaczy\u0107, <code>[README](https:\/\/github.com\/tommcfarlin\/custom-metadata-filter\/blob\/develop\/README.md)<\/code>poniewa\u017c zawiera instrukcje dotycz\u0105ce dodawania danych do bazy danych dla post\u00f3w, aby kotwica <strong>nag\u0142\u00f3wk\u00f3w<\/strong> faktycznie dzia\u0142a\u0142a, a nie bezwarunkowo pokazywa\u0142a warto\u015b\u0107 zerow\u0105.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>W tym artykule opisano kod potrzebny do dodania niestandardowego \u0142\u0105cza na ekranie Wszystkie posty, kt\u00f3ry u\u017cywa niestandardowego fragmentu metadanych posta.<\/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":[721,919,897,805,836,845,866],"tags":[1169],"class_list":["post-231397","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-kod","category-php-7","category-przewodnik-dla-poczatkujacych","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/231397","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=231397"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/231397\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/158583"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=231397"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=231397"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=231397"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}