{"id":228286,"date":"2022-10-18T11:41:00","date_gmt":"2022-10-18T08:41:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228286"},"modified":"2022-11-09T01:41:57","modified_gmt":"2022-11-08T22:41:57","slug":"korzystanie-z-edytora-blokow-wordpress-gutenberg-z-interfejsem-api-rest","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/korzystanie-z-edytora-blokow-wordpress-gutenberg-z-interfejsem-api-rest\/","title":{"rendered":"Korzystanie z edytora blok\u00f3w WordPress (Gutenberg) z interfejsem API REST"},"content":{"rendered":"\n<p>W moim poprzednim artykule m\u00f3wi\u0142em o <a href=\"https:\/\/wholesomecode.ltd\/articles\/wp_query-and-the-wordpress-block-editor-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tym, jak zap\u0119tli\u0107 posty i niestandardowe typy post\u00f3w w Gutenbergu<\/a>. W tym po\u015bcie m\u00f3wi\u0119 o otrzymywaniu i u\u017cywaniu niestandardowych danych w obr\u0119bie Gutenberga z punkt\u00f3w ko\u0144cowych WordPress REST API.<\/p>\n<p>W tym przyk\u0142adzie zamierzamy:<\/p>\n<p><strong>REST API nie zawsze jest w\u0142a\u015bciw\u0105 \u015bcie\u017ck\u0105.<\/strong><\/p>\n<p>*W REST API u\u017cywamy <code>get_option<\/code>tylko jako przyk\u0142adu. Je\u015bli potrzebujesz tylko dost\u0119pu do opcji i nie zamierzasz zmienia\u0107 jej stanu, mo\u017cesz zamiast tego <code>wp_localize_script<\/code>przekaza\u0107 opcje do JavaScript.<\/p>\n<p>Je\u015bli chcesz uzyska\u0107 dost\u0119p do opcji ORAZ zmieni\u0107 jej stan, polecam przeczytanie mojego <a href=\"https:\/\/wholesomecode.ltd\/guides\/options-settings-data-wordpress-gutenberg\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">przewodnika na temat przechowywania ustawie\u0144 i danych w tabeli opcji za pomoc\u0105 Gutenberga za pomoc\u0105 interfejsu API ustawie\u0144<\/a> .*<\/p>\n<h2>Tworzenie punktu ko\u0144cowego interfejsu API REST<\/h2>\n<p>Stworzymy prosty punkt ko\u0144cowy REST API, kt\u00f3ry zwraca warto\u015b\u0107 opcji WordPress (za pomoc\u0105 <code>get_option<\/code>).<\/p>\n<pre><code>function wcltd_get_option() {\n    register_rest_route(\n        'wcltd\/wholesome-plugin\/v1',\n        '\/get\/option\/(?P&lt;option&gt;([A-Za-z0-9_])+)\/',\n        array(\n            'callback'            =&gt; function ($request) {\n                $option = isset( $request['option'] )? esc_attr( $request['option'] ): null;\n                $value  = get_option( $option, '' );\n                return $value;\n            },\n            'methods'             =&gt; 'GET',) );\n}\nadd_action( 'rest_api_init', 'wcltd_get_option' );\n<\/code><\/pre>\n<p>Po utworzeniu tego punktu ko\u0144cowego pami\u0119taj o <strong>ponownym zapisaniu permalink\u00f3w<\/strong>, aby uruchomi\u0142 si\u0119. Zauwa\u017c, \u017ce s\u0105 lepsze sposoby na zrobienie tego (na przyk\u0142ad u\u017cycie <code>flush_rewrite_rules()<\/code>w <code>register_activation_hook<\/code>), ale w tym przyk\u0142adzie wystarczy szybkie ponowne zapisanie.<\/p>\n<p>Teraz, gdy przeka\u017cemy adres URL <code>\/wp-json\/wcltd\/wholesome-plugin\/v1\/get\/option\/test\/<\/code>(oczywi\u015bcie po Twojej w\u0142asnej domenie) do naszej przegl\u0105darki, zwr\u00f3ci ona warto\u015b\u0107, kt\u00f3ra mo\u017ce by\u0107 albo pustym ci\u0105giem, <code>''<\/code>albo warto\u015bci\u0105 opcji, je\u015bli jest ustawiona.<\/p>\n<p><a href=\"https:\/\/cdn.hashnode.com\/res\/hashnode\/image\/upload\/v1639990082853\/S6umfXuzNF.png\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Nasz punkt ko\u0144cowy, zwracaj\u0105cy pusty ci\u0105g<\/a> Nasz punkt ko\u0144cowy, zwracaj\u0105cy pusty ci\u0105g<\/p>\n<p>Zwr\u00f3\u0107 uwag\u0119, \u017ce celowo wykomentowa\u0142em wiersze 12-14, co zapewni\u0142oby, \u017ce tylko kto\u015b, kto ma <code>edit_post<\/code>uprawnienia, mo\u017ce uruchomi\u0107 kod, je\u015bli zostanie pozostawiony. Jednak z tym zakomentowaniem nie mo\u017cemy przetestowa\u0107 kodu w naszej przegl\u0105darce.<\/p>\n<p>Spr\u00f3buj doda\u0107 kod, aby nada\u0107 opcji warto\u015b\u0107 i zobacz, co zwraca. Na przyk\u0142ad, gdybym mia\u0142 uruchomi\u0107 nast\u0119puj\u0105cy kod przed moj\u0105 funkcj\u0105:<\/p>\n<pre><code>update_option( 'wcltd_example_option', 'Hello World' );\n<\/code><\/pre>\n<p>Teraz, je\u015bli trafi\u0119 w punkt ko\u0144cowy <code>\/wp-json\/wcltd\/wholesome-plugin\/v1\/get\/option\/wcltd_example_option\/<\/code>, otrzymam nast\u0119puj\u0105ce dane wyj\u015bciowe:<\/p>\n<p>Nasz punkt ko\u0144cowy, zwracaj\u0105cy troch\u0119 danych.<\/p>\n<h2>Rejestracja magazynu danych<\/h2>\n<p>Teraz, gdy mamy punkt ko\u0144cowy REST API, mo\u017cemy utworzy\u0107 magazyn danych za pomoc\u0105 <code>registerStore<\/code>.<\/p>\n<p><code>registerStore<\/code>zapewnia magazyn danych podobny do Redux, kt\u00f3ry umo\u017cliwia nam zarz\u0105dzanie stanem w ca\u0142ej naszej aplikacji. Obs\u0142uguje r\u00f3wnie\u017c przeliczniki, kt\u00f3re umo\u017cliwiaj\u0105 nam wype\u0142nienie stanu z zewn\u0119trznego \u017ar\u00f3d\u0142a (takiego jak nasz REST API).<\/p>\n<p>Wi\u0119cej o stanie REACT mo\u017cna <a href=\"https:\/\/reactjs.org\/docs\/state-and-lifecycle.html\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">przeczyta\u0107 w oficjalnej dokumentacji<\/a>.<\/p>\n<p>Oto jak mo\u017cemy stworzy\u0107 sklep (jak <code>store.js<\/code>w naszym projekcie, kt\u00f3ry pozwoli nam pobiera\u0107 dane z naszego endpointu REST API.<\/p>\n<h3>Zale\u017cno\u015bci<\/h3>\n<p>B\u0119dziemy musieli wyodr\u0119bni\u0107 <code>apiFetch<\/code>i <code>registerStore<\/code>z naszych zale\u017cno\u015bci od WordPressa.<\/p>\n<pre><code>import apiFetch from '@wordpress\/api-fetch';\nimport { registerStore } from '@wordpress\/data';\n<\/code><\/pre>\n<h3>Selektory<\/h3>\n<p>Pierwsz\u0105 rzecz\u0105, kt\u00f3r\u0105 chcemy zrobi\u0107, jest utworzenie funkcji selektora w obiekcie zwanym selektorami.<\/p>\n<p>Wszystko, co robi, to wyodr\u0119bnienie \u201eopcji&quot; ze stanu i zwr\u00f3cenie jej.<\/p>\n<pre><code>const selectors = {\n    getOption( state, optionKey) {\n        const { option } = state;\n        return option;\n    },\n};\n<\/code><\/pre>\n<h3>Resolwery<\/h3>\n<p>Przelicznik jest efektem ubocznym selektora i robi troch\u0119 wi\u0119cej.<\/p>\n<p>Tutaj tworzymy nasz\u0105 funkcj\u0119, kt\u00f3ra pobiera nasz optionKey i przekazuje punkt ko\u0144cowy REST API do naszych akcji (kt\u00f3re zdefiniujemy dalej).<\/p>\n<p>To nast\u0119pnie ustawia opcj\u0119, z kolejnym wezwaniem do naszych dzia\u0142a\u0144.<\/p>\n<pre><code>const resolvers = {\n    *getOption( optionKey) {\n        const option = yield actions.getOption(\n            '\/wcltd\/wholesome-plugin\/v1\/get\/option\/' + optionKey + '\/',\n        );\n        return actions.setOption( option );\n    },\n};\n<\/code><\/pre>\n<h3>dzia\u0142ania<\/h3>\n<p><code>actions<\/code>W tym miejscu zdefiniowane s\u0105 dwie funkcje w obiekcie o nazwie, kt\u00f3ry wywo\u0142ali\u015bmy wcze\u015bniej.<\/p>\n<p>Wskazuj\u0105, kt\u00f3rego regulatora lub reduktora b\u0119dziemy u\u017cywa\u0107 do ustawienia lub uzyskania warto\u015bci.<\/p>\n<pre><code>const actions = {\n    setOption( option) {\n        return {\n            type: 'SET_OPTION',\n            option,\n        };\n    },\n    getOption( path) {\n        return {\n            type: 'GET_OPTION',\n            path,\n        };\n    },\n};\n<\/code><\/pre>\n<h3>Sterownica<\/h3>\n<p>W naszych kontrolkach mamy <code>GET_OPTION<\/code>co sprawia, \u017ce \u200b\u200bwywo\u0142anie API wykorzystuje <code>apiFetch<\/code>i \u015bcie\u017ck\u0119, kt\u00f3r\u0105 zdefiniowali\u015bmy wcze\u015bniej.<\/p>\n<pre><code>const controls = {\n    GET_OPTION( action) {\n        return apiFetch( { path: action.path } );\n    },\n};\n<\/code><\/pre>\n<h3>Reduktor<\/h3>\n<p>W naszej funkcji reduktora mamy funkcj\u0119, <code>SET_OPTION<\/code>kt\u00f3ra przyjmuje nasz\u0105 warto\u015b\u0107 (w tym przypadku <code>option<\/code>, i ustawia sw\u00f3j stan).<\/p>\n<pre><code>function reducer( state = { option: '' }, action) {\n    switch (action.type) {\n        case 'SET_OPTION':\n            return {\n                ...state,\n                option: action.option,\n            };\n    }\n    return state;\n};\n<\/code><\/pre>\n<h3>Rejestracja Sklepu<\/h3>\n<p>Na koniec rejestrujemy sklep, nadajemy mu przestrze\u0144 nazw, aby mie\u0107 do niego dost\u0119p, i przekazujemy obiekt wszystkich powy\u017cszych obiekt\u00f3w i funkcji.<\/p>\n<pre><code>const store = registerStore(\n    'wcltd\/wholesome-plugin\/data',\n    {\n        actions,\n        controls,\n        reducer,\n        resolvers,\n        selectors,\n    }\n);\n\nexport default store;\n<\/code><\/pre>\n<p>eksportuj domy\u015blny sklep;<\/p>\n<h2>U\u017cywanie danych z blokiem<\/h2>\n<p>Rozwi\u0144my <a href=\"https:\/\/wholesomecode.ltd\/articles\/an-overview-of-the-wordpress-create-block-script\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">blok stworzony przez <code>@wordpress\/create-block<\/code>skrypt, o kt\u00f3rym pisa\u0142em wcze\u015bniej<\/a>, aby umo\u017cliwi\u0107 nam po\u0142\u0105czenie si\u0119 z punktem ko\u0144cowym REST API.<\/p>\n<p>Utw\u00f3rz plik w <code>\/src<\/code>folderze o nazwie <code>store.js<\/code>i skopiuj do niego ca\u0142y powy\u017cszy kod:<\/p>\n<pre><code>import apiFetch from '@wordpress\/api-fetch';\nimport { registerStore } from '@wordpress\/data';\n\nconst selectors = {\n    getOption( state, optionKey) {\n        const { option } = state;\n        return option;\n    },\n};\n\nconst resolvers = {\n    *getOption( optionKey) {\n        const option = yield actions.getOption(\n            '\/wcltd\/wholesome-plugin\/v1\/get\/option\/' + optionKey + '\/',\n        );\n        return actions.setOption( option );\n    },\n};\n\nconst actions = {\n    setOption( option) {\n        return {\n            type: 'SET_OPTION',\n            option,\n        };\n    },\n    getOption( path) {\n        return {\n            type: 'GET_OPTION',\n            path,\n        };\n    },\n};\n\nconst controls = {\n    GET_OPTION( action) {\n        return apiFetch( { path: action.path } );\n    },\n};\n\nfunction reducer( state = { option: '' }, action) {\n    switch (action.type) {\n        case 'SET_OPTION':\n            return {\n                ...state,\n                option: action.option,\n            };\n    }\n    return state;\n};\n\nconst store = registerStore(\n    'wcltd\/wholesome-plugin\/data',\n    {\n        actions,\n        controls,\n        reducer,\n        resolvers,\n        selectors,\n    }\n);\n\nexport default store;\n<\/code><\/pre>\n<p>Teraz edytuj nasz <code>\/src\/index.js<\/code>plik, aby do\u0142\u0105czy\u0107 <code>store.js<\/code>plik:<\/p>\n<pre><code>\nimport store from '.\/store';\nimport Edit from '.\/edit';\nimport save from '.\/save';\n<\/code><\/pre>\n<p>Musimy r\u00f3wnie\u017c upewni\u0107 si\u0119, \u017ce <code>withSelect<\/code>u g\u00f3ry naszego pliku umie\u015bcili\u015bmy:<\/p>\n<pre><code>import { withSelect } from '@wordpress\/data';\n<\/code><\/pre>\n<p>Nast\u0119pnie zapakujmy nasz modu\u0142 Edit, <code>withSelect<\/code>aby wywo\u0142a\u0107 API REST do naszej opcji, tak jak poni\u017cej:<\/p>\n<pre><code>\nedit: withSelect( (select) =&gt; {\n    const option = select( 'wcltd\/wholesome-plugin\/data' ).getOption( 'wcltd_example_option' );\n    return {\n        option,\n    };\n} )( Edit ),\n<\/code><\/pre>\n<p>Teraz mo\u017cemy uzyska\u0107 dost\u0119p <code>option<\/code>do naszych rekwizyt\u00f3w w <code>edit.js<\/code>, na przyk\u0142ad:<\/p>\n<pre><code>export default function Edit( { className, option }) {\n    return (&lt;p className={ className }&gt;\n            { option }\n        &lt;\/p&gt;\n    );\n}\n<\/code><\/pre>\n<p>Na koniec przejrzyjmy nasz blok w edytorze i zobaczmy, co otrzymamy:<\/p>\n<p><a href=\"https:\/\/cdn.hashnode.com\/res\/hashnode\/image\/upload\/v1639990090843\/2uT6sdoTo.png\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Dane wyj\u015bciowe w edytorze blok\u00f3w.<\/a> Dane wyj\u015bciowe w edytorze blok\u00f3w.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>W moim poprzednim artykule m\u00f3wi\u0142em o tym, jak zap\u0119tli\u0107 posty i niestandardowe typy post\u00f3w w Gutenbergu. W tym po\u015bcie m\u00f3wi\u0119 o otrzymywaniu i u\u017cywaniu niestandardowych danych w Gutenberg f&#8230;<\/p>\n","protected":false},"author":1,"featured_media":220671,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,919,897,866],"tags":[1169],"class_list":["post-228286","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-kod","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228286","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=228286"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228286\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/220671"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=228286"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=228286"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=228286"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}