{"id":230179,"date":"2022-12-06T14:52:00","date_gmt":"2022-12-06T11:52:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230179"},"modified":"2022-12-06T15:02:51","modified_gmt":"2022-12-06T12:02:51","slug":"organizowanie-typow-widokow-i-subskrybentow-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/organizowanie-typow-widokow-i-subskrybentow-wordpress\/","title":{"rendered":"Organizowanie typ\u00f3w, widok\u00f3w i subskrybent\u00f3w WordPress"},"content":{"rendered":"\n<p>Jedn\u0105 z rzeczy, kt\u00f3re staram si\u0119 robi\u0107 regularnie, jest usprawnienie sposobu budowania funkcjonalno\u015bci skoncentrowanej na WordPressie. <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pl\/prosty-przewodnik-po-organizacji-zajec-opartych-na-wordpressie\/\" title=\"Niedawno o tym m\u00f3wi\u0142em\">Niedawno o tym m\u00f3wi\u0142em<\/a><\/strong>, ale pomy\u015bla\u0142em, \u017ce rozszerz\u0119 to troch\u0119 bardziej.<\/p>\n<p>To znaczy, pomy\u015bla\u0142em, \u017ce przedstawi\u0119 podej\u015bcie, kt\u00f3re przyjm\u0119 podczas tworzenia takich rzeczy, jak niestandardowe typy post\u00f3w, taksonomie, metaboxy i tak dalej.<\/p>\n<p>Og\u00f3lnie rzecz bior\u0105c, pomy\u015bl o tym jako o strategii, kt\u00f3r\u0105 stosuj\u0119 do budowania aspekt\u00f3w projektu, kt\u00f3ry jest bezpo\u015brednio po\u0142\u0105czony z WordPress, ale mo\u017ce wymaga\u0107 kilku komponent\u00f3w, takich jak:<\/p>\n<ul>\n<li>klasy, kt\u00f3re rejestruj\u0105 si\u0119 w WordPressie poprzez r\u00f3\u017cne hooki,<\/li>\n<li>klasy, kt\u00f3re wymagaj\u0105 wywo\u0142a\u0144 okre\u015blonych API WordPress<\/li>\n<li>i klasy, kt\u00f3re wymagaj\u0105 niestandardowego widoku.<\/li>\n<\/ul>\n<p>Jasne, nie wszystko, co \u0142\u0105czy si\u0119 z WordPressem, b\u0119dzie wymaga\u0142o wszystkich powy\u017cszych (na przyk\u0142ad, czy niestandardowy typ posta wymaga widoku? Nie. Ale metabox tak).<\/p>\n<h2>Organizowanie typ\u00f3w WordPress<\/h2>\n<p>Powiedziawszy to, zamierzam wzi\u0105\u0107 bardziej zaanga\u017cowany przyk\u0142ad, taki jak metabox, a nast\u0119pnie podzieli\u0107 spos\u00f3b, w jaki my\u015bl\u0119, \u017ce mo\u017cna go zaimplementowa\u0107. Zanotuj\u0119 rzeczy, kt\u00f3re uwa\u017cam za konieczne i te, kt\u00f3re s\u0105 opcjonalne.<\/p>\n<p>I, jak powiedzia\u0142em, u\u017cywam meta pola jako przyk\u0142adu, poniewa\u017c mam poprzednie odniesienie i wymaga to najwi\u0119kszej ilo\u015bci pracy, podczas gdy co\u015b innego, takie jak niestandardowa taksonomia, mo\u017ce nie wymaga\u0107 wszystkich (tylko podzbioru) element\u00f3w .<\/p>\n<p>Powiedziawszy to, pozw\u00f3l, \u017ce przedstawi\u0119 moje podej\u015bcie.<\/p>\n<h3>Potrzebujemy subskrybent\u00f3w<\/h3>\n<p>Opowiedzia\u0142em o tym konkretnym wzorcu wystarczaj\u0105co do momentu, w kt\u00f3rym po prostu po\u0142\u0105cz\u0119 si\u0119 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Publish%E2%80%93subscribe_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">z jego definicj\u0105<\/a>. Je\u015bli czytasz t\u0119 stron\u0119, prawdopodobnie dobrze wiesz o r\u00f3\u017cnych haczykach i sposobach ich u\u017cywania w WordPressie.<\/p>\n<p>Zdj\u0119cie autorstwa Alexandra Andrewsa na Unsplash<\/p>\n<p>Ale powodem, dla kt\u00f3rego chc\u0119 o tym wspomnie\u0107, jest to, \u017ce zamiast my\u015ble\u0107 o pod\u0142\u0105czaniu funkcji do uruchamiania, gdy co\u015b si\u0119 dzieje, chc\u0119, aby\u015b pomy\u015bla\u0142 o obiekcie, kt\u00f3ry subskrybuje zdarzenie, gdy ono wyst\u0105pi.<\/p>\n<p>Oznacza to, \u017ce b\u0119dziemy potrzebowa\u0107 typu klasy subskrybenta.<\/p>\n<h3>Klasy API WordPress<\/h3>\n<p>Po drugie, potrzebujemy klas, kt\u00f3re s\u0105 odpowiedzialne za bezpo\u015brednie po\u0142\u0105czenie z WordPressem. S\u0105 to klasy, kt\u00f3re wywo\u0142uj\u0105 API WordPressa i rejestruj\u0105 wszystko, za co s\u0105 odpowiedzialne.<\/p>\n<p>Oznacza to, \u017ce by\u0107 mo\u017ce zdefiniuj\u0105 niestandardowy typ posta, a mo\u017ce, jak wspomniano, zdefiniuj\u0105 pole meta.<\/p>\n<h3>Definiowanie widok\u00f3w<\/h3>\n<p>Na koniec wa\u017cne jest, aby pami\u0119ta\u0107, \u017ce w przypadku niekt\u00f3rych niestandardowych funkcji dla obszaru administracyjnego WordPress (lub nawet obszar\u00f3w publicznych) mo\u017cesz chcie\u0107 do\u0142\u0105czy\u0107 widok, szablon lub cz\u0119\u015b\u0107 (zwykle nazywam je po prostu widokami), kt\u00f3re b\u0119d\u0105 pracy do reprezentowania danych dla pola meta.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162654-61e741fa06c63.jpg\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-162654-61e741fa06c63.jpg\" alt=\"Organizowanie typ\u00f3w, widok\u00f3w i subskrybent\u00f3w WordPress\"><\/a><\/p>\n<p>Zdj\u0119cie: Saketh Garuda na Unsplash<\/p>\n<p>Czasami b\u0119dzie to po prostu informacyjne. Czasami b\u0119dzie to wymaga\u0107 odes\u0142ania z powrotem do serwera i serializacji danych. Chocia\u017c my\u015bl\u0119, \u017ce rozmowa o tym ostatnim by\u0142aby naprawd\u0119 korzystna, wykracza to poza obecny zakres tego postu.<\/p>\n<p>By\u0107 mo\u017ce w przysz\u0142ym po\u015bcie.<\/p>\n<h2>Organizowanie zaj\u0119\u0107<\/h2>\n<p>Co to wszystko powiedzia\u0142o, jak by to wygl\u0105da\u0142o, gdyby to wszystko roz\u0142o\u017cy\u0107? Przynajmniej patrzymy na:<\/p>\n<ul>\n<li>subskrybent,<\/li>\n<li>typu WordPress,<\/li>\n<li>widok<\/li>\n<\/ul>\n<p>Co najwy\u017cej mo\u017cesz by\u0107 zainteresowany zdefiniowaniem interfejs\u00f3w lub klas abstrakcyjnych, aby pom\u00f3c w egzekwowaniu umowy mi\u0119dzy r\u00f3\u017cnymi typami WordPressa. Jest to r\u00f3wnie\u017c zdrowa zasada zorientowania obiektowego, o kt\u00f3rej opowiem w przysz\u0142ym po\u015bcie.<\/p>\n<p>Na razie jednak porozmawiajmy o tym, jak skonfigurowa\u0107 ka\u017cdy z nich.<\/p>\n<h3>Abonent<\/h3>\n<p>M\u00f3wi\u0105c najpro\u015bciej, subskrybent jest odpowiedzialny za s\u0142uchanie, gdy WordPress zg\u0142asza zdarzenie (publikuje zdarzenie). A kiedy zauwa\u017cy, \u017ce tak, uruchamia funkcj\u0119, kt\u00f3ra jest z nim pod\u0142\u0105czona.<\/p>\n<p>Jest to og\u00f3lnie zdefiniowane we wzorcu rejestru. Je\u015bli nie czyta\u0142e\u015b tego posta, polecam, ale ustawienie kodu <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-00-acme-meta-box-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jest do\u015b\u0107 \u0142atwe:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nclass AcmeMetaBoxSubscriber extends AbstractSubscriber\n{\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    public function load()\n    {\n        (new AcmeMetaBox())-&gt;render();\n    }\n}\n<\/code><\/pre>\n<p>Stamt\u0105d, za ka\u017cdym razem, gdy zdarzenie zostanie wywo\u0142ane, funkcja zostanie uruchomiona. Oto jednak rzecz: funkcja musi by\u0107 cz\u0119\u015bci\u0105 pewnej klasy. Tak wi\u0119c potrzeba WordPress typu<\/p>\n<h3>Typ WordPress<\/h3>\n<p>Lubi\u0119 traktowa\u0107 typy rzeczy, kt\u00f3re wsp\u00f3\u0142pracuj\u0105 z WordPressem jako typy WordPress (podobnie jak nasze j\u0119zyki programowania maj\u0105 natywne typy, takie jak ci\u0105gi i liczby ca\u0142kowite). WordPress zawiera taksonomie, metaboxy, menu i tak dalej.<\/p>\n<p>Aby nasz subskrybent m\u00f3g\u0142 prawid\u0142owo dzia\u0142a\u0107, musi by\u0107 \u015bwiadomy naszego typu WordPress. Zgodnie z przyk\u0142adem metabox, <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-01-acme-meta-box-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">oto jak mo\u017ce wygl\u0105da\u0107:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nclass AcmeMetaBox extends AbstractMetaBox\n{\n    public function render()\n    {\n        add_meta_box(\n            'acme-data',\n            'Acme Data',\n            [$this, 'display'],\n            $this-&gt;postType,\n            'normal',\n            'high'\n        );\n    }\n\n    public function display()\n    {\n        include_once plugin_dir_path(__FILE__).'Views\/acme-data.php';\n    }\n}\n<\/code><\/pre>\n<p>Nast\u0119pnie musimy upewni\u0107 si\u0119, \u017ce rejestr jest \u015bwiadomy tej klasy.<\/p>\n<h3>Widok<\/h3>\n<p>Na koniec, w przypadku meta pola, musimy upewni\u0107 si\u0119, \u017ce istnieje widok, kt\u00f3ry przynajmniej wy\u015bwietli informacje. Serializowanie informacji, a nast\u0119pnie aktualizowanie widoku dla u\u017cytkownika to troch\u0119 inna bestia.<\/p>\n<p>Ale jak mo\u017ce wygl\u0105da\u0107 widok? <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-02-acme-data-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">\u0141atwy<\/a><\/strong> :<\/p>\n<pre><code>&lt;div class=\"acme-data-metabox\"&gt;\n  &lt;?php echo __('Acme Data', 'acme-meta-box'); ?&gt;\n  &lt;p class=\"description\"&gt;\n    This is the content of the metabox.\n  &lt;\/p&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p>To tylko podstawowe znaczniki, kt\u00f3re renderuj\u0105 informacje u\u017cytkownikowi.<\/p>\n<h2>\u0141\u0105cz\u0105c to wszystko razem<\/h2>\n<p>Ilekro\u0107 \u0142\u0105cz\u0119 to wszystko razem, zwykle mam klas\u0119 wtyczek, od kt\u00f3rej wszystko si\u0119 zaczyna. Je\u015bli projekt jest du\u017cy, mo\u017ce by\u0107 ich wi\u0119cej ni\u017c jeden, ale w tym przypadku my\u015bl\u0119, \u017ce mo\u017cna pokaza\u0107, jak to wygl\u0105da, u\u017cywaj\u0105c jednej klasy.<\/p>\n<p>Po pierwsze, g\u0142\u00f3wna klasa wtyczki <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-03-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wygl\u0105da tak:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nclass Plugin\n{\n    private $registry;\n\n    public function __construct(Registry $registry)\n    {\n        $this-&gt;registry = $registry;\n    }\n\n    public function start()\n    {\n        array_map(function ($subscriber) {\n            add_action($subscriber-&gt;getHook(), [$subscriber, 'load']);\n        }, $this-&gt;registry-&gt;getRegisteredSubscribers());\n    }\n}\n<\/code><\/pre>\n<p>A bootstrap dla wtyczki <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/274b69d0fc1e39aaf51384287240cea6#file-04-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wygl\u0105da tak:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('acmeApiRegistry', function() use ($registry) {\n    return $registry;\n});\n\n\/\/ Register all of our objects with a basic registry.\n$registry-&gt;add('acmeMetaBoxSubscriber', new AcmeMetaBoxSubscriber('add_meta_boxes'));\n\n$plugin = new Plugin($registry);\n$plugin-&gt;start();<\/code><\/pre>\n<p>I od tego momentu wszystko inne jest w ruchu.<\/p>\n<h2>A co z bardziej zaawansowan\u0105 funkcjonalno\u015bci\u0105?<\/h2>\n<p>Podnosz\u0119 to pytanie, poniewa\u017c ju\u017c troch\u0119 o tym m\u00f3wi\u0142em wcze\u015bniej w po\u015bcie. Mianowicie m\u00f3wi\u0142em o:<\/p>\n<ol>\n<li>pomys\u0142 wysy\u0142ania danych z powrotem na serwer (i prawdopodobnie ponownego ich odczytania),<\/li>\n<li>i m\u00f3wi\u0142em o u\u017cyciu interfejs\u00f3w.<\/li>\n<\/ol>\n<p>My\u015bl\u0119, \u017ce s\u0105 to obie rzeczy, kt\u00f3re warto zbada\u0107 bardziej szczeg\u00f3\u0142owo. Ale zanim to zrobisz, k\u0142ad\u0119 podwaliny pod to, jak organizuj\u0119 te informacje, s\u0105 one zbudowane, szczeg\u00f3lnie bior\u0105c pod uwag\u0119, \u017ce s\u0105 oparte na poprzednich postach, takich jak <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pl\/korzystanie-z-wzorca-rejestru-w-wordpress\/\" title=\"Wzorzec rejestru\">Wzorzec rejestru<\/a><\/strong> i organizowanie klas opartych na WordPressie r\u00f3wnie\u017c za pomoc\u0105 <strong><a href=\"https:\/\/wordpress.mediadoma.com\/pl\/prosty-przewodnik-po-organizacji-zajec-opartych-na-wordpressie\/\" title=\"metabox\u00f3w\">metabox\u00f3w<\/a><\/strong>.<\/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>Organizowanie typ\u00f3w WordPress, widok\u00f3w, subskrybent\u00f3w i innych powi\u0105zanych materia\u0142\u00f3w mo\u017ce by\u0107 systematyczne. To dobrze, poniewa\u017c daje nam powtarzalny spos\u00f3b budowania r\u00f3\u017cnych projekt\u00f3w dla naszych klient\u00f3w.<\/p>\n","protected":false},"author":1,"featured_media":162655,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[866],"tags":[1169],"class_list":["post-230179","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230179","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=230179"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230179\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/162655"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=230179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=230179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=230179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}