{"id":229615,"date":"2022-11-24T11:22:00","date_gmt":"2022-11-24T08:22:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229615"},"modified":"2022-11-09T08:42:38","modified_gmt":"2022-11-09T05:42:38","slug":"modyfikuj-kontenery-obrazow-po-stronie-serwera-w-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/modyfikuj-kontenery-obrazow-po-stronie-serwera-w-wordpress\/","title":{"rendered":"Modyfikuj kontenery obraz\u00f3w po stronie serwera w WordPress"},"content":{"rendered":"\n<p>Za ka\u017cdym razem, gdy tworzysz niestandardowe rozwi\u0105zania dla innych os\u00f3b, mo\u017cesz mie\u0107 do czynienia z drobiazgowymi przypadkami renderowania tre\u015bci przez WordPress.<\/p>\n<p>Zwykle sprowadza si\u0119 to do motywu, co najmniej jednej wtyczki lub kombinacji obu. A je\u015bli musisz pracowa\u0107 z obrazami indywidualnie, mo\u017ce to by\u0107 wyzwaniem. Problem z nawet pr\u00f3b\u0105 napisania takiego posta polega na tym, \u017ce trudno jest nawet opisa\u0107 sytuacj\u0119, w kt\u00f3rej mo\u017cesz potrzebowa\u0107 czego\u015b takiego.<\/p>\n<p>Mimo to zamierzam zrobi\u0107, co w mojej mocy. Oznacza to, \u017ce chc\u0119 podzieli\u0107 si\u0119 sposobem modyfikowania kontener\u00f3w obraz\u00f3w po stronie serwera przed renderowaniem ich po stronie klienta i zrobi\u0107 to za pomoc\u0105 biblioteki DOMDocument PHP.<\/p>\n<p>Brzmi jak du\u017co? Mam nadziej\u0119, \u017ce \u0142atwo to rozwi\u0105\u017c\u0119.<\/p>\n<p>Zanim przejdziemy do kodu, powiedzmy, \u017ce masz je, kt\u00f3re renderuj\u0105 obrazy w pojedynczym elemencie akapitu (lub dowolnym typie elementu na poziomie bloku) i musisz owin\u0105\u0107 ka\u017cdy element w jaki\u015b typ klasy, aby m\u00f3c uzyska\u0107 dost\u0119p to za po\u015brednictwem CSS lub JavaScript.<\/p>\n<h3>Gdzie jeste\u015bmy<\/h3>\n<p>Na pocz\u0105tek powiedzmy, \u017ce obrazy renderuj\u0105 si\u0119 tak:<\/p>\n<p>I musisz je renderowa\u0107 w ten spos\u00f3b:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164647-61e7698060b2e.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-164647-61e7698060b2e.png\" alt=\"Modyfikuj kontenery obraz\u00f3w po stronie serwera w WordPress\" ><\/a><\/p>\n<p>Teraz mo\u017cesz potrzebowa\u0107 odst\u0119pu mi\u0119dzy nimi lub nie. To naprawd\u0119 nie ma znaczenia, poniewa\u017c masz nad tym kontrol\u0119 za po\u015brednictwem CSS. Ale masz kontrol\u0119 nad tym, jak to jest przesy\u0142ane przez sie\u0107 do strony klienta.<\/p>\n<p>Aby to zrobi\u0107, potrzebujesz kilku rzeczy:<\/p>\n<ul>\n<li>Dost\u0119p do biblioteki DOMDocument PHP,<\/li>\n<li>Zrozumienie, jak manipulowa\u0107 tre\u015bci\u0105 za pomoc\u0105 haka <strong>the_content WordPress,<\/strong><\/li>\n<li>Strategia, jak chcesz zawija\u0107 obrazy.<\/li>\n<\/ul>\n<p>Przejd\u0119 przez ka\u017cdy z nich w kodzie, ale wystarczy powiedzie\u0107, \u017ce zamierzam zawin\u0105\u0107 ka\u017cdy obraz w element akapitu. Mo\u017cesz oczywi\u015bcie zrobi\u0107 to, co chcesz.<\/p>\n<h3>Jak to zrobi\u0107<\/h3>\n<p>Najpierw upewnij si\u0119, \u017ce deklarujesz, \u017ce u\u017cywasz tre\u015bci dokumentu DOM nad <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-00-acme-class-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">swoj\u0105 klas\u0105<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\nnamespace Acme;\n\nuse DOMDocument;\n\nclass AcmeContentSubscriber\n{\n  \/\/ ...\n}\n<\/code><\/pre>\n<p>Nast\u0119pnie id\u017a dalej i utw\u00f3rz zaczep do <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Filter_Reference\/the_content\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">the_content<\/a>. Spos\u00f3b, w jaki to zrobisz, b\u0119dzie zale\u017ce\u0107 od tego, jak zorganizowa\u0142e\u015b sw\u00f3j kod (czy to <a href=\"https:\/\/tommcfarlin.com\/tag\/oop-fundamentals\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">OOP<\/a>, czy nie). W tym przyk\u0142adzie poka\u017c\u0119 bardzo prosty przyk\u0142ad, <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-01-acme-content-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jak to zrobi\u0107<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\npublic function contentSubscriber()\n{\n  add_action( 'the_content', [$this, 'addImageAttributes']);\n}\n<\/code><\/pre>\n<p>Nast\u0119pnie b\u0119dziesz musia\u0142 wykona\u0107 troch\u0119 pracy (z kt\u00f3rych wszystko jest poni\u017cej, ale poza zakresem tego postu). To zawiera:<\/p>\n<ul>\n<li>konwersja kodowania encji HTML,<\/li>\n<li>tworzenie instancji dokumentu DOM,<\/li>\n<li>\u0142adowanie kodu HTML posta z przychodz\u0105cej tre\u015bci<\/li>\n<\/ul>\n<p>W kodzie powinno to wygl\u0105da\u0107 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-02-acme-add-image-attrbutes-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\npublic function addImageAttributes($content)\n{\n\n    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', \"UTF-8\");\n    $document = new DOMDocument();\n\n    libxml_use_internal_errors(true);\n    $document-&gt;loadHTML(utf8_decode($content));\n\n    \/\/ ...\n}\n<\/code><\/pre>\n<p>Nast\u0119pnie musisz przej\u015b\u0107 przez\u00a0 elementy <strong>img<\/strong> i upewni\u0107 si\u0119, \u017ce ustawiasz w\u0142a\u015bciwy atrybut. Mo\u017cesz zdecydowa\u0107 si\u0119 na u\u017cycie klasy, mo\u017cesz zdecydowa\u0107 si\u0119 na u\u017cycie atrybutu danych lub mo\u017cesz zdecydowa\u0107 si\u0119 na u\u017cycie czego\u015b innego. Ta cz\u0119\u015b\u0107 nie ma znaczenia.<\/p>\n<p>Zwr\u00f3\u0107 uwag\u0119, \u017ce dla danego obrazu b\u0119dziesz chcia\u0142 sprawdzi\u0107, czy nast\u0119pny element nie jest elementem akapitu, poniewa\u017c to w\u0142a\u015bnie wybieram zawijanie obrazu. Innymi s\u0142owy, je\u015bli nast\u0119pny element nie jest akapitem, zawiniemy go w element akapitu.<\/p>\n<p>Aby to zrobi\u0107, szkielet g\u0142\u00f3wnej funkcji powinien <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-03-acme-add-image-attrbutes-part-2-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wygl\u0105da\u0107 tak<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\npublic function addImageAttributes($content)\n{\n\n    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', \"UTF-8\");\n    $document = new DOMDocument();\n\n    libxml_use_internal_errors(true);\n    $document-&gt;loadHTML(utf8_decode($content));\n\n    $images = $document-&gt;getElementsByTagName('img');\n    foreach ($images as $image) {\n        $image-&gt;setAttribute('class', 'acme-iamge');\n        if ($image-&gt;nextSibling-&gt;tagName !== 'p') {\n            $this-&gt;wrapImage($document, $image);\n        }\n    }\n\n    \/\/ ...\n}\n<\/code><\/pre>\n<p>Wtedy funkcja odpowiedzialna za faktyczne zawini\u0119cie elementu w elemencie akapitu powinna wygl\u0105da\u0107 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-05-wrap-image-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * This function is used to wrap individual images in a paragraph element.\n *\n * @param $document The DOM Document which is to be rendered.\n * @param $image    The image to wrap with the new paragraph element.\n *\/\nprivate function wrapImage($document, $image)\n{\n    if (null === $image) {\n        return;\n    }\n    $wrapper = $document-&gt;createElement('p');\n    $wrapper-&gt;setAttribute('class', 'acme-image');\n\n    $image-&gt;parentNode-&gt;replaceChild($wrapper, $image);\n    if (null !== $image) {\n        $wrapper-&gt;appendChild($image);\n    }\n}\n<\/code><\/pre>\n<p>Pami\u0119taj, aby przeczyta\u0107 DocBlock kodu, aby zrozumie\u0107, jak dzia\u0142a funkcja. M\u00f3wi\u0105c prosto:<\/p>\n<ul>\n<li>akceptuje instancj\u0119 dokumentu oraz element image,<\/li>\n<li>tworzy element akapitu,<\/li>\n<li>dodaje atrybut klasy<\/li>\n<li>zast\u0119puje oryginalny element obrazu paragrafem,<\/li>\n<li>i dodaje obraz jako element podrz\u0119dny<\/li>\n<\/ul>\n<p>A poniewa\u017c oparli\u015bmy obiekt document na metodzie, nie musimy niczego zwraca\u0107.<\/p>\n<p>Ostateczna wersja oryginalnej funkcji powinna wygl\u0105da\u0107 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-04-acme-add-image-attrbutes-part-3-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\npublic function addImageAttributes($content)\n{\n\n    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', \"UTF-8\");\n    $document = new DOMDocument();\n\n    libxml_use_internal_errors(true);\n    $document-&gt;loadHTML(utf8_decode($content));\n\n    $images = $document-&gt;getElementsByTagName('img');\n    foreach ($images as $image) {\n        $image-&gt;setAttribute('class', 'acme-image');\n        if ($image-&gt;nextSibling-&gt;tagName !== 'p') {\n            $this-&gt;wrapImage($document, $image);\n        }\n    }\n\n  return $document-&gt;saveHTML();\n}\n<\/code><\/pre>\n<p>Twoje wyj\u015bcie powinno wygl\u0105da\u0107 jak na powy\u017cszym obrazku. Pami\u0119taj jednak; musisz zwr\u00f3ci\u0107 wyniki instancji dokumentu do WordPressa, aby poprawnie renderowa\u0142 kod HTML. I to w\u0142a\u015bnie\u00a0 robi funkcja <strong>saveHTML<\/strong> w powy\u017cszym kodzie.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sprawd\u017a, jak u\u017cywa\u0107 DOMDocument do modyfikowania element\u00f3w HTML przed ich renderowaniem.<\/p>\n","protected":false},"author":1,"featured_media":221217,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,845,866],"tags":[1169],"class_list":["post-229615","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229615","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=229615"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/229615\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/221217"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=229615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=229615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=229615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}