{"id":230634,"date":"2022-12-16T10:56:00","date_gmt":"2022-12-16T07:56:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230634"},"modified":"2022-12-07T11:40:17","modified_gmt":"2022-12-07T08:40:17","slug":"paginacja-wordpress-proste-narzedzie-i-dlaczego","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/paginacja-wordpress-proste-narzedzie-i-dlaczego\/","title":{"rendered":"Paginacja WordPress: proste narz\u0119dzie (i dlaczego)"},"content":{"rendered":"\n<p>Tworz\u0105c szablony dla WordPressa, zazwyczaj masz funkcje stronicowania, kt\u00f3re pochodz\u0105 z samej aplikacji.<\/p>\n<p>Nale\u017c\u0105 do nich takie rzeczy jak:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_next_post\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_next_post()<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_next_post_link\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_next_post_link()<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_previous_post\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_previous_post()<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_previous_post_link\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_previous_post_link()<\/a><\/li>\n<\/ul>\n<p>Jest te\u017c kilka innych post\u00f3w, kt\u00f3re zapewniaj\u0105 wi\u0119ksz\u0105 szczeg\u00f3\u0142owo\u015b\u0107 taksonomii, takich jak <strong><a href=\"https:\/\/tommcfarlin.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_adjacent_post()<\/a><\/strong>.<\/p>\n<p>Polecam przeczytanie wszystkich powy\u017cszych link\u00f3w, poniewa\u017c s\u0105 one przydatne, je\u015bli tworzysz motyw, pracujesz z niestandardowymi typami post\u00f3w lub po prostu szukasz g\u0142\u0119bszego zrozumienia niekt\u00f3rych typowych tag\u00f3w szablon\u00f3w.<\/p>\n<p>Je\u015bli jednak szukasz \u0142atwego sposobu na napisanie narz\u0119dzia do stronicowania WordPress (kt\u00f3remu wyja\u015bni\u0119 za chwil\u0119), to reszta tego postu dok\u0142adnie to om\u00f3wi.<\/p>\n<h2>Niestandardowa paginacja WordPress<\/h2>\n<p>Po pierwsze, za ka\u017cdym razem, gdy tworzysz dla kogo\u015b aplikacj\u0119 internetow\u0105, z pewno\u015bci\u0105 pojawi\u0105 si\u0119 niuanse, w kt\u00f3rych natywna funkcjonalno\u015b\u0107 WordPressa mo\u017ce nie dzia\u0142a\u0107. By\u0107 mo\u017ce nie dzia\u0142a zgodnie z oczekiwaniami, nie dzia\u0142a zgodnie z przeznaczeniem lub nie spe\u0142nia twoich potrzeb.<\/p>\n<p>W ka\u017cdym razie nie oznacza to, \u017ce nie mo\u017cna zbudowa\u0107 paginacji, aby s\u0142u\u017cy\u0142a twoim celom. W ko\u0144cu sedno paginacji \u2013 zw\u0142aszcza w odniesieniu do paginacji pojedynczego posta \u2013 polega w zasadzie na tym:<\/p>\n<p>Na podstawie bie\u017c\u0105cego wpisu sprawd\u017a, czy wpis istnieje przed nim i sprawd\u017a, czy istnieje wpis po nim. Je\u015bli istnieje kt\u00f3rykolwiek typ postu, podaj do niego link; w przeciwnym razie nie.<\/p>\n<p>St\u0105d mo\u017cemy ustali\u0107, \u017ce b\u0119dziemy potrzebowa\u0107 nast\u0119puj\u0105cych funkcji:<\/p>\n<ol>\n<li>spos\u00f3b na ustalenie, czy post istnieje za aktualnym postem,<\/li>\n<li>spos\u00f3b na ustalenie, czy post istnieje po aktualnym po\u015bcie,<\/li>\n<li>spos\u00f3b na odzyskanie danego posta,<\/li>\n<li>spos\u00f3b na uzyskanie permalinku dla danego posta.<\/li>\n<\/ol>\n<p>Jednak staram si\u0119 by\u0107 bardzo dok\u0142adny w powy\u017cszym j\u0119zyku, poniewa\u017c post, kt\u00f3ry jest \u201eza&quot; lub \u201epo&#8221; danym po\u015bcie, mo\u017ce nie mie\u0107 identyfikatora, kt\u00f3ry jest o jeden mniejszy ni\u017c identyfikator bie\u017c\u0105cego posta.<\/p>\n<p>To po prostu pierwszy opublikowany post, kt\u00f3ry mo\u017cna pobra\u0107 w dowolnym kierunku, prawda?<\/p>\n<p>Maj\u0105c to na uwadze, oznacza to, \u017ce b\u0119dziemy potrzebowa\u0107 dw\u00f3ch zapyta\u0144:<\/p>\n<ul>\n<li>zapytanie do pobrania posta za aktualnym postem,<\/li>\n<li>zapytanie do pobrania posta po aktualnym po\u015bcie.<\/li>\n<\/ul>\n<p>W tym przyk\u0142adzie zak\u0142adam, \u017ce masz dost\u0119p do identyfikatora bie\u017c\u0105cego wpisu poprzez funkcj\u0119 <strong><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_the_id\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_the_ID()<\/a><\/strong>.<\/p>\n<h3>Uzyskaj post za bie\u017c\u0105cym postem<\/h3>\n<p>Aby to zrobi\u0107, musimy utworzy\u0107 proste zapytanie, kt\u00f3re pobierze jeden opublikowany post z bazy danych okre\u015blonego typu posta i jest on powi\u0105zany z pozycj\u0105 bie\u017c\u0105cego posta.<\/p>\n<p><strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/763a68936f225834bba671a3d0a8b9f6#file-00-previous-post-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Mo\u017cemy to zrobi\u0107<\/a><\/strong>, ograniczaj\u0105c zestaw wynik\u00f3w do jednego, porz\u0105dkuj\u0105c wyniki w kolejno\u015bci malej\u0105cej i por\u00f3wnuj\u0105c warto\u015b\u0107 identyfikatora posta:<\/p>\n<pre><code>&lt;?php\n\nglobal $wpdb;\n$results = $wpdb-&gt;get_results(\n    $wpdb-&gt;prepare(\n        \"\n        SELECT *\n        FROM $wpdb-&gt;posts\n        WHERE ID &lt; (SELECT ID\n            FROM $wpdb-&gt;posts\n            WHERE ID = %d\n            AND post_type = '%s'\n            AND post_status = '%s'\n            ORDER BY ID DESC) AND post_type = '%s'\n        AND post_status = '%s'\n        ORDER BY ID DESC\n        LIMIT 1\n        \",\n        get_the_ID(),\n        'acme-custom-post-type',\n        'publish',\n        'acme-custom-post-type',\n        'publish') );<\/code><\/pre>\n<p>Spowoduje to zwr\u00f3cenie tablicy wynik\u00f3w, kt\u00f3rymi za chwil\u0119 zobaczymy, jak zarz\u0105dza\u0107.<\/p>\n<h3>Pobierz post po bie\u017c\u0105cym po\u015bcie<\/h3>\n<p><strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/763a68936f225834bba671a3d0a8b9f6#file-01-next-post-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">W kolejnym po\u015bcie<\/a><\/strong> piszemy podobne zapytanie. Zamiast tego szukamy nast\u0119pnej warto\u015bci, kt\u00f3ra jest wi\u0119ksza i kt\u00f3ra wyprzedza obecny identyfikator:<\/p>\n<pre><code>&lt;?php\n\nglobal $wpdb;\n$results = $wpdb-&gt;get_results(\n    $wpdb-&gt;prepare(\n        \"\n        SELECT *\n        FROM $wpdb-&gt;posts\n        WHERE ID &gt; (SELECT ID\n            FROM $wpdb-&gt;posts\n            WHERE ID = %d\n            AND post_type = '%s'\n            AND post_status = '%s'\n            ORDER BY ID ASC) AND post_type = '%s'\n        AND post_status = '%s'\n        ORDER BY ID ASC\n        LIMIT 1\n        \",\n        get_the_ID(),\n        'acme-custom-post-type',\n        'publish',\n        'acme-custom-post-type',\n        'publish') );<\/code><\/pre>\n<p>Teraz potrzebujemy kilku funkcji, aby okre\u015bli\u0107, czy posty istniej\u0105. Mo\u017cemy to zrobi\u0107 za pomoc\u0105 zwr\u00f3conej tablicy wynik\u00f3w.<\/p>\n<h3>Sprawd\u017a, czy post istnieje<\/h3>\n<p>Zauwa\u017c, \u017ce <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/763a68936f225834bba671a3d0a8b9f6#file-03-has-previous-post-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">w poni\u017cszym przyk\u0142adzie<\/a><\/strong> funkcja akceptuje tablic\u0119 wynik\u00f3w i po prostu zwraca, je\u015bli istnieje poprzedni wpis. Wyniki przekazywane do tej funkcji powinny pochodzi\u0107 z poprzedniego zapytania post powy\u017cej.<\/p>\n<p>Po drugie, zauwa\u017c, \u017ce jest prywatny. Mo\u017cesz chcie\u0107 upubliczni\u0107 sw\u00f3j szablon w zale\u017cno\u015bci od tego, jak chcesz skonstruowa\u0107 swoje szablony.<\/p>\n<pre><code>&lt;?php \n\/**\n * @param array $results the results of the query to determined if there are past posts\n *\n * @return bool true if there is a previous post; otherwise, false\n *\/\nprivate function hasPreviousPost($results)\n{\n    return isset($results[0]);\n}<\/code><\/pre>\n<p>W <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/763a68936f225834bba671a3d0a8b9f6#file-04-has-next-post-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">nast\u0119pnym po\u015bcie<\/a><\/strong> wygl\u0105da to tak samo, ale pami\u0119taj, \u017ce wyniki przekazywane do tej funkcji pochodz\u0105 z innego zapytania.<\/p>\n<pre><code>&lt;?php\n\/**\n * @param array $results the results of the query to determined if there are future posts\n *\n * @return bool true if there is a next post; otherwise, false\n *\/\nprivate function hasNextPost($results)\n{\n    return isset($results[0]);\n}<\/code><\/pre>\n<p>I wreszcie, mo\u017cemy u\u017cy\u0107 tych funkcji warunkowych, aby uzyska\u0107 bezpo\u015bredni link.<\/p>\n<h3>Uzyskaj link<\/h3>\n<p>Pami\u0119taj, \u017ce spos\u00f3b, w jaki korzystasz z tej funkcji, mo\u017ce r\u00f3\u017cni\u0107 si\u0119 od dostarczonej przeze mnie implementacji. Je\u015bli wi\u0119c nie chcesz, aby by\u0142 prywatny, zmie\u0144 jego widoczno\u015b\u0107 i u\u017cyj go w swoim szablonie w <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/763a68936f225834bba671a3d0a8b9f6#file-05-get-post-link-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">razie potrzeby<\/a><\/strong>.<\/p>\n<pre><code>&lt;?php\n\/**\n * @param array $results the results of the array from which to retrieve the post ID\n *\n * @return string the ID of the post to which we're going to link\n *\/\nprivate function getPostLink($results)\n{\n    return get_the_permalink($results[0]-&gt;ID);\n}<\/code><\/pre>\n<p>Na koniec zauwa\u017c, \u017ce ta funkcja akceptuje wyniki przekazywane do niej z dowolnego zapytania i pobierze w\u0142a\u015bciwo\u015b\u0107 ID z pierwszego indeksu wynik\u00f3w.<\/p>\n<p>Dzieje si\u0119 tak, poniewa\u017c wyniki s\u0105 ograniczone do jednego i zale\u017c\u0105 od u\u017cycia funkcji warunkowych. Oznacza to, \u017ce mo\u017cesz zrobi\u0107 co\u015b takiego:<\/p>\n<ul>\n<li>je\u015bli jest nast\u0119pny post, uzyskaj link do nast\u0119pnego posta<\/li>\n<\/ul>\n<p>Ale twoja implementacja mo\u017ce si\u0119 r\u00f3\u017cni\u0107.<\/p>\n<h2>Dlaczego jest to potrzebne?<\/h2>\n<p>Mo\u017ce nie by\u0107 potrzebne. To wszystko: je\u015bli korzystasz z gotowego WordPressa z bardzo niewielkimi dostosowaniami lub rozszerzeniami i nie musisz robi\u0107 niczego poza tym, co mo\u017ce zapewni\u0107, mo\u017cesz tego nie potrzebowa\u0107.<\/p>\n<p>Je\u015bli z drugiej strony szukasz sposobu na wprowadzenie funkcji stronicowania WordPress w pojedynczym po\u015bcie, to jest to spos\u00f3b, kt\u00f3ry mo\u017ce w\u0142a\u015bciwie obs\u0142u\u017cy\u0107 przypadki post\u00f3w, kt\u00f3re s\u0105 okre\u015blonego typu, ale nie t mie\u0107 identyfikatory sekwencyjne (kt\u00f3re dzia\u0142aj\u0105 tylko ze statusem publikacji posta).<\/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>Podczas tworzenia aplikacji internetowej z pewno\u015bci\u0105 pojawi\u0105 si\u0119 niuanse, w kt\u00f3rych natywna funkcjonalno\u015b\u0107 mo\u017ce nie dzia\u0142a\u0107. Mo\u017cesz potrzebowa\u0107 niestandardowej paginacji WordPress.<\/p>\n","protected":false},"author":1,"featured_media":236123,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,897,805,866],"tags":[1169],"class_list":["post-230634","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-kod","category-php-7","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230634","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=230634"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230634\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/236123"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=230634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=230634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=230634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}