{"id":233746,"date":"2023-02-20T10:28:00","date_gmt":"2023-02-20T07:28:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233746"},"modified":"2023-02-26T12:42:29","modified_gmt":"2023-02-26T09:42:29","slug":"dodaj-ustawienia-niestandardowe-do-istniejacych-blokow-wordpress-gutenberg","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/dodaj-ustawienia-niestandardowe-do-istniejacych-blokow-wordpress-gutenberg\/","title":{"rendered":"Dodaj ustawienia niestandardowe do istniej\u0105cych blok\u00f3w WordPress Gutenberg"},"content":{"rendered":"\n<p>Czy kiedykolwiek znalaz\u0142e\u015b si\u0119 w sytuacji, w kt\u00f3rej chcesz doda\u0107 w\u0142asne ustawienia do blok\u00f3w Gutenberga w WordPressie? W tym po\u015bcie om\u00f3wimy szczeg\u00f3\u0142owo, jak to zrobi\u0107. Znajdziesz dwa przyk\u0142adowe kody rzeczywistych przypadk\u00f3w dodawania niestandardowych ustawie\u0144 do blok\u00f3w WordPressa.<\/p>\n<p>Pami\u0119taj, \u017ce poniewa\u017c bloki Gutenberga s\u0105 JavaScriptem, ich modyfikacja wymaga napisania kodu w JavaScript. Tak jak kod PHP WordPressa ma haki i filtry, kt\u00f3re pozwalaj\u0105 tw\u00f3rcom motyw\u00f3w lub wtyczek modyfikowa\u0107 jego kod, tak samo istniej\u0105 filtry w kodzie JavaScript WordPressa. Podobnie jak w przypadku PHP <code>[add_filter](https:\/\/developer.wordpress.org\/reference\/functions\/add_filter\/)()<\/code>mamy funkcj\u0119 Javascript <code>[addFilter](https:\/\/developer.wordpress.org\/block-editor\/packages\/packages-hooks\/#api-usage)()<\/code>.<\/p>\n<p>Napisz\u0119 kod w sk\u0142adni Javascript ES6, kt\u00f3ra wymaga kompilatora do jego przekszta\u0142cenia. Mo\u017cesz pisa\u0107 w sk\u0142adni ES5, ale polecam ES6\/ESNext. Mam <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/kompletny-przewodnik-po-tworzeniu-srodowiska-programistycznego-dla-gutenberg\/\" title=\"post, kt\u00f3ry wyja\u015bnia, jak skonfigurowa\u0107 transformator dla ES6\/ESNext\">post, kt\u00f3ry wyja\u015bnia, jak skonfigurowa\u0107 transformator dla ES6\/ESNext<\/a>. Zak\u0142adam r\u00f3wnie\u017c, \u017ce masz pewn\u0105 znajomo\u015b\u0107 React\/JSX, by\u0107 mo\u017ce pewne do\u015bwiadczenie w <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/jak-stworzyc-niestandardowy-blok-wordpress-gutenberg-seria-samouczkow\/\" title=\"tworzeniu w\u0142asnych niestandardowych blok\u00f3w Gutenberga\">tworzeniu w\u0142asnych niestandardowych blok\u00f3w Gutenberga<\/a>.<\/p>\n<h2>Co mo\u017cesz filtrowa\u0107 na blokach Gutenberga<\/h2>\n<p>Nie ma ca\u0142ej dokumentacji w dost\u0119pnych hookach i filtrach Gutenberga. Ale w celu dodania niestandardowych ustawie\u0144 i zastosowania ich w istniej\u0105cych blokach; to w\u0142a\u015bnie znalaz\u0142em do tej pory. Skupi\u0142em si\u0119 na dodawaniu prostych ustawie\u0144 \u2013 a nie na operacjach, kt\u00f3re wymagaj\u0105 drastycznych zmian komponent\u00f3w lub z\u0142o\u017conego zachowania.<\/p>\n<p>Istniej\u0105 trzy kroki, aby doda\u0107 niestandardowe ustawienia do istniej\u0105cych blok\u00f3w:<\/p>\n<ul>\n<li>Dodajemy filtr do <code>[registerBlockType](https:\/\/developer.wordpress.org\/block-editor\/developers\/block-api\/block-registration\/#registerblocktype)<\/code>tablicy ustawie\u0144 istniej\u0105cego bloku. To pozwala nam dodawa\u0107 nowe atrybuty do <code>attributes<\/code>tablicy, co pozwala nam na zapisanie dodatkowych informacji w bloku. Musimy gdzie\u015b zapisa\u0107 nasze niestandardowe ustawienie.<\/li>\n<li>Zaczep si\u0119 do <code>edit<\/code>komponentu bloku (komponentu odpowiedzialnego za renderowanie bloku w edytorze). W tym haczyku mo\u017cemy podpi\u0105\u0107 si\u0119 pod Inspektora (pasek boczny) i doda\u0107 w\u0142asne komponenty. Mo\u017cemy albo doda\u0107 now\u0105 sekcj\u0119\/panel, albo podpi\u0105\u0107 si\u0119 pod sekcj\u0119 \u201eZaawansowane&quot;, kt\u00f3ra jest zawsze obecna we wszystkich blokach. Nast\u0119pnie od nas zale\u017cy wyrenderowanie danych wej\u015bciowych ustawie\u0144, takich jak wprowadzanie tekstu, pola wyboru lub cokolwiek innego.<\/li>\n<li><code>save<\/code>Filtruj rekwizyty bloku. Mo\u017cemy dostosowa\u0107 props do zapisu, kt\u00f3ry odpowiada zar\u00f3wno za zapisanie bloku, jak i renderowanie go w interfejsie u\u017cytkownika (poza edytorem). W naszym przypadku chcemy doda\u0107 klas\u0119 lub styl inline.<\/li>\n<\/ul>\n<p>Mo\u017cemy celowa\u0107 w okre\u015blone bloki lub wszystkie. Zawsze mamy dost\u0119p do tego, w jakim bloku si\u0119 znajdujemy.<\/p>\n<p>Innymi s\u0142owy: dodajemy kilka niestandardowych ustawie\u0144 w Inspektorze i zapisujemy je w niestandardowych atrybutach, kt\u00f3re dodali\u015bmy do bloku. Mo\u017cemy wtedy wp\u0142yn\u0105\u0107 na nazw\u0119 klasy bloku lub styl inline (w niekt\u00f3rych przypadkach), w zale\u017cno\u015bci od zapisanych atrybut\u00f3w. Dzi\u0119ki niestandardowym nazwom klas mo\u017cemy \u0142atwo doda\u0107 niestandardowe CSS, kt\u00f3ry wizualnie nadaje efekt naszym ustawieniom.<\/p>\n<h2>Czego nie mo\u017cemy zrobi\u0107 (na razie?)<\/h2>\n<p>Niestety s\u0105 pewne rzeczy, do kt\u00f3rych nie mo\u017cemy uzyska\u0107 dost\u0119pu za pomoc\u0105 filtr\u00f3w w istniej\u0105cych blokach. Je\u015bli chodzi o dodawanie prostych niestandardowych ustawie\u0144 do blok\u00f3w, s\u0105 to typowe rzeczy, na kt\u00f3re nie mamy wp\u0142ywu.<\/p>\n<h3>Brak dost\u0119pu do stylu wbudowanego bloku w edytorze<\/h3>\n<p>W niekt\u00f3rych przypadkach ustawienia, kt\u00f3re wp\u0142ywaj\u0105 na projekt bloku, musimy doda\u0107 styl wbudowany w w\u0119\u017ale zawijania bloku. Tylko nazwa klasy nie wystarczy. Na przyk\u0142ad, je\u015bli dodasz niestandardowe ustawienie koloru, a u\u017cytkownik wybierze niestandardowy kolor (z pr\u00f3bnika kolor\u00f3w), nie mo\u017cesz rozwi\u0105za\u0107 tego problemu, dodaj\u0105c klas\u0119 \u2013 potrzebujesz stylu wbudowanego.<\/p>\n<p>Niestety wygl\u0105da na to, \u017ce domy\u015blne bloki WordPressa obs\u0142uguj\u0105 styl inline w edytorze ca\u0142kowicie niezale\u017cnie, bez opcji filtrowania lub \u201epodpinania si\u0119&#8221;. W ostatnim przyk\u0142adzie poni\u017cej poka\u017c\u0119 spos\u00f3b na obej\u015bcie tego problemu, ale nie we wszystkich przypadkach jest to idealne.<\/p>\n<p>Mo\u017cesz zapyta\u0107, dlaczego blok wygl\u0105da inaczej w edytorze ni\u017c w interfejsie? Celem Gutenberga jest zaimplementowanie wizualnego sposobu edycji tre\u015bci, w kt\u00f3rej to, co widzimy, jest faktycznie tym, co otrzymujemy. Chcemy osi\u0105gn\u0105\u0107 ten sam wygl\u0105d wizualny zar\u00f3wno w edytorze, jak i frontendzie.<\/p>\n<h3>Niekt\u00f3re bloki nie zawieraj\u0105 nazwy klasy w edytorze<\/h3>\n<p>Jak wspomniano powy\u017cej, mo\u017cemy filtrowa\u0107 nazw\u0119 klasy opakowania bloku, poniewa\u017c jest to w\u0142a\u015bciwo\u015b\u0107 przekazywana do wszystkich blok\u00f3w Gutenberga. Niestety, istniej\u0105 pewne bloki, kt\u00f3re w og\u00f3le nie stosuj\u0105 klasy bloku w programie <code>edit<\/code>. Jednym z przyk\u0142ad\u00f3w jest blok Cover. Du\u017co si\u0119 bawi\u0142em, u\u017cywaj\u0105c blok\u00f3w ok\u0142adki jako \u201esekcji&#8221; na pierwszych stronach i ci\u0105gle napotykam problemy, poniewa\u017c blok ok\u0142adki buduje w\u0142asn\u0105 klas\u0119 wewn\u0105trz <code>edit<\/code>. Ca\u0142kowicie pomija klas\u0119 \u201eglobal&#8221; bloku (do kt\u00f3rej mamy dost\u0119p poprzez filtry).<\/p>\n<p>Ale przynajmniej mo\u017cemy by\u0107 pewni, \u017ce filtrowane nazwy klas s\u0105 zawsze stosowane w <code>save<\/code>(frontendzie). Dzieje si\u0119 to automatycznie poza okre\u015blonym kodem ka\u017cdego bloku.<\/p>\n<p>Je\u015bli si\u0119 myl\u0119 co do kt\u00f3regokolwiek z powy\u017cszych, PROSZ\u0118 daj mi zna\u0107 w komentarzach poni\u017cej! Nieustannie ucz\u0119 si\u0119 Gutenberga, a jednocze\u015bnie Gutenberg r\u00f3wnie\u017c ewoluuje. Mam nadziej\u0119, \u017ce w kt\u00f3rym\u015b momencie powy\u017csze b\u0119dzie mo\u017cliwe lub \u017ce jest mo\u017cliwe, ale brakuje mi tylko kilku istotnych informacji!<\/p>\n<p>Pomijaj\u0105c to, zacznijmy szuka\u0107 kodu.<\/p>\n<h2>Przyk\u0142ad 1: Dodaj pole prze\u0142\u0105czania, aby ukry\u0107 blok ok\u0142adki na urz\u0105dzeniu mobilnym<\/h2>\n<p>Za\u0142\u00f3\u017cmy, \u017ce opracowujemy motyw, w kt\u00f3rym bloki ok\u0142adki b\u0119d\u0105 u\u017cywane jako \u201esekcje&#8221; na pierwszej stronie. I chcemy zapewni\u0107 u\u017cytkownikowi mo\u017cliwo\u015b\u0107 ukrycia okre\u015blonej sekcji przed telefonem kom\u00f3rkowym. Aby rozwi\u0105za\u0107 ten problem, mo\u017cemy doda\u0107 pole prze\u0142\u0105czania w sekcji \u201eZaawansowane&#8221; w Inspektorze bloku ok\u0142adki. Je\u015bli pole jest w\u0142\u0105czone, blok Cover otrzyma dodatkow\u0105 niestandardow\u0105 klas\u0119, do kt\u00f3rej mo\u017cemy kierowa\u0107 zapytaniami CSS i mediami.<\/p>\n<p>Przy okazji: jest to przypadek, w kt\u00f3rym kwestia Cover block niestosuj\u0105ca naszych niestandardowych nazw klas w edytorze faktycznie jest zalet\u0105! Wyobra\u017a sobie, \u017ce tak; wtedy u\u017cytkownik nie b\u0119dzie m\u00f3g\u0142 edytowa\u0107 bloku w edytorze, je\u015bli ma ma\u0142y ekran!<\/p>\n<p>Jak wspomniano wcze\u015bniej, musimy kodowa\u0107 trzy kroki. Musimy r\u00f3wnie\u017c doda\u0107 troch\u0119 PHP, aby umie\u015bci\u0107 nasz plik JavaScript w kolejce do edytora. Zr\u00f3bmy to najpierw.<\/p>\n<h3>Dodanie naszego skryptu do edytora<\/h3>\n<p>Pod\u0142\u0105czamy funkcj\u0119 do akcji <code>[enqueue_block_editor_assets](https:\/\/developer.wordpress.org\/reference\/hooks\/enqueue_block_editor_assets\/)<\/code>. Wewn\u0105trz naszej funkcji umieszczamy w kolejce skrypt, tak jak zwykle robimy to w <code>wp_enqueue_scripts<\/code>hooku.<\/p>\n<pre><code>add_action('enqueue_block_editor_assets', function() {\n    wp_enqueue_script('awp-gutenberg-filters', get_template_directory_uri(). '\/assets\/js\/gutenberg-filters.js', ['wp-edit-post']);\n});<\/code><\/pre>\n<p>Pami\u0119taj, aby dostosowa\u0107 \u015bcie\u017ck\u0119 do miejsca, w kt\u00f3rym znajduje si\u0119 Tw\u00f3j skrypt! Uwaga: Je\u015bli piszesz w ES6 z webpackiem kompiluj\u0105cym Tw\u00f3j Javascript, pami\u0119taj, aby ustawi\u0107 \u015bcie\u017ck\u0119 do kompilacji skryptu, a nie \u017ar\u00f3d\u0142o.<\/p>\n<p>Lubi\u0119 dodawa\u0107 \u201e <code>wp-edit-post<\/code>&#8221; jako zale\u017cno\u015b\u0107 do skryptu, aby upewni\u0107 si\u0119, \u017ce \u0142aduje si\u0119 wystarczaj\u0105co p\u00f3\u017ano.<\/p>\n<p>To wszystko, co musimy zrobi\u0107 w PHP. Reszta jest napisana w naszym pliku JavaScript.<\/p>\n<h3>Dodaj niestandardowy atrybut<\/h3>\n<p>Pierwszym filtrem, kt\u00f3rego u\u017cyjemy, jest obiekt ustawie\u0144 <code>blocks.registerBlockType<\/code>filtr\u00f3w .<code>registerBlockType<\/code><\/p>\n<p>Ale najpierw troch\u0119 o dodawaniu filtr\u00f3w w JavaScript. Poniewa\u017c nie znalaz\u0142em \u017cadnej dobrej dokumentacji na ten temat, wyja\u015bni\u0119 to nieco tutaj. Funkcja <code>addFilter<\/code>znajduje si\u0119 w <code>wp.hooks<\/code>przestrzeni nazw i akceptuje cztery argumenty.<\/p>\n<p><code>addFilter('hookName', 'namespace', 'functionName', 'priority');<\/code><\/p>\n<p>Pierwszy parametr, 'hookName&#8217;, to nazwa filtra, do kt\u00f3rego chcemy si\u0119 pod\u0142\u0105czy\u0107. Jest to odpowiednik pierwszego parametru u\u017cywanego w PHP <code>add_filter()<\/code>. Drugi parametr, \u201enamespace&#8221;, to niestandardowa nazwa w przestrzeni nazw dla Twojego kodu. Ma to na celu unikni\u0119cie kolizji nazw. Mo\u017cesz tutaj ustawi\u0107 wszystko, co chcesz, po prostu nie u\u017cywaj przestrzeni nazw WordPress (&#8217;wp&#8217;). U\u017cyj kr\u00f3tkiej formy swojego imienia lub nazwy projektu. Trzeci parametr, 'functionName&#8217;, to przechwycona funkcja \u2013 kt\u00f3ra jest taka sama, jak <code>add_filter()<\/code>drugi argument PHP. I wreszcie czwarty parametr, \u201epriorytet&#8221;, jest opcjonalny. Znowu jest to to samo, co <code>add_filter()<\/code>trzeci argument PHP.<\/p>\n<p>Proces filtr\u00f3w w JavaScript jest taki sam jak w PHP. Definiujemy funkcj\u0119, kt\u00f3ra musi zwr\u00f3ci\u0107 przefiltrowan\u0105 zmienn\u0105. Czasami zmienna jest napisem, obiektem lub komponentem. Wewn\u0105trz funkcji modyfikujemy zmienn\u0105 wed\u0142ug w\u0142asnego uznania.<\/p>\n<p>W naszym przypadku chcemy doda\u0107 nowy atrybut do <code>attribute<\/code>obiektu bloku. Wywo\u0142amy nowy atrybut <code>hideOnMobile<\/code>i ustawimy jego typ na <code>boolean<\/code>. Odbywa si\u0119 to tak:<\/p>\n<pre><code>function addCoverAttribute(settings, name) {\n    if (typeof settings.attributes !== 'undefined') {\n        if (name == 'core\/cover') {\n            settings.attributes = Object.assign(settings.attributes, {\n                hideOnMobile: {\n                    type: 'boolean',\n                }\n            });\n        }\n    }\n    return settings;\n}\n\u00a0\nwp.hooks.addFilter(\n    'blocks.registerBlockType',\n    'awp\/cover-custom-attribute',\n    addCoverAttribute\n);<\/code><\/pre>\n<p>W wierszu <code>#3<\/code>upewniamy si\u0119, \u017ce kierujemy tylko bloki typu \u201e <code>core\/cover<\/code>&#8222;. Drugim argumentem do <code>blocks.registerBlockType<\/code>filtrowania dogodnie jest nazwa bloku. Nast\u0119pnie dodajemy nowy element obiektu do <code>settings.attributes<\/code>obiektu. Na koniec upewniamy si\u0119, \u017ce zwracamy przefiltrowan\u0105 zmienn\u0105 <code>settings<\/code>.<\/p>\n<p>W tym momencie wizualnie nic si\u0119 nie zmienia w Gutenbergu. Ale wszystkie bloki Cover maj\u0105 teraz dodatkowy atrybut, kt\u00f3rego mo\u017cemy u\u017cy\u0107 do przechowywania naszych ustawie\u0144.<\/p>\n<h3>Dodaj ustawienie do Inspektora (panel Zaawansowane)<\/h3>\n<p>Drugi filtr jest wywo\u0142ywany <code>editor.BlockEdit<\/code>i filtruje sk\u0142adnik bloku <code>edit<\/code>. Ten filtr otrzymuje sk\u0142adnik oryginalnego bloku <code>BlockEdit<\/code>i zwraca nowy opakowany sk\u0142adnik. Musimy u\u017cy\u0107 <code>wp.compose.createHigherOrderComponent<\/code>, aby zwr\u00f3ci\u0107 opakowany komponent.<\/p>\n<p>Wewn\u0105trz naszego komponentu upewniamy si\u0119, \u017ce renderujemy opakowany komponent <code>BlockEdit<\/code>niezale\u017cnie od tego. Ale je\u015bli blok jest typu Cover, r\u00f3wnie\u017c podpinamy si\u0119 pod komponent <code>InspectorAdvancedControls<\/code>(kt\u00f3ry jest panelem \u201eZaawansowane&#8221; w Inspektorze) i dodajemy <code>ToggleControl<\/code>. Piszemy, <code>ToggleControl<\/code>aby pokaza\u0107 warto\u015b\u0107 i zaktualizowa\u0107 atrybut niestandardowy, kt\u00f3ry dodali\u015bmy wcze\u015bniej, <code>hideOnMobile<\/code>.<\/p>\n<pre><code>const coverAdvancedControls = wp.compose.createHigherOrderComponent((BlockEdit) =&gt; {\n    return (props) =&gt; {\n        const { Fragment } = wp.element;\n        const { ToggleControl } = wp.components;\n        const { InspectorAdvancedControls } = wp.blockEditor;\n        const { attributes, setAttributes, isSelected } = props;\n        return (&lt;Fragment&gt;\n                &lt;BlockEdit {...props} \/&gt;\n                {isSelected &amp;&amp; (props.name == 'core\/cover') &amp;&amp; \n                    &lt;InspectorAdvancedControls&gt;\n                        &lt;ToggleControl\n                            label={wp.i18n.__('Hide on mobile', 'awp')}\n                            checked={!!attributes.hideOnMobile}\n                            onChange={(newval) =&gt; setAttributes({ hideOnMobile: !attributes.hideOnMobile })}\n                        \/&gt;\n                    &lt;\/InspectorAdvancedControls&gt;\n                }\n            &lt;\/Fragment&gt;\n        );\n    };\n}, 'coverAdvancedControls');\n\u00a0\nwp.hooks.addFilter(\n    'editor.BlockEdit',\n    'awp\/cover-advanced-control',\n    coverAdvancedControls\n);<\/code><\/pre>\n<p>Nie zapomnij zawsze zwr\u00f3ci\u0107 orygina\u0142u <code>BlockEdit<\/code>, co robimy w kolejce <code>#9<\/code>. W linii #10 sprawdzamy, czy typem bloku jest Cover i renderujemy <code>InspectorAdvancedControls<\/code>komponent. Wewn\u0105trz dodajemy a <code>ToggleControl<\/code>, kt\u00f3ry jest kontrolk\u0105 wej\u015bciow\u0105, kt\u00f3ra wy\u015bwietla si\u0119 jako prze\u0142\u0105czanie mi\u0119dzy prawd\u0105 a fa\u0142szem. Ustawiamy etykiet\u0119 i \u0142\u0105czymy jej warto\u015b\u0107 z <code>hideOnMobile<\/code>atrybutem. Je\u015bli wcze\u015bniej doda\u0142e\u015b ustawienia do Inspektora, powinno to by\u0107 dla Ciebie ca\u0142kiem proste.<\/p>\n<p>W powy\u017cszym kodzie powinni\u015bmy teraz umie\u015bci\u0107 to w panelu \u201eZaawansowane&#8221; w blokach Inspektora ok\u0142adki:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-152421-61e4d70271f5a.png\" 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-152421-61e4d70271f5a.png\" alt=\"Dodaj ustawienia niestandardowe do istniej\u0105cych blok\u00f3w WordPress Gutenberg\"><\/a><\/p>\n<p>Dane wej\u015bciowe zaktualizuj\u0105 teraz nasz niestandardowy atrybut <code>hideOnMobile<\/code>. Ostatnim krokiem jest zrobienie czego\u015b w zale\u017cno\u015bci od warto\u015bci tego atrybutu. W tej chwili atrybut jest zapisany, ale w rzeczywisto\u015bci na nic nie wp\u0142ywa.<\/p>\n<h3>Dodaj niestandardow\u0105 klas\u0119<\/h3>\n<p>Ostatnim krokiem jest dodanie w\u0142asnej klasy do klasy bloku. Robimy to z filtrem <code>blocks.getSaveContent.extraProps<\/code>. Ten filtr wp\u0142ywa na w\u0142a\u015bciwo\u015bci <code>save<\/code>komponentu bloku. Jednym z nich jest prop <code>className<\/code>, kt\u00f3ry zawsze b\u0119dzie stosowany do frontendu. Po prostu do\u0142\u0105czamy po niej nasz\u0105 niestandardow\u0105 klas\u0119, je\u015bli atrybut by\u0142 <code>true<\/code>, a nast\u0119pnie zwracamy j\u0105. Postanowi\u0142em doda\u0107 klas\u0119 \u201e <code>hide-on-mobile<\/code>&#8222;, ale mo\u017cesz j\u0105 nazwa\u0107, jak chcesz.<\/p>\n<pre><code>function coverApplyExtraClass(extraProps, blockType, attributes) {\n    const { hideOnMobile } = attributes;\n\u00a0\n    if (typeof hideOnMobile !== 'undefined' &amp;&amp; hideOnMobile) {\n        extraProps.className = extraProps.className + ' hide-on-mobile';\n    }\n    return extraProps;\n}\n\u00a0\nwp.hooks.addFilter(\n    'blocks.getSaveContent.extraProps',\n    'awp\/cover-apply-class',\n    coverApplyExtraClass\n);<\/code><\/pre>\n<p>Ten kod jest do\u015b\u0107 oczywisty. W linii <code>#4<\/code>sprawdzamy czy atrybut <code>hideOnMobile<\/code>istnieje i czy jest <code>true<\/code>. Je\u015bli tak, do\u0142\u0105czamy do ci\u0105gu niestandardow\u0105 klas\u0119 <code>className<\/code>.<\/p>\n<p>Dzi\u0119ki wszystkim powy\u017cszym trzem filtrom powinni\u015bmy teraz uzyska\u0107 niestandardow\u0105 klas\u0119 \u201eukryj na urz\u0105dzeniu mobilnym&#8221; zastosowan\u0105 do naszego bloku Cover za ka\u017cdym razem, gdy ustawienie jest w\u0142\u0105czone.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-152421-61e4d70343817.png\" 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-152421-61e4d70343817.png\" alt=\"Dodaj ustawienia niestandardowe do istniej\u0105cych blok\u00f3w WordPress Gutenberg\"><\/a><\/p>\n<p>Pozostaje tylko doda\u0107 troch\u0119 CSS do arkusza styl\u00f3w frontendu twojego motywu. Co\u015b takiego;<\/p>\n<pre><code>.wp-block-cover.hide-on-mobile { display: none; }\n@media (min-width: 480px) {\n    .wp-block-cover.hide-on-mobile { display: block; }\n}<\/code><\/pre>\n<h2>Przyk\u0142ad 2: Dodaj panel Inspektora z niestandardowym ustawieniem koloru t\u0142a dla bloku dystansowego<\/h2>\n<p>W drugim przypadku chcemy doda\u0107 niestandardowe ustawienia kolor\u00f3w do bloku Spacer. Domy\u015blnie blok dystansowy nie ma innych ustawie\u0144 poza jego wysoko\u015bci\u0105. Za\u0142\u00f3\u017cmy, \u017ce chcemy doda\u0107 kolor t\u0142a, kt\u00f3ry pokoloruje pe\u0142n\u0105 wysoko\u015b\u0107 bloku Spacer. Dzi\u0119ki temu u\u017cytkownik mo\u017ce dodawa\u0107 puste, kolorowe \u201epaski&#8221; w tre\u015bci. W tym przypadku chcemy doda\u0107 ustawienia kolor\u00f3w do osobnego panelu w Inspektorze, zgodnie ze zwyk\u0142ym oczekiwanym zachowaniem ustawie\u0144 kolor\u00f3w.<\/p>\n<p>Uwaga: Obs\u0142uga kolor\u00f3w jest nieco bardziej skomplikowana, poniewa\u017c musimy u\u017cy\u0107 (innego) komponentu wy\u017cszego rz\u0119du <code>withColors<\/code>. Poniewa\u017c ju\u017c musimy zaimplementowa\u0107 komponent wy\u017cszego rz\u0119du w <code>editor.BlockEdit<\/code>potrzebujemy <code>compose<\/code>wielu komponent\u00f3w. Dodatkowo musimy doda\u0107 dwa atrybuty dla ka\u017cdego ustawienia koloru. Jeden b\u0119dzie zawiera\u0142 slug palety kolor\u00f3w, a drugi b\u0119dzie zawiera\u0142 szesnastkowy kod koloru \u2013 tylko wtedy, gdy u\u017cytkownik wybra\u0142 niestandardowy kolor (u\u017cy\u0142 selektora kolor\u00f3w). To typowe zachowanie podczas pracy z programem <code>withColors<\/code>. Mam &lt;a href=&quot;https:\/\/wordpress.mediadoma.com\/pl\/jak-dodac-ustawienia-kolorow-do-niestandardowego-bloku-gutenberga\/&quot; title=&quot;post wyja\u015bniaj\u0105cy dodawanie ustawie\u0144 kolor\u00f3w i <code>withColors<\/code>szczeg\u00f3\u0142owo&#8221; &gt;post wyja\u015bniaj\u0105cy dodawanie ustawie\u0144 kolor\u00f3w i <code>withColors<\/code>szczeg\u00f3\u0142owo<\/a>, je\u015bli si\u0119 pomylisz.<\/p>\n<p>Po drugie, w tym przypadku napotkamy problem wyja\u015bniony powy\u017cej; gdzie nie mo\u017cemy doda\u0107 odpowiedniego stylu wbudowanego do edytora. Rozwi\u0105zaniem, na kt\u00f3re zdecydowa\u0142em si\u0119 w tym przypadku, jest zawini\u0119cie bloku Spacer wewn\u0105trz a <code>div<\/code>w edytorze i zastosowanie odpowiednich klas i stylu inline do wrapping <code>div<\/code>. Dzi\u0119ki temu wybrany kolor jest widoczny w edytorze, gdy blok jest odznaczony. Jednak po wybraniu bloku WordPress dodaje do niego w\u0142asne niestandardowe jasnoszare t\u0142o, obejmuj\u0105ce nasz niestandardowy kolor t\u0142a. Jeden CSS do edytora naprawi to. Wi\u0119cej wyja\u015bni\u0119 na ko\u0144cu.<\/p>\n<p>Kroki s\u0105 takie same jak w powy\u017cszym przyk\u0142adzie. Najpierw umieszczamy nasz skrypt w kolejce do edytora w PHP. Nast\u0119pnie w JavaScript filtrujemy <code>attributes<\/code>obiekt, <code>edit<\/code>sk\u0142adnik Spacera i na ko\u0144cu sk\u0142adnik Spacera <code>save<\/code>.<\/p>\n<h3>Dodanie naszego skryptu do edytora<\/h3>\n<p>Pod\u0142\u0105czamy funkcj\u0119 do akcji <code>[enqueue_block_editor_assets](https:\/\/developer.wordpress.org\/reference\/hooks\/enqueue_block_editor_assets\/)<\/code>. Wewn\u0105trz naszej funkcji umieszczamy w kolejce skrypt, tak jak zwykle robimy to w <code>wp_enqueue_scripts<\/code>hooku.<\/p>\n<pre><code>add_action('enqueue_block_editor_assets', function() {\n    wp_enqueue_script('awp-gutenberg-filters', get_template_directory_uri(). '\/assets\/js\/gutenberg-filters.js', ['wp-edit-post']);\n});<\/code><\/pre>\n<p>Pami\u0119taj, aby dostosowa\u0107 \u015bcie\u017ck\u0119 do swojego skryptu. Lubi\u0119 dodawa\u0107 \u201e <code>wp-edit-post<\/code>&#8221; jako zale\u017cno\u015b\u0107 do skryptu, aby upewni\u0107 si\u0119, \u017ce \u0142aduje si\u0119 wystarczaj\u0105co p\u00f3\u017ano.<\/p>\n<p>To wszystko, co musimy zrobi\u0107 w PHP. Reszta jest napisana w naszym pliku JavaScript.<\/p>\n<h3>Dodaj niestandardowe atrybuty<\/h3>\n<p>Podobnie jak w powy\u017cszym przyk\u0142adzie dodajemy filtr <code>blocks.registerBlockType<\/code>, aby doda\u0107 dodatkowe elementy obiektu do obiektu bloku <code>attributes<\/code>.<\/p>\n<p>Podczas pracy z <code>withColors<\/code>ka\u017cdym kolorem musimy doda\u0107 dwa atrybuty. Nazwa naszego atrybutu koloru t\u0142a to <code>backgroundColor<\/code>, co oznacza, \u017ce \u200b\u200bdrugi atrybut musi by\u0107 nazwany <code>customBackgroundColor<\/code>. To wszystko zosta\u0142o wyja\u015bnione w <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/jak-dodac-ustawienia-kolorow-do-niestandardowego-bloku-gutenberga\/\" title=\"moim po\u015bcie dotycz\u0105cym obs\u0142ugi ustawie\u0144 kolor\u00f3w w Gutenbergu\">moim po\u015bcie dotycz\u0105cym obs\u0142ugi ustawie\u0144 kolor\u00f3w w Gutenbergu<\/a>. Oba powinny by\u0107 typu string i stosowane tylko do blok\u00f3w typu Spacer.<\/p>\n<pre><code>function addSpacerAttributes(settings, name) {\n    if (typeof settings.attributes !== 'undefined') {\n        if (name == 'core\/spacer') {\n            settings.attributes = Object.assign(settings.attributes, {\n                backgroundColor: {\n                    type: 'string',\n                },\n                customBackgroundColor: {\n                    type: 'string'\n                }\n            });\n        }\n    }\n    return settings;\n}\n\u00a0\nwp.hooks.addFilter(\n    'blocks.registerBlockType',\n    'awp\/spacer-background-attribute',\n    addSpacerAttributes\n);<\/code><\/pre>\n<h3>Dodaj panel ColorSettings do Inspektora<\/h3>\n<p>Drugim krokiem jest dodanie panelu ustawie\u0144 kolor\u00f3w do Inspektora bloku Spacer poprzez filtrowanie <code>editor.BlockEdit<\/code>.<\/p>\n<pre><code>const spacerInspectorControls = wp.compose.compose(\n    wp.blockEditor.withColors({backgroundColor: 'background-color'}),\n\u00a0\n    wp.compose.createHigherOrderComponent((BlockEdit) =&gt; {\n        return (props) =&gt; {\n\u00a0\n            if (props.name !== 'core\/spacer') {\n                return(&lt;BlockEdit {...props} \/&gt;);\n            }\n\u00a0\n            const { Fragment } = wp.element;\n            const { InspectorControls, PanelColorSettings } = wp.blockEditor;\n            const { attributes, setAttributes, isSelected } = props;\n            const { backgroundColor, setBackgroundColor } = props;\n\u00a0\n            let newClassName = (attributes.className != undefined)? attributes.className: '';\n            let newStyles = {...props.style};\n            if (backgroundColor != undefined) {\n                if (backgroundColor.class == undefined) {\n                    newStyles.backgroundColor = backgroundColor.color;\n                } else {\n                    newClassName += ' ' + backgroundColor.class;\n                }\n            }\n            const newProps = {\n                ...props,\n                attributes: {\n                    ...attributes,\n                    className: newClassName\n                },\n                style: newStyles\n            }\n\u00a0\n            return (&lt;Fragment&gt;\n                    &lt;div style={newStyles} className={newClassName}&gt;\n                        &lt;BlockEdit {...newProps} \/&gt;\n                        {isSelected &amp;&amp; (props.name == 'core\/spacer') &amp;&amp; \n                            &lt;InspectorControls&gt;\n                                &lt;PanelColorSettings \n                                    title={wp.i18n.__('Color Settings', 'awp')}\n                                    colorSettings={[\n                                        {\n                                            value: backgroundColor.color,\n                                            onChange: setBackgroundColor,\n                                            label: wp.i18n.__('Background color', 'awp')\n                                        }\n                                    ]}\n                                \/&gt;\n                            &lt;\/InspectorControls&gt;\n                        }\n                    &lt;\/div&gt;\n                &lt;\/Fragment&gt;\n            );\n        };\n}, 'spacerInspectorControls'));\n\u00a0\nwp.hooks.addFilter(\n    'editor.BlockEdit',\n    'awp\/spacer-inspector-control',\n    spacerInspectorControls\n);<\/code><\/pre>\n<p>Musimy u\u017cy\u0107 <code>compose<\/code>do po\u0142\u0105czenia sk\u0142adnika wy\u017cszego rz\u0119du zwr\u00f3conego przez ten filtr i <code>withColors<\/code>. Innymi s\u0142owy, po prostu zawijamy zwr\u00f3cony komponent w <code>withColors<\/code>. Jako parametr <code>withColors<\/code>podajemy nasz atrybut <code>backgroundColor<\/code>.<\/p>\n<p>Wewn\u0105trz owini\u0119tego komponentu upewniamy si\u0119, \u017ce zawsze wracamy <code>BlockEdit<\/code>(linia <code>#9<\/code>i <code>#39<\/code>klocki Spacer). W przypadku bloku typu Spacer zaczepiamy si\u0119 r\u00f3wnie\u017c, <code>InspectorControls<\/code>aby doda\u0107 <code>PanelColorSettings<\/code>wybrany przez nas kolor. Jest to standardowa procedura dodawania ustawie\u0144 kolor\u00f3w.<\/p>\n<p>W linii <code>#17 - 34<\/code>r\u0119cznie generujemy niezb\u0119dn\u0105 klas\u0119 i\/lub styl inline. Nast\u0119pnie w linii <code>#38<\/code>dodajemy otaczaj\u0105cy div <code>BlockEdit<\/code>z tymi klasami i stylami wbudowanymi.<\/p>\n<p>Rezultatem jest nowy panel ustawie\u0144 kolor\u00f3w w blokach Inspector for Spacer, w pe\u0142ni funkcjonalny.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-152421-61e4d7041a66b.png\" 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-152421-61e4d7041a66b.png\" alt=\"Dodaj ustawienia niestandardowe do istniej\u0105cych blok\u00f3w WordPress Gutenberg\"><\/a><\/p>\n<p>Wyb\u00f3r koloru palety lub koloru niestandardowego b\u0119dzie rzeczywi\u015bcie mia\u0142 wp\u0142yw na zawijania div wewn\u0105trz edytora. Ale mo\u017cesz to zobaczy\u0107 tylko wtedy, gdy odznaczysz blok Spacer!<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-152421-61e4d7052e0c9.gif\" 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-152421-61e4d7052e0c9.gif\" alt=\"Dodaj ustawienia niestandardowe do istniej\u0105cych blok\u00f3w WordPress Gutenberg\"><\/a><\/p>\n<p>Dzieje si\u0119 tak, poniewa\u017c WordPress stosuje w\u0142asny styl podczas wybierania bloku odst\u0119pnika. Naprawimy to na ko\u0144cu, najpierw musimy tylko zastosowa\u0107 t\u0119 sam\u0105 klas\u0119 i\/lub styl inline r\u00f3wnie\u017c we frontendzie.<\/p>\n<h3>Dodaj niestandardow\u0105 klas\u0119 i styl wbudowany, aby zapisa\u0107<\/h3>\n<p>Na koniec musimy przefiltrowa\u0107 <code>blocks.getSaveContent.extraProps<\/code>i zastosowa\u0107 niezb\u0119dn\u0105 klas\u0119 i\/lub styl inline dla frontendu. Znowu jest to bardzo podobne do tego, co zrobili\u015bmy w przyk\u0142adzie 1 powy\u017cej. Je\u015bli wybrano kolor palety, musimy doda\u0107 nazw\u0119 klasy, kt\u00f3ra jest zgodna ze standardami WordPress dotycz\u0105cymi ustawie\u0144 kolor\u00f3w (\u201e <code>has-&lt;PALETTESLUG&gt;-background-color<\/code>&#8222;). Je\u015bli wybrano kolor niestandardowy, musimy doda\u0107 styl wbudowany z kolorem szesnastkowym.<\/p>\n<p>Uwaga: Je\u015bli cz\u0119sto potrzebujesz obs\u0142ugiwa\u0107 nazwy klas, polecam zaimportowa\u0107 <code>classnames<\/code>bibliotek\u0119. Jest to cz\u0119sto wykorzystywane w Gutenbergu, poniewa\u017c znacznie upraszcza ustawianie w\u0142a\u015bciwych nazw klas. Poni\u017cszy kod zak\u0142ada, \u017ce \u200b\u200btego nie zrobi\u0142e\u015b i tworzysz nazw\u0119 klasy r\u0119cznie.<\/p>\n<pre><code>function applySpacerBackground(props, blockType, attributes) {\n    if (blockType.name == 'core\/spacer') {\n        const { backgroundColor, customBackgroundColor } = attributes;\n\u00a0\n        \/\/ For improved class name handling, use classnames library. Or do it manually like..\n        let className = (props.className != undefined)? props.className: '';\n        if (backgroundColor != undefined) {\n            className += ' has-' + backgroundColor + '-background-color';\n        }\n        props.className = className;\n        if (customBackgroundColor != undefined) {\n            Object.assign(props, { style: { ...props.style, backgroundColor: customBackgroundColor }});\n        }\n    }\n    return props;\n}\n\u00a0\nwp.hooks.addFilter(\n    'blocks.getSaveContent.extraProps',\n    'awp\/spacer-apply-class',\n    applySpacerBackground\n);<\/code><\/pre>\n<p>Dzi\u0119ki powy\u017cszemu kodowi frontend b\u0119dzie teraz doskonale renderowa\u0107 bloki Spacer z naszym niestandardowym wyborem kolor\u00f3w!<\/p>\n<p>Ostatni\u0105 (opcjonaln\u0105) poprawk\u0105 jest dodanie CSS do edytora. Musisz doda\u0107 wbudowany CSS lub arkusz styl\u00f3w edytora. Na przyk\u0142ad mo\u017cesz umie\u015bci\u0107 arkusz styl\u00f3w w kolejce w tym samym haczyku PHP, kt\u00f3rego u\u017cyli\u015bmy do umieszczenia w kolejce naszego pliku JavaScript. Nie b\u0119d\u0119 wdawa\u0107 si\u0119 w szczeg\u00f3\u0142y, jak to zrobi\u0107; ale CSS, kt\u00f3rego potrzebujesz, jest podobny do poni\u017cszego. Jedyne co robi, to ustawia Spacer <code>background-color<\/code>na odziedziczony kolor (b\u0119dzie dziedziczy\u0142 po naszym wrapping div) po zaznaczeniu bloku:<\/p>\n<pre><code>.block-library-spacer__resize-container.is-selected { \n    background-color: inherit; \n}<\/code><\/pre>\n<p>PS: Pami\u0119taj, \u017ce mo\u017ce si\u0119 to zmieni\u0107 w przysz\u0142o\u015bci. Gutenberg wci\u0105\u017c intensywnie si\u0119 rozwija.<\/p>\n<h2>Wniosek<\/h2>\n<p>W tym po\u015bcie poznali\u015bmy dwie metody implementowania niestandardowych ustawie\u0144 do istniej\u0105cych blok\u00f3w WordPress Gutenberg. Jest to w pe\u0142ni mo\u017cliwe w przypadku prostych ustawie\u0144, kt\u00f3re by\u0107 mo\u017ce wymagaj\u0105 jedynie stylizacji klasowej lub wbudowanej. Przyjrzeli\u015bmy si\u0119 ostrze\u017ceniom, kt\u00f3re mam nadziej\u0119 zostan\u0105 poprawione w p\u00f3\u017aniejszych wersjach Gutenberga!<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>W tym po\u015bcie om\u00f3wimy szczeg\u00f3\u0142owo, jak doda\u0107 niestandardowe ustawienia do istniej\u0105cych blok\u00f3w Gutenberga WordPress z dwoma przyk\u0142adowymi kodami rzeczywistych przypadk\u00f3w u\u017cycia.<\/p>\n","protected":false},"author":1,"featured_media":152422,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[897,721,721,940,940,897,1110,836,836,845,845,866,866],"tags":[1169],"class_list":{"0":"post-233746","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-kod","8":"category-deweloper","10":"category-gutenberg-7","13":"category-n-a","14":"category-przewodnik-dla-poczatkujacych","16":"category-samouczki","18":"category-wordpress-7","20":"tag-affiai-pl"},"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233746","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=233746"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233746\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/152422"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=233746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=233746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=233746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}