{"id":233995,"date":"2023-02-27T13:00:00","date_gmt":"2023-02-27T10:00:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233995"},"modified":"2022-11-11T13:42:00","modified_gmt":"2022-11-11T10:42:00","slug":"utworz-niestandardowy-blok-gutenberga-czesc-4-atrybuty","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/utworz-niestandardowy-blok-gutenberga-czesc-4-atrybuty\/","title":{"rendered":"Utw\u00f3rz niestandardowy blok Gutenberga &#8211; Cz\u0119\u015b\u0107 4: Atrybuty"},"content":{"rendered":"\n<p>W tej cz\u0119\u015bci przyjrzymy si\u0119, jak definiowa\u0107 atrybuty, pobiera\u0107 ich warto\u015bci i aktualizowa\u0107. Dzi\u0119ki atrybutom mo\u017cemy przyj\u0105\u0107 dane wej\u015bciowe z edytora, zapisa\u0107 je i wyprowadzi\u0107 w dowolny spos\u00f3b. W <a href=\"https:\/\/awhitepixel.com\/blog\/wordpress-gutenberg-create-custom-blocks-part-3-props-wordpress-components\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">poprzednim kroku<\/a> przyjrzeli\u015bmy si\u0119 komponentom WordPress, gdzie je znale\u017a\u0107 i jak je wdro\u017cy\u0107. W tym po\u015bcie dodamy rekwizyty do nawi\u0105zania po\u0142\u0105czenia z atrybutami \u2013 zapisanymi danymi.<\/p>\n<h2>Definiowanie atrybut\u00f3w<\/h2>\n<p>Atrybuty s\u0105 dodawane jako obiekty w tablicy do <code>attributes<\/code>w\u0142a\u015bciwo\u015bci w <code>registerBlockType()<\/code>. Kluczem ka\u017cdego atrybutu jest nazwa atrybutu i musisz mie\u0107 <code>type<\/code>przynajmniej w\u0142a\u015bciwo\u015b\u0107.<\/p>\n<p>W\u0142a\u015bciwo\u015b\u0107 <code>type<\/code>mo\u017ce by\u0107 dowoln\u0105 z poni\u017cszych; <code>null<\/code>, <code>boolean<\/code>, <code>object<\/code>, <code>array<\/code>, <code>number<\/code>, <code>string<\/code>, lub <code>integer<\/code>.<\/p>\n<p>Opcjonalnie mo\u017cesz poda\u0107 w\u0142a\u015bciwo\u015b\u0107, <code>default<\/code>aby zdefiniowa\u0107 pocz\u0105tkow\u0105 warto\u015b\u0107 atrybutu. Je\u015bli nie podasz warto\u015bci domy\u015blnej, atrybut przyjmie warto\u015b\u0107 domy\u015bln\u0105 <code>null<\/code>.<\/p>\n<p>Inna w\u0142a\u015bciwo\u015b\u0107 atrybutu <code>source<\/code>dzia\u0142a razem z t\u0105 <code>selector<\/code>w\u0142a\u015bciwo\u015bci\u0105, ale s\u0105 to drobiazgi, kt\u00f3rym przyjrzymy si\u0119 szczeg\u00f3\u0142owo poni\u017cej.<\/p>\n<p>Na przyk\u0142ad zdefiniowanie dw\u00f3ch atrybut\u00f3w; <code>exampleText<\/code>jako ci\u0105g i <code>postIds<\/code>jako tablica wygl\u0105da\u0142aby tak:<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nregisterBlockType('awp\/firstblock', {\n    title: 'My first block',\n    category: 'common',\n    attributes: {\n        exampleText: {\n            type: 'string',\n            default: ''\n        },\n        postIds: {\n            type: 'array'\n            default: []\n        }\n    },\n    edit: (props) =&gt; { \n    ...<\/code><\/pre>\n<p><strong>Wszystko, co chcesz zapisa\u0107 dla swojego bloku (dane wej\u015bciowe od u\u017cytkownika\/edytora), wymaga atrybutu<\/strong>. Od Ciebie zale\u017cy, jak ustrukturyzujesz swoje dane, definiuj\u0105c osobne atrybuty dla ka\u017cdego z nich lub \u0142\u0105cz\u0105c je wszystkie w jeden obiekt. B\u0119dzie to tylko r\u00f3\u017cnica w sposobie pobierania ich danych i ich aktualizacji.<\/p>\n<h2>Pobieranie warto\u015bci atrybut\u00f3w<\/h2>\n<p>Atrybuty s\u0105 dost\u0119pne jako rekwizyty do Twojego bloku <code>edit<\/code>i <code>save<\/code>funkcji. Je\u015bli \u015bledzi\u0142e\u015b t\u0119 seri\u0119 od <a href=\"https:\/\/awhitepixel.com\/blog\/wordpress-gutenberg-create-custom-blocks-part-3-props-wordpress-components\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">poprzedniego kroku<\/a>, pami\u0119taj, \u017ce zaktualizowali\u015bmy funkcje, aby przekazywa\u0142y props jako parametr.<\/p>\n<p>Cz\u0119sto <strong>destrukturyzuje<\/strong> si\u0119 atrybuty z rekwizyt\u00f3w, jak zwykle cz\u0119sto si\u0119 do nich odwo\u0142ujesz. Na przyk\u0142ad wypisanie wywo\u0142ywanego atrybutu <code>exampleText<\/code>wygl\u0105da\u0142oby tak:<\/p>\n<pre><code>edit: (props) =&gt; { \n    const { attributes } = props;\n    return &lt;div&gt;{attributes.exampleText}&lt;\/div&gt;\n},<\/code><\/pre>\n<h2>Aktualizowanie warto\u015bci atrybut\u00f3w<\/h2>\n<p>W celu aktualizacji atrybut\u00f3w mamy dost\u0119pn\u0105 w props metod\u0119 o nazwie <code>setAttributes()<\/code>. Ta funkcja akceptuje obiekt, do kt\u00f3rego mo\u017cesz doda\u0107 dowolny atrybut, kt\u00f3ry chcesz zaktualizowa\u0107. Mo\u017cesz zaktualizowa\u0107 tylko jeden atrybut, wi\u0119cej lub wszystkie naraz. Je\u015bli masz zdefiniowanych wiele atrybut\u00f3w i wywo\u0142asz <code>setAttributes()<\/code>aktualizacj\u0119 tylko jednego z nich, pozosta\u0142e nie zostan\u0105 dotkni\u0119te.<\/p>\n<p>Je\u015bli masz do\u015bwiadczenie z Reactem, prawdopodobnie od razu rozpoznasz podobie\u0144stwa mi\u0119dzy <code>setAttributes()<\/code>i <code>setState()<\/code>. Dzia\u0142aj\u0105 dok\u0142adnie tak samo, ale r\u00f3\u017cnica polega na tym, \u017ce stan w React jest po prostu czym\u015b przechowywanym lokalnie w tym komponencie, a atrybuty s\u0105 w rzeczywisto\u015bci zapisywane jako dane poza komponentem.<\/p>\n<p>Aby zaktualizowa\u0107 atrybut, zwykle destrukujesz funkcj\u0119 z w\u0142a\u015bciwo\u015bci i nazywasz to w ten spos\u00f3b: Poni\u017cej aktualizujemy <code>exampleText<\/code>atrybut na \u201eHi&quot;.<\/p>\n<pre><code>const { setAttributes } = props;\nsetAttributes({ exampleText: 'Hi' });<\/code><\/pre>\n<p>Naturalnie uruchomi\u0142by\u015b <code>setAttributes()<\/code>od wewn\u0105trz jak\u0105\u015b akcj\u0119. Typowym przyk\u0142adem jest wn\u0119trze w\u0142a\u015bciwo\u015bci <code>onChange<\/code>w jakim\u015b polu wej\u015bciowym, kt\u00f3re jest u\u017cywane do przechowywania warto\u015bci <code>exampleText<\/code>atrybutu.<\/p>\n<p>Upewnij si\u0119, \u017ce zapisa\u0142e\u015b atrybuty w typie zdefiniowanym w atrybucie. Na przyk\u0142ad nie b\u0119dziesz mia\u0142 szcz\u0119\u015bcia, pr\u00f3buj\u0105c zapisa\u0107 obiekty w atrybucie \u0142a\u0144cuchowym.<\/p>\n<p>Wypr\u00f3bujmy to w praktyce! Zainicjuj <code>npm run start<\/code>, je\u015bli jeszcze tego nie zrobi\u0142e\u015b.<\/p>\n<h2>Wy\u015bwietlanie atrybutu w niestandardowym wprowadzaniu tekstu i aktualizowanie warto\u015bci atrybutu<\/h2>\n<p>W poprzednim kroku dodali\u015bmy do <code>edit<\/code>, np. wpis tekstowy, ale nic nie zosta\u0142o zapisane. Dodajmy atrybut i jedno wej\u015bcie tekstowe dla niego w naszym bloku. Oboje upewnimy si\u0119, \u017ce wprowadzany tekst pokazuje aktualn\u0105 warto\u015b\u0107, a za ka\u017cdym razem, gdy dane wej\u015bciowe zostan\u0105 zmienione, zaktualizujemy atrybut.<\/p>\n<h3>Dodawanie tekstu wej\u015bciowego i jego <code>onChange<\/code>w\u0142a\u015bciwo\u015bci<\/h3>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { TextControl } = wp.components;\n\u00a0\nregisterBlockType('awp\/firstblock', {\n    title: 'My first block',\n    category: 'common',\n    attributes: {\n        exampleText: {\n            type: 'string',\n            default: ''\n        }\n    },\n    edit: (props) =&gt; { \n        const { attributes, setAttributes } = props;\n        return (&lt;div&gt;\n                &lt;TextControl \n                    value={attributes.exampleText}\n                    onChange={(newtext) =&gt; setAttributes({ exampleText: newtext })}\n                \/&gt; \n            &lt;\/div&gt;\n        );\n    },\n    save:() =&gt; { \n        return &lt;div&gt;:)&lt;\/div&gt; \n    }\n});<\/code><\/pre>\n<p>Destrukturyzujemy <code>attributes<\/code>i korzystamy <code>setAttributes<\/code>z <code>props<\/code>obu. Nast\u0119pnie korzystamy z <code>TextControl<\/code>komponentu z <code>wp.components<\/code>pakietu WordPress. Przekazujemy do niego dwa rekwizyty; <code>value<\/code>ustawi warto\u015b\u0107 wej\u015bcia (zar\u00f3wno pocz\u0105tkow\u0105, jak i podczas pisania) oraz akcj\u0119 na zdarzeniu wej\u015bcia <code>onChange<\/code>.<\/p>\n<p>W <code>value<\/code>ustawiamy j\u0105 na warto\u015b\u0107 naszego atrybutu; <code>attributes.exampleText<\/code>. W <code>onChange<\/code>przypadku, gdy uruchamiamy funkcj\u0119, przekazuj\u0105c wpisan\u0105 warto\u015b\u0107 naszego wej\u015bcia jako parametr <code>newtext<\/code>(warto\u015b\u0107 wej\u015bciowa to w\u0142a\u015bciwo\u015b\u0107 zwracana z komponentu). W tej funkcji wywo\u0142ujemy <code>setAttributes()<\/code>i aktualizujemy atrybut <code>exampleText<\/code>do tego, co zosta\u0142o wpisane w danych wej\u015bciowych.<\/p>\n<p>To jest podstawowy React \u2013 poza tym, \u017ce pracujemy z atrybutami, a nie stanem. Je\u015bli powy\u017csze zdezorientowa\u0142o Ci\u0119, polecam zajrze\u0107 do kr\u00f3tkiego samouczka w React, poniewa\u017c prawdopodobnie wyja\u015bni\u0105 to lepiej ni\u017c ja!<\/p>\n<p>Od\u015bwie\u017c sw\u00f3j edytor i zobacz, jak dzia\u0142a blok! Powiniene\u015b otrzyma\u0107 standardowe wej\u015bcie tekstowe do wpisywania rzeczy, kt\u00f3re zostanie zapisane za ka\u017cdym razem, gdy naci\u015bniesz Zapisz \/ Aktualizuj w edycji postu.<\/p>\n<h3>Wynik w interfejsie i w bazie danych<\/h3>\n<p>Je\u015bli przegl\u0105dasz sw\u00f3j post w interfejsie, powinien on nadal wy\u015bwietla\u0107 div z \u201e:)&#8221;, poniewa\u017c nadal mamy to w naszej <code>save<\/code>funkcji. Ale co\u015b si\u0119 wydarzy\u0142o za kulisami! Blok komentarza naszego bloku zawiera teraz warto\u015b\u0107 naszego atrybutu w JSON.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151357-61e4ca89cf1d2.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-151357-61e4ca89cf1d2.png\" alt=\"Utw\u00f3rz niestandardowy blok Gutenberga - Cz\u0119\u015b\u0107 4: Atrybuty\" ><\/a><\/p>\n<p>Nie mo\u017cesz zobaczy\u0107 blok\u00f3w komentarzy w szablonie, kt\u00f3ry wykonuje normalne <code>the_content()<\/code>wywo\u0142anie. Aby zobaczy\u0107 bloki komentarzy, masz dwie opcje. Sp\u00f3jrz na <code>post_content<\/code>tabel\u0119 w bazie danych post\u00f3w. Lub dodaj <code>echo get_the_content()<\/code>szablon i sp\u00f3jrz na niego w narz\u0119dziu do sprawdzania\/debugowania.<\/p>\n<p>Oczywi\u015bcie mamy r\u00f3wnie\u017c dost\u0119p do atrybut\u00f3w <code>save<\/code>z rekwizyt\u00f3w.<\/p>\n<h3>Wy\u015bwietlanie warto\u015bci wej\u015bcia w<code>save<\/code><\/h3>\n<p>Wy\u015bwietlmy warto\u015b\u0107 atrybutu w div w naszej <code>save<\/code>funkcji:<\/p>\n<pre><code>save: (props) =&gt; { \n    const { attributes } = props;\n    return &lt;div&gt;{attributes.exampleText}&lt;\/div&gt;\n}<\/code><\/pre>\n<p>Uwaga: po dokonaniu tej zmiany otrzymasz uszkodzony blok w po\u015bcie, do kt\u00f3rego ju\u017c doda\u0142e\u015b ten blok. Dzieje si\u0119 tak, poniewa\u017c edytor napotyka inny wynik <code>save<\/code>ni\u017c to, co zdefiniowali\u015bmy teraz. Usu\u0144 blok i dodaj go ponownie. Wpisz co\u015b w swoim tek\u015bcie, zaktualizuj post i wy\u015bwietl go w interfejsie.<\/p>\n<p>I to jest w\u0142a\u015bciwie sedno tego. Ty decydujesz, jakich atrybut\u00f3w potrzebujesz, aby zapisa\u0107 to, co chcesz w swoim bloku. W <code>edit<\/code>ten spos\u00f3b wyrenderujesz sposoby wprowadzania danych przez u\u017cytkownika, dbaj\u0105c o to, aby bie\u017c\u0105ce warto\u015bci by\u0142y wy\u015bwietlane i aktualizowa\u0107 je za ka\u017cdym razem, gdy ulegn\u0105 zmianie. Wyodr\u0119bniaj <code>save<\/code>zapisane atrybuty i renderuj dane wyj\u015bciowe tak, jak chcesz.<\/p>\n<p>W tej serii samouczk\u00f3w dotkniemy o wiele wi\u0119cej r\u00f3\u017cnych komponent\u00f3w i atrybut\u00f3w. Przyjrzyjmy si\u0119 jednak jeszcze jednemu komponentowi w tym po\u015bcie, aby zobaczy\u0107, o co chodzi we w\u0142a\u015bciwo\u015bci atrybutu <code>source<\/code>.<\/p>\n<h2>RichText i atrybut atrybut<code>source<\/code><\/h2>\n<p>Komponent WordPress <code>RichText<\/code>zapewnia obszar tekstowy \u201ebez obramowania&#8221; z obs\u0142ug\u0105 formatowania tekstu. Mo\u017cesz preferowa\u0107 u\u017cywanie tego zamiast (brzydkiego?) standardowego wprowadzania tekstu lub obszaru tekstowego. Pami\u0119taj jednak, \u017ce <code>RichText<\/code>musi to by\u0107 obs\u0142ugiwane nieco inaczej, poniewa\u017c istnieje kilka w\u0142a\u015bciwo\u015bci, o kt\u00f3rych musisz wiedzie\u0107, a tak\u017ce jest r\u00f3\u017cnica w sposobie, w jaki utrzymujemy warto\u015b\u0107 w naszej <code>save<\/code>funkcji.<\/p>\n<h3>Dodawanie <code>RichText<\/code>komponentu<\/h3>\n<p>Najprostsz\u0105 form\u0105 <code>RichText<\/code>jest zaimplementowanie go tak, jak przy wprowadzaniu tekstu:<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { RichText } = wp.blockEditor;\n\u00a0\nregisterBlockType('awp\/firstblock', {\n    ...\n    attributes: {\n        myRichText: {\n            type: 'string',\n            default: ''\n        }\n    },\n    edit: (props) =&gt; { \n        const { attributes, setAttributes } = props;\n        return (&lt;div&gt;\n                &lt;RichText \n                    value={attributes.myRichText}\n                    onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n                \/&gt; \n            &lt;\/div&gt;\n        );\n    },\n    ...<\/code><\/pre>\n<p>Zdestrukturyzowali\u015bmy <code>RichText<\/code>komponent z <code>wp.blockEditor<\/code>pakietu, ale poza tym powy\u017csze jest identyczne z tym, co zrobili\u015bmy ze standardowym tekstem wej\u015bciowym.<\/p>\n<h3>Obs\u0142uga <code>save<\/code>z<code>RichText<\/code><\/h3>\n<p>Jednak w <code>save<\/code>funkcji musisz ponownie u\u017cy\u0107 <code>RichText<\/code>komponentu, aby uzyska\u0107 warto\u015b\u0107 atrybutu. Wywo\u0142ujemy <code>RichText.Content<\/code>i ustawiamy prop <code>value<\/code>na nasz atrybut:<\/p>\n<pre><code>save: (props) =&gt; { \n    const { attributes } = props;\n    return (&lt;div&gt;\n            &lt;RichText.Content \n                value={attributes.myRichText}\n            \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre>\n<p>Spowoduje to wy\u015bwietlenie wszystkiego, co zosta\u0142o wpisane w <code>RichText<\/code>edytorze bezpo\u015brednio, bez zawini\u0119tego kodu HTML.<\/p>\n<p>Podczas pracy z <code>RichText<\/code>tob\u0105 najprawdopodobniej chcesz kontrolowa\u0107 opakowanie HTML wok\u00f3\u0142 tekstu, na przyk\u0142ad a <code>&lt;p&gt;<\/code>lub a <code>&lt;h2&gt;<\/code>, zar\u00f3wno w interfejsie, jak iw edytorze. W tym celu mo\u017cemy u\u017cy\u0107 prop o nazwie <code>tagName<\/code>.<\/p>\n<p>Komponent <code>RichText<\/code>umo\u017cliwia r\u00f3wnie\u017c kilka innych rekwizyt\u00f3w. <code>placeholder<\/code>Za pomoc\u0105 rekwizytu mo\u017cesz zdefiniowa\u0107 tekst zast\u0119pczy, kt\u00f3ry b\u0119dzie wy\u015bwietlany (wygaszony), gdy jest pusty. Komponent pozwala r\u00f3wnie\u017c kontrolowa\u0107, jakie opcje formatowania umo\u017cliwia pole (kt\u00f3re przyciski wy\u015bwietla na pasku narz\u0119dzi).<\/p>\n<h3><code>RichText<\/code>z<code>tagName<\/code><\/h3>\n<p>Za pomoc\u0105 w\u0142a\u015bciwo\u015bci <code>tagName<\/code>mo\u017cesz wst\u0119pnie zdefiniowa\u0107, w kt\u00f3rym tagu HTML zostanie opakowane wyj\u015bcie. Kiedy u\u017cywasz <code>tagName<\/code>w\u0142a\u015bciwo\u015bci, powiniene\u015b u\u017cy\u0107 tej samej w\u0142a\u015bciwo\u015bci <code>tagName<\/code>i warto\u015bci w obu <code>edit<\/code>i <code>save<\/code>.<\/p>\n<p>Powiedzmy, \u017ce chcesz umie\u015bci\u0107 warto\u015b\u0107 atrybutu w <code>&lt;h2&gt;<\/code>, co spowoduje w edytorze, \u017ce ka\u017cde dane wej\u015bciowe b\u0119d\u0105 h2. W <code>edit<\/code>mo\u017cesz zrobi\u0107:<\/p>\n<pre><code>&lt;RichText \n    tagName=\"h2\"\n    placeholder=\"Write your heading here\"\n    value={attributes.myRichText}\n    onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n\/&gt;<\/code><\/pre>\n<p>A w <code>save<\/code>:<\/p>\n<pre><code>&lt;RichText.Content \n    tagName=\"h2\"\n    value={attributes.myRichText}\n\/&gt;<\/code><\/pre>\n<p>Powy\u017csze spowoduje teraz wy\u015bwietlenie tego, co zosta\u0142o wpisane w <code>RichText<\/code>obszarze wewn\u0105trz <code>&lt;h2&gt;<\/code>tagu.<\/p>\n<h3>Za pomoc\u0105<code>source<\/code><\/h3>\n<p>Oczywi\u015bcie mo\u017cesz po\u0142\u0105czy\u0107 wiele tekstu sformatowanego w bloku, na przyk\u0142ad jeden dla nag\u0142\u00f3wka i jeden dla akapitu. Pami\u0119taj tylko, \u017ce ka\u017cdy b\u0119dzie potrzebowa\u0142 w\u0142asnego atrybutu. Na przyk\u0142ad:<\/p>\n<pre><code>attributes: {\n    myRichHeading: {\n        type: 'string'\n    },\n    myRichText: {\n        type: 'string'\n    }\n},\nedit: (props) =&gt; { \n    const { attributes, setAttributes } = props;\n    return (&lt;div&gt;\n            &lt;RichText \n                tagName=\"h2\"\n                placeholder=\"Write your heading here\"\n                value={attributes.myRichHeading}\n                onChange={(newtext) =&gt; setAttributes({ myRichHeading: newtext })}\n            \/&gt;\n            &lt;RichText\n                tagName=\"p\"\n                placeholder=\"Write your paragraph here\"\n                value={attributes.myRichText}\n                onChange={(newtext) =&gt; setAttributes({ myRichText: newtext })}\n            \/&gt;\n        &lt;\/div&gt;\n    );\n},\nsave: (props) =&gt; { \n    const { attributes } = props;\n    return (&lt;div&gt;\n            &lt;RichText.Content \n                tagName=\"h2\"\n                value={attributes.myRichHeading}\n            \/&gt;\n            &lt;RichText.Content \n                tagName=\"p\"\n                value={attributes.myRichText}\n            \/&gt;\n        &lt;\/div&gt;\n    );\n}<\/code><\/pre>\n<p>Jednak teraz zaczniesz napotyka\u0107 pewne problemy. Mimo \u017ce mo\u017cesz formatowa\u0107 tekst w edytorze, nic (lub niekt\u00f3re) z formatowania nie zostan\u0105 zapisane. Kiedy przegl\u0105dasz post w interfejsie, po prostu pojawi si\u0119 on jako <code>h2<\/code>i <code>p<\/code>, bez \u017cadnego formatowania (kursywa, pogrubienie, link). Nawet blok komentarza do twojego bloku nie zawiera formatowania. To jest trudne z <code>RichText<\/code>. Aby rozwi\u0105za\u0107 ten problem, musimy pracowa\u0107 z w\u0142a\u015bciwo\u015bci\u0105 atrybutu <code>source<\/code>.<\/p>\n<p>W\u0142a\u015bciwo\u015b\u0107 <code>source<\/code>umo\u017cliwiaj\u0105ca WordPressowi wyodr\u0119bnianie i interpretowanie tre\u015bci bezpo\u015brednio z tre\u015bci posta. Je\u015bli atrybut nie jest <code>source<\/code>ustawiony, zostanie zapisany i wyodr\u0119bniony z bloku komentarzy HTML.<\/p>\n<p>Podczas pracy <code>RichText<\/code>zwykle ustawiamy <code>source<\/code>na <code>html<\/code>, kt\u00f3ry wykorzystuje bibliotek\u0119 WordPressa do analizowania znacznik\u00f3w HTML. W\u0142a\u015bciwo\u015b\u0107 <code>source<\/code>wsp\u00f3\u0142pracuje z inn\u0105 w\u0142a\u015bciwo\u015bci\u0105 atrybutu; <code>selector<\/code>kt\u00f3ry definiuje, z kt\u00f3rego znacznika HTML powinien on wyodr\u0119bni\u0107.<\/p>\n<p>Jako przyk\u0142ad ustawiamy <code>source<\/code>jak <code>html<\/code>w naszym akapicie <code>RichText<\/code>i ustawiamy <code>selector<\/code>jako <code>p<\/code>(w przeciwnym razie domy\u015blnie jest to root of block the block).<\/p>\n<pre><code>attributes: {\n    ...\n    myRichText: {\n        type: 'string',\n        source: 'html',\n        selector: 'p'\n    }\n},<\/code><\/pre>\n<p>Teraz nasz drugi <code>RichText<\/code>powinien pomy\u015blnie zapisa\u0107 ca\u0142e formatowanie tekstu. Zauwa\u017cysz r\u00f3wnie\u017c, \u017ce blok komentarza wy\u015bwietla teraz tylko <code>myRichHeading<\/code>atrybut w JSON. Atrybut <code>myRichText<\/code>ca\u0142kowicie znikn\u0105\u0142 z bloku komentarzy. Dzieje si\u0119 tak, poniewa\u017c <code>source<\/code>WordPress analizuje teraz tre\u015b\u0107 posta zamiast bloku komentarza dla warto\u015bci atrybutu.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-151357-61e4ca8ab1967.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-151357-61e4ca8ab1967.png\" alt=\"Utw\u00f3rz niestandardowy blok Gutenberga - Cz\u0119\u015b\u0107 4: Atrybuty\" ><\/a><\/p>\n<p>Aby by\u0107 ca\u0142kowicie szczerym, nie pracowa\u0142em tak du\u017co z tym <code>source<\/code>atrybutem i zaleca\u0142bym unikanie go, je\u015bli mo\u017cesz. Dokumentacja WordPressa wyja\u015bnia nieco wi\u0119cej o <a href=\"https:\/\/developer.wordpress.org\/block-editor\/developers\/block-api\/block-attributes\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">\u017ar\u00f3dle i atrybutach<\/a>, kt\u00f3re chcesz sprawdzi\u0107 sam.<\/p>\n<p>W tym po\u015bcie poznali\u015bmy podstawy atrybut\u00f3w; jak je zdefiniowa\u0107, zaktualizowa\u0107 i wyprowadzi\u0107 ich warto\u015bci. W kolejnych krokach przyjrzymy si\u0119 wi\u0119kszej liczbie r\u00f3\u017cnych komponent\u00f3w i sposobom dodawania ustawie\u0144 poza sam\u0105 zawarto\u015bci\u0105 bloku; na pasku narz\u0119dzi i pasku bocznym edytora (nazywanym Inspektorem).<\/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 tej lekcji bloku Gutenberga dla pocz\u0105tkuj\u0105cych przyjrzymy si\u0119, jak definiowa\u0107 atrybuty, pobiera\u0107 ich warto\u015bci i aktualizowa\u0107.<\/p>\n","protected":false},"author":1,"featured_media":151358,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[940,940,1110,815,845,845,866,866,815],"tags":[1169],"class_list":["post-233995","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gutenberg-7","category-n-a","category-wtyczki","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233995","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=233995"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233995\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/151358"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=233995"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=233995"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=233995"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}