{"id":233386,"date":"2023-02-12T15:12:00","date_gmt":"2023-02-12T12:12:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233386"},"modified":"2022-11-10T23:25:04","modified_gmt":"2022-11-10T20:25:04","slug":"jak-dodac-obraz-wybierz-w-niestandardowym-bloku-wordpress-gutenberg","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/jak-dodac-obraz-wybierz-w-niestandardowym-bloku-wordpress-gutenberg\/","title":{"rendered":"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg"},"content":{"rendered":"\n<p>Ten post jest dla Ciebie, kt\u00f3ry tworzy niestandardowy blok Gutenberga i potrzebuje sposobu na wybranie lub przes\u0142anie obrazu z Biblioteki multimedi\u00f3w. Wi\u0119kszo\u015b\u0107 innych typ\u00f3w p\u00f3l, takich jak pola wyboru, wprowadzanie tekstu lub selektory kolor\u00f3w, jest do\u015b\u0107 \u0142atwa do dodania, ale program do przesy\u0142ania multimedi\u00f3w wymaga nieco wi\u0119cej kodu. Stworzymy komponent Inspector, kt\u00f3ry jest odpowiedzialny za renderowanie przycisku do otwierania Biblioteki multimedi\u00f3w, wybierania obrazu i opcjonalnie usuwania lub zmiany w p\u00f3\u017aniejszym czasie. Wszystko przy u\u017cyciu standardowych komponent\u00f3w WordPress.<\/p>\n<p>Zanim zag\u0142\u0119bimy si\u0119 w kod, pami\u0119taj, \u017ce ten post wymaga pewnej wiedzy Gutenberga na temat pisania niestandardowych blok\u00f3w. Skoncentrujemy si\u0119 tylko na cz\u0119\u015bci do przesy\u0142ania multimedi\u00f3w, a nie na tym, jak zarejestrowa\u0107 si\u0119 i zrobi\u0107 sam blok Gutenberga. Je\u015bli nie masz pewno\u015bci, jak napisa\u0107 niestandardowy blok Gutenberga, mam seri\u0119 samouczk\u00f3w obejmuj\u0105cych dok\u0142adnie to:<\/p>\n<p>Pomijaj\u0105c to, zanurkujmy od razu!<\/p>\n<h2>Co zrobimy<\/h2>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153621-61e511f57cf93.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-153621-61e511f57cf93.png\" alt=\"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg\" ><\/a><\/p>\n<p>Funkcja wyboru multimedi\u00f3w b\u0119dzie funkcjonalnie dok\u0142adnie taka sama, jak funkcja polecanego obrazu WordPress. W Inspektorze dodamy panel sk\u0142adaj\u0105cy si\u0119 z przycisku do wyboru obrazu.<\/p>\n<p>Po klikni\u0119ciu przycisku pojawi si\u0119 okno \u201eWybierz lub prze\u015blij multimedia&quot; umo\u017cliwiaj\u0105ce wybranie pliku z Biblioteki multimedi\u00f3w. Ograniczamy Bibliotek\u0119 multimedi\u00f3w do wy\u015bwietlania tylko obraz\u00f3w. Po wybraniu obrazu wyskakuj\u0105ce okienko zamyka si\u0119, a panel wy\u015bwietla podgl\u0105d ma\u0142a miniatura wybranego obrazu. Poni\u017cej pojawi\u0105 si\u0119 przyciski podgl\u0105du do zmiany i usuni\u0119cia obrazu. Dok\u0142adnie tak jak w przypadku polecanego obrazu.<\/p>\n<p>Ten samouczek zak\u0142ada, \u017ce \u200b\u200bu\u017cyjesz wybranego obrazu jako t\u0142a bloku \u2013 tylko jako przyk\u0142ad. Dlatego przechowujemy adres URL obrazu. Podam przyk\u0142ad, jak wykorzysta\u0107 wybrany obrazek (zar\u00f3wno w funkcji, jak <code>edit<\/code>iw <code>save<\/code>funkcji). Wybieraj\u0105c obraz, obraz pojawi si\u0119 jako t\u0142o dla naszego bloku, zar\u00f3wno w edytorze, jak i w interfejsie u\u017cytkownika.<\/p>\n<p>Przechowujemy identyfikator multimedi\u00f3w i adres URL multimedi\u00f3w w atrybutach bloku. Kod u\u017cywa <code>withSelect<\/code>, komponentu wy\u017cszego rz\u0119du dostarczonego w <code>wp.data<\/code>pakiecie, do zapytania o wi\u0119cej informacji o wybranych mediach wed\u0142ug ID.<\/p>\n<p>\u201ePo\u017cyczam&#8221; r\u00f3wnie\u017c nazwy klas z funkcji polecanych obraz\u00f3w WordPressa, aby upewni\u0107 si\u0119, \u017ce wszystko wygl\u0105da dobrze i nie ma potrzeby samodzielnego pisania CSS. Jest to oczywi\u015bcie opcjonalne.<\/p>\n<h2>Zapisywanie wybranych medi\u00f3w w atrybutach<\/h2>\n<p>To, co musisz zapisa\u0107 w atrybutach swojego bloku, zale\u017cy troch\u0119 od Ciebie. Jako minimum musimy oczywi\u015bcie przechowywa\u0107 identyfikator no\u015bnika. Mo\u017ce to wystarczy\u0107, je\u015bli nie musisz u\u017cywa\u0107 adresu URL multimedi\u00f3w w dowolnym miejscu w kodzie skryptu. Na przyk\u0142ad, je\u015bli u\u017cywasz <code>ServerSideRender<\/code>gdzie PHP jest odpowiedzialne za renderowanie wyj\u015bcia bloku. W takim przypadku mo\u017cesz \u0142atwo uzyska\u0107 adres URL obrazu z identyfikatora medi\u00f3w, u\u017cywaj\u0105c na przyk\u0142ad <code>[wp_get_attachment_image_src](https:\/\/developer.wordpress.org\/reference\/functions\/wp_get_attachment_image_src\/)()<\/code>. Jednak w poni\u017cszym przyk\u0142adzie pokazuj\u0119 prosty przyk\u0142ad wy\u015bwietlania obrazu jako t\u0142a naszego bloku, wi\u0119c przechowuj\u0119 r\u00f3wnie\u017c adres URL medi\u00f3w jako atrybut. U\u017cyjemy atrybutu URL zar\u00f3wno w <code>edit<\/code>(aby doda\u0107 t\u0142o w edytorze), jak i w <code>save<\/code>(aby doda\u0107 t\u0142o w interfejsie).<\/p>\n<p>Zacznijmy od zdefiniowania naszych atrybut\u00f3w. Identyfikator medi\u00f3w powinien by\u0107 numerem typu i domy\u015blnie r\u00f3wnym 0. U\u0142atwia to por\u00f3wnywanie. Adres URL medi\u00f3w powinien by\u0107 typu string z domy\u015blnym pustym ci\u0105giem.<\/p>\n<pre><code>attributes: {\n    mediaId: {\n        type: 'number',\n        default: 0\n    },\n    mediaUrl: {\n        type: 'string',\n        default: ''\n    }\n},<\/code><\/pre>\n<h2>Tworzenie komponentu<\/h2>\n<p>Aby nasz kod by\u0142 bardziej uporz\u0105dkowany, definiujemy osobny komponent dla funkcji bloku <code>edit<\/code>. P\u00f3\u017aniej przeka\u017cemy ten komponent <code>withSelect<\/code>, aby owin\u0105\u0107 go wok\u00f3\u0142 naszego komponentu.<\/p>\n<p>W zwrocie komponentu renderujemy prost\u0105 <code>&lt;div&gt;<\/code>zawarto\u015b\u0107 bloku. Zak\u0142adam, \u017ce b\u0119dziesz lub mia\u0142 wi\u0119cej rzeczywistej zawarto\u015bci bloku, aby zast\u0105pi\u0107 fikcyjn\u0105 zawarto\u015b\u0107 przyk\u0142adu. Wykonujemy r\u00f3wnie\u017c renderowanie <code>InspectorControls<\/code>(package <code>wp.blockEditor<\/code>) w celu dodania sekcji do inspektora. Na razie dodaj\u0119 pusty <code>PanelBody<\/code>w \u015brodku <code>InspectorControls<\/code>. Dodaj\u0119 <code>&lt;div&gt;<\/code>klas\u0119 z t\u0105 sam\u0105 klas\u0105, kt\u00f3rej u\u017cywa sekcja z polecanymi obrazami WordPressa. Dzi\u0119ki temu nasza stylizacja b\u0119dzie dobrze wygl\u0105da\u0107. P\u00f3\u017aniej wype\u0142nimy <code>PanelBody<\/code>go kodem wybranej funkcji multimedialnej.<\/p>\n<p>Ale najpierw zdestrukturyzujmy niezb\u0119dny komponent na pocz\u0105tku pliku:<\/p>\n<pre><code>const { InspectorControls } = wp.blockEditor;\nconst { PanelBody } = wp.components;\nconst { Fragment } = wp.element;<\/code><\/pre>\n<p>Powy\u017cej <code>registerBlockType<\/code>definiuj\u0119 prosty komponent o nazwie <code>BlockEdit<\/code>. Je\u015bli wolisz przenie\u015b\u0107 to do osobnego pliku, mo\u017cesz to zrobi\u0107. Jest to powszechne i zalecane, ale w tym samouczku staram si\u0119 zachowa\u0107 prostot\u0119 i trzymam to w tym samym pliku.<\/p>\n<pre><code>const BlockEdit = (props) =&gt; {\n    const { attributes, setAttributes } = props;\n\u00a0\n    return (&lt;Fragment&gt;\n            &lt;InspectorControls&gt;\n                &lt;PanelBody\n                    title={__('Select block background image', 'awp')}\n                    initialOpen={ true }\n                &gt;\n                    &lt;div className=\"editor-post-featured-image\"&gt;\n                        ...We will add code here...\n                    &lt;\/div&gt;\n                &lt;\/PanelBody&gt;\n            &lt;\/InspectorControls&gt;\n            &lt;div&gt;\n                ... Your block content here...\n            &lt;\/div&gt;\n        &lt;\/Fragment&gt;\n    );\n};<\/code><\/pre>\n<p>Teraz chcemy wyrenderowa\u0107 ten komponent w naszej <code>edit<\/code>funkcji. Ale chcemy go owin\u0105\u0107 w <code>withSelect<\/code>.<\/p>\n<h2>Korzystanie <code>withSelect<\/code>w <code>edit<\/code>funkcji<\/h2>\n<p>Je\u015bli nie znasz <code>withSelect<\/code>, jest to przydatny sk\u0142adnik wy\u017cszego rz\u0119du, kt\u00f3ry umo\u017cliwia nam wykonywanie zapyta\u0144. Za pomoc\u0105 tego mo\u017cesz na przyk\u0142ad wyszukiwa\u0107 posty. Wykorzystamy jednak t\u0119 funkcj\u0119 <code>select('core').getMedia()<\/code>do zapytania o identyfikator medi\u00f3w. W odpowiedzi otrzymamy obiekt ze wszystkimi informacjami medialnymi. Obiekt multimedialny, kt\u00f3ry otrzymamy w odpowiedzi, zostanie udost\u0119pniony jako prop w naszym <code>BlockEdit<\/code>komponencie, gotowy do u\u017cycia. Sprytnie.<\/p>\n<p>Upewniamy si\u0119, \u017ce wysy\u0142amy zapytania do medi\u00f3w tylko wtedy, gdy atrybut ID medi\u00f3w jest rzeczywi\u015bcie ustawiony na co\u015b innego ni\u017c 0. Tak b\u0119dzie wygl\u0105da\u0107 nasza funkcja edycji:<\/p>\n<pre><code>edit: withSelect((select, props) =&gt; {\n    return { media: props.attributes.mediaId? select('core').getMedia(props.attributes.mediaId): undefined };\n})(BlockEdit),<\/code><\/pre>\n<p>Na samym ko\u0144cu, po zamkni\u0119ciu <code>withSelect<\/code>w kolejce <code>#3<\/code>, prosimy <code>withSelect<\/code>o zwrot naszego <code>BlockEdit<\/code>komponentu. Dzi\u0119ki temu nasz <code>BlockEdit<\/code>komponent ma teraz dost\u0119p do <code>props.media<\/code>.<\/p>\n<h2>Renderowanie wyboru medi\u00f3w<\/h2>\n<p>Wreszcie nadchodzi zabawna cz\u0119\u015b\u0107: rola w Inspektorze.<\/p>\n<p>Interesuj\u0105cy nas komponent to <code>MediaUpload<\/code>(pakiet <code>wp.blockEditor<\/code>). Je\u015bli jeste\u015b zainteresowany, repozytorium WordPress Github dla Gutenberga ma troch\u0119 <a href=\"https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/block-editor\/src\/components\/media-upload\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">dokumentacji na temat tego komponentu<\/a>. Zawiniemy r\u00f3wnie\u017c ten komponent wewn\u0105trz komponentu o nazwie <code>MediaUploadCheck<\/code>(package <code>wp.blockEditor<\/code>). Ten sk\u0142adnik upewnia si\u0119, \u017ce bie\u017c\u0105cy u\u017cytkownik ma mo\u017cliwo\u015b\u0107 korzystania z Biblioteki multimedi\u00f3w, wi\u0119c korzystanie z tego jest dobr\u0105 praktyk\u0105.<\/p>\n<p>Komponent <code>MediaUpload<\/code>ma wymagan\u0105 w\u0142a\u015bciwo\u015b\u0107: <code>render<\/code>. Spos\u00f3b dzia\u0142ania tego komponentu polega na tym, \u017ce definiujemy funkcj\u0119 dla w\u0142a\u015bciwo\u015bci, w <code>render<\/code>kt\u00f3rej renderujemy dane wyj\u015bciowe dla \u201eobszaru przesy\u0142ania medi\u00f3w&#8221;. W naszym przypadku wyrenderujemy <code>Button<\/code>(pakiet <code>wp.components<\/code>). Wewn\u0105trz w\u0142a\u015bciwo\u015bci renderuj\u0105cej MediaUpload uzyskujemy dost\u0119p do <code>open<\/code>funkcji, kt\u00f3r\u0105 mo\u017cemy wywo\u0142a\u0107, aby WordPress otworzy\u0142 wyskakuj\u0105ce okienko Media Library:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153621-61e511f6d571d.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-153621-61e511f6d571d.png\" alt=\"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg\" ><\/a><\/p>\n<p>Dost\u0119pnych jest jeszcze kilka rekwizyt\u00f3w dla <code>MediaUpload<\/code>. W tym samouczku om\u00f3wimy najwa\u017cniejsze, aby dzia\u0142a\u0142y, ale jest jeszcze kilka, z kt\u00f3rymi mo\u017cesz si\u0119 bawi\u0107. Mo\u017cesz by\u0107 co najmniej zainteresowany propozycj\u0105, w <code>allowedTypes<\/code>kt\u00f3rej mo\u017cesz ograniczy\u0107 typy plik\u00f3w, kt\u00f3re mo\u017cna wybra\u0107 w Bibliotece. W naszym przypadku ustawiamy go tak, aby zezwala\u0142 tylko na obrazy.<\/p>\n<h3>Dodawanie<code>MediaUpload<\/code><\/h3>\n<p>Najpierw zdekonstruuj nowe komponenty;<\/p>\n<pre><code>const { Button } = wp.components;\nconst { MediaUpload, MediaUploadCheck } = wp.blockEditor;<\/code><\/pre>\n<p>Dodajmy <code>MediaUploadCheck<\/code>i <code>MediaUpload<\/code>wewn\u0105trz naszych <code>div<\/code>w naszym <code>PanelBody<\/code>:<\/p>\n<pre><code>&lt;div className=\"editor-post-featured-image\"&gt;\n    &lt;MediaUploadCheck&gt;\n        &lt;MediaUpload\n            allowedTypes={ ['image'] }\n            render={({open}) =&gt; (&lt;Button \n                    className={attributes.mediaId == 0? 'editor-post-featured-image__toggle': 'editor-post-featured-image__preview'}\n                    onClick={open}\n                &gt;\n                    {attributes.mediaId == 0 &amp;&amp; __('Choose an image', 'awp')}\n                &lt;\/Button&gt;\n            )}\n        \/&gt;\n    &lt;\/MediaUploadCheck&gt;\n&lt;\/div&gt;<\/code><\/pre>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153621-61e511fa0bf3f.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-153621-61e511fa0bf3f.png\" alt=\"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg\" ><\/a><\/p>\n<p>Powy\u017cszy kod destrukturyzuje <code>open<\/code>wewn\u0105trz funkcji for <code>render<\/code>. Renderujemy prosty, w <code>Button<\/code>kt\u00f3rym jego <code>onClick<\/code>w\u0142a\u015bciwo\u015b\u0107 b\u0119dzie uruchamia\u0107 <code>open<\/code>funkcj\u0119. Doda\u0142em r\u00f3wnie\u017c te same nazwy klas, co funkcja obrazu w WordPressie, aby upewni\u0107 si\u0119, \u017ce nie musimy dodawa\u0107 \u017cadnych styl\u00f3w.<\/p>\n<p>Wewn\u0105trz <code>Button<\/code>komponentu sprawdzamy, czy zosta\u0142 ustawiony obrazek (<code>attributes.mediaId<\/code>). Je\u015bli nie, powtarzamy tekst \u201eWybierz obraz&#8221;. Powinni\u015bmy to teraz dosta\u0107 w naszym bloku.<\/p>\n<p>Po klikni\u0119ciu przycisku powinno pojawi\u0107 si\u0119 wyskakuj\u0105ce okienko Media Library. Jednak wyb\u00f3r obrazu nie dzia\u0142a w tej chwili, poniewa\u017c brakuje nam rekwizyt\u00f3w <code>onSelect<\/code>i na. Naprawmy to teraz. Ustawiamy wybrany identyfikator no\u015bnika i uruchamiamy funkcj\u0119, kt\u00f3r\u0105 p\u00f3\u017aniej zdefiniujemy w naszym komponencie.<code>value``MediaUpload``value``onSelect<\/code><\/p>\n<pre><code>...\n&lt;MediaUploadCheck&gt;\n    &lt;MediaUpload\n        onSelect={onSelectMedia}\n        value={attributes.mediaId}\n        allowedTypes={ ['image'] }\n        ...<\/code><\/pre>\n<p>Zdefiniujmy <code>onSelectMedia<\/code>funkcj\u0119 w naszym komponencie.<\/p>\n<h3>Obs\u0142uga wyboru medi\u00f3w<\/h3>\n<p><strong>Uwaga<\/strong>: moje funkcje definiuj\u0119 jako funkcje strza\u0142ek (<code>onSelectMedia =() =&gt; { }<\/code>). Funkcje strza\u0142ek s\u0105 ca\u0142kiem nowe w ESNext i ca\u0142kiem fajne. Minusem jest to, \u017ce u\u017cywanie funkcji strza\u0142ek wymaga dodania obs\u0142ugi tego w konfiguracji Babel. Je\u015bli jeszcze tego nie zrobi\u0142e\u015b, polecam zajrze\u0107 pod nag\u0142\u00f3wek \u201eKonfiguracja Babel&#8221; w <a href=\"https:\/\/awhitepixel.com\/blog\/how-to-create-custom-gutenberg-blocks-part-1-setting-up-the-development-environment\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tym po\u015bcie<\/a>.<\/p>\n<p>Tu\u017c przed instrukcj\u0105 return komponentu definiuj\u0119 <code>onSelectMedia<\/code>funkcj\u0119. Wszystko, co musimy zrobi\u0107, to zaktualizowa\u0107 nasze atrybuty za pomoc\u0105 <code>setAttributes()<\/code>. Jako parametr <code>onSelectMedia<\/code>otrzymujemy obiekt media. Po prostu wydobywamy to, czego potrzebujemy z obiektu medialnego. W naszym przypadku jest to identyfikator medi\u00f3w i adres URL w pe\u0142nym rozmiarze, kt\u00f3re s\u0105 odpowiednio w\u0142a\u015bciwo\u015bciami <code>id<\/code>.<code>url<\/code><\/p>\n<pre><code>const BlockEdit = (props) =&gt; {\n    const { attributes, setAttributes } = props;\n\u00a0\n    const onSelectMedia = (media) =&gt; {\n        props.setAttributes({\n            mediaId: media.id,\n            mediaUrl: media.url\n        });\n    }\n\u00a0\n    return(\n        ...<\/code><\/pre>\n<p>Wypr\u00f3buj teraz, a teraz b\u0119dziesz m\u00f3g\u0142 wybra\u0107 obraz z Biblioteki multimedi\u00f3w. Wybrane media zostan\u0105 zapisane w atrybutach bloku. Jednak nie ma jeszcze podgl\u0105du tego w Inspektorze, a poniewa\u017c zaznaczy\u0142e\u015b obraz, przycisk wyboru obrazu znika. Panel jest teraz pusty. Nast\u0119pnym krokiem jest renderowanie podgl\u0105du po wybraniu obrazu oraz udost\u0119pnienie opcji jego usuni\u0119cia lub zmiany.<\/p>\n<h2>Renderowanie obrazu podgl\u0105du<\/h2>\n<p>Wewn\u0105trz <code>Button<\/code>komponentu renderujemy wewn\u0119trzn\u0105 w\u0142a\u015bciwo\u015b\u0107, wy\u015bwietlamy tekst <code>MediaUpload<\/code>\u201e <code>render<\/code>Wybierz obraz&#8221;, je\u015bli obraz nie jest jeszcze ustawiony. Ale musimy doda\u0107 troch\u0119 kodu, gdy obraz jest tutaj ustawiany; podgl\u0105d.<\/p>\n<p>Aby pom\u00f3c nam wyrenderowa\u0107 \u0142adny podgl\u0105d, u\u017cywamy komponentu <code>ResponsiveWrapper<\/code>(pakiet <code>wp.components<\/code>). Aby w <code>ResponsiveWrapper<\/code>pe\u0142ni funkcjonowa\u0107 musimy zapewni\u0107 podpory na wysoko\u015b\u0107 i szeroko\u015b\u0107. Potrzebujemy r\u00f3wnie\u017c adresu URL miniatury. Nie ma sensu u\u017cywa\u0107 pe\u0142nego adresu URL (kt\u00f3ry mo\u017ce by\u0107 gigantyczny) do renderowania podgl\u0105du w Inspektorze. St\u0105d pochodzi prop <code>withSelect<\/code>. Wewn\u0105trz komponentu renderujemy prosty <code>&lt;img&gt;<\/code>znacznik HTML.<\/p>\n<p>Najpierw destrukturyzujemy niezb\u0119dny sk\u0142adnik:<\/p>\n<pre><code>const { ResponsiveWrapper } = wp.components;<\/code><\/pre>\n<pre><code>&lt;Button \n    className={attributes.mediaId == 0? 'editor-post-featured-image__toggle': 'editor-post-featured-image__preview'}\n    onClick={open}\n&gt;\n    {attributes.mediaId == 0 &amp;&amp; __('Choose an image', 'awp')}\n    {props.media != undefined &amp;&amp; \n        &lt;ResponsiveWrapper\n                naturalWidth={ props.media.media_details.width }\n            naturalHeight={ props.media.media_details.height }\n            &gt;\n                &lt;img src={props.media.source_url} \/&gt;\n            &lt;\/ResponsiveWrapper&gt;\n    }\n&lt;\/Button&gt;<\/code><\/pre>\n<p>Jak wida\u0107, uzyskujemy dost\u0119p do podpory <code>withSelect<\/code>dostarczonego nam komponentu, <code>props.media<\/code>. Z obiektu pobieramy szeroko\u015b\u0107, wysoko\u015b\u0107 i adres URL do rozmiaru miniaturki multimedi\u00f3w.<\/p>\n<p>Powiniene\u015b teraz uzyska\u0107 \u0142adny podgl\u0105d wybranego obrazu!<\/p>\n<p>Poniewa\u017c renderujemy obraz podgl\u0105du wewn\u0105trz, <code>Button<\/code>klikni\u0119cie na obraz podgl\u0105du uruchomi funkcj\u0119 <code>Button<\/code>\u2013 <code>onClick<\/code>czyli otwarcie Biblioteki multimedi\u00f3w. W ten spos\u00f3b mo\u017cesz ju\u017c zmieni\u0107 wybrany obraz.<\/p>\n<p>Obecnie nie ma mo\u017cliwo\u015bci usuni\u0119cia lub zresetowania wybranego obrazu. Naprawmy to!<\/p>\n<h3>Dodawanie funkcji usuwania<\/h3>\n<p>Powinni\u015bmy przynajmniej zaoferowa\u0107 u\u017cytkownikowi mo\u017cliwo\u015b\u0107 usuni\u0119cia wybranego obrazu. W tej chwili po wybraniu obrazu mo\u017cesz go tylko zmieni\u0107, ale nie mo\u017cesz go usun\u0105\u0107.<\/p>\n<p>Zrobimy to tak samo, jak WordPress w przypadku polecanego obrazu: Nowe <code>Button<\/code>pod obrazem podgl\u0105du (ca\u0142kowicie poza jego <code>MediaUploadCheck<\/code>). Dodaj\u0105c kilka sprytnych rekwizyt\u00f3w <code>Button<\/code>, sprawiamy, \u017ce wygl\u0105da on jak link (<code>isLink<\/code>) z czerwonym kolorem tekstu (<code>isDestructive<\/code>). Przeczytaj <a href=\"https:\/\/github.com\/WordPress\/gutenberg\/tree\/master\/packages\/components\/src\/button\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">dokumentacj\u0119 przycisku<\/a>, aby zobaczy\u0107, co jeszcze jest mo\u017cliwe. Przycisk owijamy w jeszcze jeden <code>MediaUploadCheck<\/code>, aby zapewni\u0107 u\u017cytkownikowi odpowiednie mo\u017cliwo\u015bci.<\/p>\n<pre><code>        ...\n        &lt;\/MediaUploadCheck&gt;\n        {attributes.mediaId != 0 &amp;&amp; \n            &lt;MediaUploadCheck&gt;\n                &lt;Button onClick={removeMedia} isLink isDestructive&gt;{__('Remove image', 'awp')}&lt;\/Button&gt;\n            &lt;\/MediaUploadCheck&gt;\n        }\n    &lt;\/div&gt;\n&lt;\/PanelBody&gt;<\/code><\/pre>\n<p>W tym przypadku uruchamiamy now\u0105 funkcj\u0119 w naszym komponencie <code>Button<\/code>:. Definiujemy go gdzie\u015b tu\u017c przed funkcj\u0105 powrotu komponentu, tak jak zrobili\u015bmy to z .<code>onClick``removeMedia()``onSelectMedia<\/code><\/p>\n<pre><code>const removeMedia =() =&gt; {\n    props.setAttributes({\n        mediaId: 0,\n        mediaUrl: ''\n    });\n}<\/code><\/pre>\n<p>Wszystko, co robi ta funkcja, to resetowanie naszych dw\u00f3ch warto\u015bci atrybut\u00f3w.<\/p>\n<p>Teraz b\u0119dziemy mieli \u0142adny, przejrzysty link do usuni\u0119cia obrazu:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153621-61e511faedb09.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-153621-61e511faedb09.png\" alt=\"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg\" ><\/a><\/p>\n<p>Po klikni\u0119ciu nowego przycisku wybrany obraz i sam przycisk znikaj\u0105, a przycisk wyboru obrazu pojawia si\u0119 ponownie.<\/p>\n<h3>Dodawanie przycisku wymiany<\/h3>\n<p>Ten krok jest w pe\u0142ni opcjonalny. Jak wspomniano wcze\u015bniej, klikni\u0119cie obrazu podgl\u0105du obrazu otworzy bibliotek\u0119 multimedi\u00f3w i umo\u017cliwi zmian\u0119 obrazu. Jednak mo\u017ce to nie by\u0107 tak intuicyjne, aby wszyscy mogli to zrozumie\u0107. WordPress dodaje osobny przycisk do zmiany obrazu, aby by\u0142 bardzo przejrzysty. Mo\u017cemy zrobi\u0107 to samo.<\/p>\n<p>Aby wyrenderowa\u0107 przycisk zmiany obrazu, zasadniczo powtarzamy kod, kt\u00f3ry mamy do wyboru obrazu: inny <code>MediaUpload<\/code>komponent. Zapewniamy t\u0119 sam\u0105 funkcj\u0119 dla <code>onSelect<\/code>i <code>allowedFileTypes<\/code>jak <code>value<\/code>poprzednio. Wewn\u0105trz <code>render<\/code>rekwizytu <code>MediaUpload<\/code>po prostu renderujemy inny <code>Button<\/code>, kt\u00f3ry otwiera bibliotek\u0119 medi\u00f3w. Umie\u015b\u0107my ten przycisk przed przyciskiem Usu\u0144 \u2013 poniewa\u017c ma to wi\u0119cej sensu dla u\u017cytkownika ko\u0144cowego:<\/p>\n<pre><code>&lt;\/MediaUploadCheck&gt;\n{attributes.mediaId != 0 &amp;&amp; \n    &lt;MediaUploadCheck&gt;\n        &lt;MediaUpload\n            title={__('Replace image', 'awp')}\n            value={attributes.mediaId}\n            onSelect={onSelectMedia}\n            allowedTypes={['image']}\n            render={({open}) =&gt; (&lt;Button onClick={open} isDefault isLarge&gt;{__('Replace image', 'awp')}&lt;\/Button&gt;\n            )}\n        \/&gt;\n    &lt;\/MediaUploadCheck&gt;\n}\n{attributes.mediaId != 0 &amp;&amp; \n    &lt;MediaUploadCheck&gt;\n        &lt;Button onClick={removeMedia} ...<\/code><\/pre>\n<p>Wi\u0119c teraz powiniene\u015b otrzyma\u0107 to:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153621-61e511f57cf93.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-153621-61e511f57cf93.png\" alt=\"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg\" ><\/a><\/p>\n<h2>Korzystanie z wybranego obrazu<\/h2>\n<p>Do tej pory powinno by\u0107 ca\u0142kiem jasne, w jaki spos\u00f3b mo\u017cesz u\u017cy\u0107 wybranego obrazu. Masz identyfikator i adres URL medi\u00f3w zapisane w atrybutach twojego bloku. Jednak jako prosty przyk\u0142ad podam kod, kt\u00f3ry ustawia wybrany obraz jako t\u0142o bloku. Kod mo\u017cna wykona\u0107 dok\u0142adnie tak samo w funkcjach <code>edit<\/code>i <code>save<\/code>funkcjach. Po prostu tworzymy obiekt stylu, kt\u00f3ry nak\u0142adamy na opakowanie div bloku. W obiekcie stylu ustawiamy obraz t\u0142a na adres URL medi\u00f3w.<\/p>\n<pre><code>    ...\n    const blockStyle = {\n        backgroundImage: attributes.mediaUrl != 0? 'url(\"' + attributes.mediaUrl + '\")': 'none'\n    };\n\u00a0\n    return(\n        &lt;Fragment&gt;\n            &lt;InspectorControls&gt;\n            ...\n            &lt;\/InspectorControls&gt;\n            &lt;div style={blockStyle}&gt;\n                ... Your block content here...\n            &lt;\/div&gt;\n        &lt;\/Fragment&gt;\n        ...<\/code><\/pre>\n<p>Z reszt\u0105 niestandardowej zawarto\u015bci bloku mo\u017ce to z \u0142atwo\u015bci\u0105 wygl\u0105da\u0107 mniej wi\u0119cej tak:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-153621-61e511fd78dce.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-153621-61e511fd78dce.png\" alt=\"Jak doda\u0107 obraz Wybierz w niestandardowym bloku WordPress Gutenberg\" ><\/a><\/p>\n<p>Je\u015bli zastosujesz styl blokowy w obu <code>edit<\/code>i <code>save<\/code>, tw\u00f3j blok powinien teraz pobra\u0107 wybrane media jako t\u0142o. Zar\u00f3wno wewn\u0105trz edytora, jak i frontendu.<\/p>\n<h2>Wniosek<\/h2>\n<p>Wyb\u00f3r obrazu (lub pliku) z Biblioteki multimedi\u00f3w to funkcja, kt\u00f3rej Ty jako programista Gutenberg bez w\u0105tpienia b\u0119dziesz potrzebowa\u0107 do swoich blok\u00f3w. Nauczyli\u015bmy si\u0119, jak doda\u0107 funkcj\u0119 wyboru obrazu z Biblioteki multimedi\u00f3w w naszym niestandardowym bloku Gutenberga. Zrobili\u015bmy to w taki sam spos\u00f3b, jak sam WordPress robi to dla polecanego obrazu. (Edytuj, maj 2020 r.: WordPress zaktualizowa\u0142 teraz polecany obraz, aby u\u017cywa\u0107 <code>useSelect<\/code>zamiast niego haka React). Dzi\u0119ki temu nasz kod nie jest \u201ehackowy&#8221; i wi\u0105\u017ce si\u0119 z wysokim ryzykiem z\u0142amania w przysz\u0142ych aktualizacjach.<\/p>\n<p>Daj mi zna\u0107, je\u015bli mia\u0142e\u015b z tego jakikolwiek u\u017cytek!<\/p>\n<h2>Pe\u0142ny kod<\/h2>\n<p>Poni\u017cej znajduje si\u0119 pe\u0142ny kod niestandardowego bloku, kt\u00f3ry zawiera wybrane funkcje multimedialne. I tak naprawd\u0119 nic wi\u0119cej. Ta cz\u0119\u015b\u0107 zale\u017cy od Ciebie!<\/p>\n<pre><code>const { registerBlockType } = wp.blocks;\nconst { InspectorControls, MediaUpload, MediaUploadCheck } = wp.blockEditor;\nconst { PanelBody, Button, ResponsiveWrapper } = wp.components;\nconst { Fragment } = wp.element;\nconst { withSelect } = wp.data;\nconst { __ } = wp.i18n;\nconst BlockEdit = (props) =&gt; {\n    const { attributes, setAttributes } = props;\n\u00a0\n    const removeMedia = () =&gt; {\n        props.setAttributes({\n            mediaId: 0,\n            mediaUrl: ''\n        });\n    }\n    const onSelectMedia = (media) =&gt; {\n        props.setAttributes({\n            mediaId: media.id,\n            mediaUrl: media.url\n        });\n    }\n\u00a0\n    const blockStyle = {\n        backgroundImage: attributes.mediaUrl != ''? 'url(\"' + attributes.mediaUrl + '\")': 'none'\n    };\n    return (&lt;Fragment&gt;\n            &lt;InspectorControls&gt;\n                &lt;PanelBody\n                    title={__('Select block background image', 'awp')}\n                    initialOpen={ true }\n                &gt;\n                    &lt;div className=\"editor-post-featured-image\"&gt;\n                        &lt;MediaUploadCheck&gt;\n                            &lt;MediaUpload\n                                onSelect={onSelectMedia}\n                                value={attributes.mediaId}\n                                allowedTypes={ ['image'] }\n                                render={({open}) =&gt; (&lt;Button \n                                        className={attributes.mediaId == 0? 'editor-post-featured-image__toggle': 'editor-post-featured-image__preview'}\n                                        onClick={open}\n                                    &gt;\n                                        {attributes.mediaId == 0 &amp;&amp; __('Choose an image', 'awp')}\n                                        {props.media != undefined &amp;&amp; \n                                                &lt;ResponsiveWrapper\n                                                naturalWidth={ props.media.media_details.width }\n                                            naturalHeight={ props.media.media_details.height }\n                                            &gt;\n                                                &lt;img src={props.media.source_url} \/&gt;\n                                            &lt;\/ResponsiveWrapper&gt;\n                                            }\n                                    &lt;\/Button&gt;\n                                )}\n                            \/&gt;\n                        &lt;\/MediaUploadCheck&gt;\n                        {attributes.mediaId != 0 &amp;&amp; \n                            &lt;MediaUploadCheck&gt;\n                                &lt;MediaUpload\n                                    title={__('Replace image', 'awp')}\n                                    value={attributes.mediaId}\n                                    onSelect={onSelectMedia}\n                                    allowedTypes={['image']}\n                                    render={({open}) =&gt; (&lt;Button onClick={open} isDefault isLarge&gt;{__('Replace image', 'awp')}&lt;\/Button&gt;\n                                    )}\n                                \/&gt;\n                            &lt;\/MediaUploadCheck&gt;\n                        }\n                        {attributes.mediaId != 0 &amp;&amp; \n                            &lt;MediaUploadCheck&gt;\n                                &lt;Button onClick={removeMedia} isLink isDestructive&gt;{__('Remove image', 'awp')}&lt;\/Button&gt;\n                            &lt;\/MediaUploadCheck&gt;\n                        }\n                    &lt;\/div&gt;\n                &lt;\/PanelBody&gt;\n            &lt;\/InspectorControls&gt;\n            &lt;div style={blockStyle}&gt;\n                ... Your block content here...\n            &lt;\/div&gt;\n        &lt;\/Fragment&gt;\n    );\n};\nregisterBlockType('awp\/imageselectinspector', {\n    title: 'AWP Imageselect',\n    icon: 'smiley',\n    category: 'layout',\n    supports: {\n        align: true\n    },\n    attributes: {\n        mediaId: {\n            type: 'number',\n            default: 0\n        },\n        mediaUrl: {\n            type: 'string',\n            default: ''\n        }\n    }, \n    edit: withSelect((select, props) =&gt; {\n        return { media: props.attributes.mediaId? select('core').getMedia(props.attributes.mediaId): undefined };\n    })(BlockEdit),\n    save: (props) =&gt; {\n        const { attributes } = props;\n        const blockStyle = {\n            backgroundImage: attributes.mediaUrl != ''? 'url(\"' + attributes.mediaUrl + '\")': 'none'\n        };\n        return (&lt;div style={blockStyle}&gt;\n                ... Your block content here...\n            &lt;\/div&gt;\n        );\n    }\n});<\/code><\/pre>\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 samouczku wyja\u015bniono, jak doda\u0107 przycisk wyboru lub przesy\u0142ania obrazu do biblioteki multimedi\u00f3w w inspektorze dla niestandardowego bloku WordPress Gutenberg.<\/p>\n","protected":false},"author":1,"featured_media":153622,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[897,940,940,732,732,897,1110,805,805,815,836,836,845,845,866,866,815],"tags":[1169],"class_list":{"0":"post-233386","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","6":"hentry","7":"category-kod","8":"category-gutenberg-7","10":"category-javascript-7","13":"category-n-a","14":"category-php-7","16":"category-wtyczki","17":"category-przewodnik-dla-poczatkujacych","19":"category-samouczki","21":"category-wordpress-7","24":"tag-affiai-pl"},"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233386","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=233386"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/233386\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/153622"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=233386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=233386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=233386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}