{"id":229764,"date":"2022-11-24T10:37:00","date_gmt":"2022-11-24T07:37:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229764"},"modified":"2022-11-09T16:17:06","modified_gmt":"2022-11-09T13:17:06","slug":"aendra-bildbehaallare-paa-serversidan-i-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/aendra-bildbehaallare-paa-serversidan-i-wordpress\/","title":{"rendered":"\u00c4ndra bildbeh\u00e5llare p\u00e5 serversidan i WordPress"},"content":{"rendered":"\n<p>N\u00e4rhelst du bygger anpassade l\u00f6sningar f\u00f6r andra m\u00e4nniskor kan du beh\u00f6va ta itu med nyanserade fall av hur WordPress renderar inneh\u00e5llet.<\/p>\n<p>Detta beror vanligtvis p\u00e5 temat, \u00e5tminstone en plugin eller kombinationen av b\u00e5da. Och om du beh\u00f6ver arbeta med bilder individuellt, d\u00e5 kan det vara lite av en utmaning. Problemet med att ens f\u00f6rs\u00f6ka skriva ett s\u00e5nt h\u00e4r inl\u00e4gg \u00e4r att det \u00e4r sv\u00e5rt att ens beskriva en situation d\u00e4r du kan beh\u00f6va n\u00e5got liknande.<\/p>\n<p>\u00c4nd\u00e5 ska jag g\u00f6ra s\u00e5 gott jag kan. Det vill s\u00e4ga, jag vill dela med mig av hur man modifierar bildbeh\u00e5llare p\u00e5 serversidan innan jag renderar dem p\u00e5 klientsidan och g\u00f6r det med PHP:s DOMDocument-bibliotek.<\/p>\n<p>L\u00e5ter det mycket? F\u00f6rhoppningsvis kan jag bryta ner detta enkelt nog.<\/p>\n<p>Innan du g\u00e5r in i koden, l\u00e5t oss s\u00e4ga att du har en dem som \u00e5terger bilder i ett enda styckeelement (eller n\u00e5gon typ av element p\u00e5 blockniv\u00e5) och att du m\u00e5ste sl\u00e5 in varje element i n\u00e5gon typ av klass s\u00e5 att du kan komma \u00e5t det via CSS eller JavaScript.<\/p>\n<h3>D\u00e4r vi \u00e4r<\/h3>\n<p>S\u00e5, till att b\u00f6rja med, l\u00e5t oss s\u00e4ga att bilderna \u00e5terges s\u00e5 h\u00e4r:<\/p>\n<p>Och du m\u00e5ste \u00e5terge dem s\u00e5 h\u00e4r:<\/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=\"\u00c4ndra bildbeh\u00e5llare p\u00e5 serversidan i WordPress\" ><\/a><\/p>\n<p>Nu kanske du beh\u00f6ver utrymme mellan dem eller inte. Det spelar egentligen ingen roll eftersom du har kontroll \u00f6ver detta via CSS. Men du har kontroll \u00f6ver hur detta skickas \u00f6ver tr\u00e5den till klientsidan.<\/p>\n<p>F\u00f6r att g\u00f6ra detta beh\u00f6ver du n\u00e5gra saker:<\/p>\n<ul>\n<li>Tillg\u00e5ng till PHP:s DOMDocument-bibliotek,<\/li>\n<li>F\u00f6rst\u00e5else f\u00f6r hur man manipulerar inneh\u00e5ll via WordPress&#8217; <strong>the_content-<\/strong> hook,<\/li>\n<li>En strategi f\u00f6r hur du vill sl\u00e5 in bilderna.<\/li>\n<\/ul>\n<p>Jag ska g\u00e5 igenom var och en av dessa i koden men det r\u00e4cker med att s\u00e4ga att jag kommer att sl\u00e5 in varje bild i ett styckeelement. Du kan sj\u00e4lvklart v\u00e4lja att g\u00f6ra vad du vill.<\/p>\n<h3>Hur man g\u00f6r det<\/h3>\n<p>Se f\u00f6rst till att du har deklarerat att du anv\u00e4nder inneh\u00e5llet i DOM-dokumentet ovanf\u00f6r <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-00-acme-class-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">din klass<\/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>G\u00e5 sedan vidare och skapa en krok till <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Filter_Reference\/the_content\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">the_content<\/a>. Hur du g\u00f6r detta beror p\u00e5 hur du har organiserat din kod (oavsett om det \u00e4r <a href=\"https:\/\/tommcfarlin.com\/tag\/oop-fundamentals\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">OOP<\/a> eller inte). F\u00f6r det h\u00e4r exemplet ska jag visa ett mycket enkelt exempel p\u00e5 <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-01-acme-content-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">hur man g\u00f6r det<\/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>Efter det m\u00e5ste du g\u00f6ra lite arbete (som allt \u00e4r nedan men utanf\u00f6r ramen f\u00f6r detta inl\u00e4gg). Detta inkluderar:<\/p>\n<ul>\n<li>konvertera kodningen av HTML-entiteterna,<\/li>\n<li>skapa en instans av DOM-dokumentet,<\/li>\n<li>ladda inl\u00e4ggets HTML fr\u00e5n det inkommande inneh\u00e5llet<\/li>\n<\/ul>\n<p>I koden ska det se <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\">ut s\u00e5 h\u00e4r<\/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>D\u00e4refter m\u00e5ste du iterera genom <strong>img-<\/strong> elementen och se till att du st\u00e4ller in ett korrekt attribut. Du kan v\u00e4lja att anv\u00e4nda en klass, du kan v\u00e4lja att anv\u00e4nda ett dataattribut eller s\u00e5 kan du v\u00e4lja att anv\u00e4nda n\u00e5got annat. Den h\u00e4r delen spelar ingen roll.<\/p>\n<p>Observera att du f\u00f6r en given bild vill kontrollera att n\u00e4sta element inte \u00e4r ett styckeelement eftersom det \u00e4r det jag v\u00e4ljer att sl\u00e5 in bilden. Med andra ord, om n\u00e4sta element inte \u00e4r ett stycke, kommer vi att sl\u00e5 in elementet i ett styckeelement.<\/p>\n<p>F\u00f6r att g\u00f6ra detta b\u00f6r skelettet f\u00f6r huvudfunktionen <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\">se ut s\u00e5 h\u00e4r<\/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>D\u00e5 ska funktionen som \u00e4r ansvarig f\u00f6r att faktiskt linda elementet i ett styckeelement se <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/44178197b6878eb43e369cf6e5de09fc#file-05-wrap-image-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ut s\u00e5 h\u00e4r<\/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>Se till att l\u00e4sa kodens DocBlock f\u00f6r att f\u00f6rst\u00e5 hur funktionen fungerar. Enkelt uttryckt:<\/p>\n<ul>\n<li>den accepterar en instans av dokumentet och bildelementet,<\/li>\n<li>skapar ett styckeelement,<\/li>\n<li>l\u00e4gger till ett klassattribut<\/li>\n<li>ers\u00e4tter det ursprungliga bildelementet med stycket,<\/li>\n<li>och l\u00e4gger till bilden som ett underordnat element<\/li>\n<\/ul>\n<p>Och eftersom vi har baserat dokumentobjektet i metoden beh\u00f6ver vi inte returnera n\u00e5got.<\/p>\n<p>Den slutliga versionen av den ursprungliga funktionen b\u00f6r se <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\">ut s\u00e5 h\u00e4r<\/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>Och din utdata ska se ut som bilden ovan. Kom dock ih\u00e5g; du m\u00e5ste returnera resultaten av dokumentinstansen till WordPress, s\u00e5 att den \u00e5terger HTML-koden ordentligt. Och det \u00e4r vad <strong>saveHTML-<\/strong> funktionen g\u00f6r i koden ovan.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kolla in hur du anv\u00e4nder DOMDocument f\u00f6r att \u00e4ndra HTML-element innan du renderar dem.<\/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":[848,724,868],"tags":[1173],"class_list":["post-229764","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-handledningar","category-utvecklaren","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/229764","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=229764"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/229764\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/221217"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=229764"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=229764"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=229764"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}