{"id":228048,"date":"2022-10-13T20:13:00","date_gmt":"2022-10-13T17:13:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228048"},"modified":"2022-11-09T00:26:11","modified_gmt":"2022-11-08T21:26:11","slug":"skapa-en-anpassad-cmb2-laenkvaeljarkontroll-foer-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/skapa-en-anpassad-cmb2-laenkvaeljarkontroll-foer-wordpress\/","title":{"rendered":"Skapa en anpassad CMB2-l\u00e4nkv\u00e4ljarkontroll f\u00f6r WordPress"},"content":{"rendered":"\n<p>I den h\u00e4r handledningen kommer jag att titta p\u00e5 hur du kan skapa en anpassad kontroll f\u00f6r att ut\u00f6ka funktionaliteten f\u00f6r <a href=\"https:\/\/wordpress.org\/plugins\/cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">CMB2<\/a> (Custom Meta Boxes 2) av <a href=\"https:\/\/webdevstudios.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WebDevStudios<\/a>.<\/p>\n<p>Jag utvecklar webbplatser (och webbapplikationer) med <a href=\"https:\/\/wordpress.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress<\/a> CMS (Content Management System), och n\u00e4r ett nytt projekt landar kan du garantera att det kommer att finnas ett krav p\u00e5 mig att utveckla &#8217;Custom Meta Boxes&#8217; f\u00f6r att l\u00e5ta anv\u00e4ndaren ha fin kontroll \u00f6ver webbplatsens inneh\u00e5ll och layout.<\/p>\n<p>Jag kommer att beskriva hur jag byggde CMB2-kontrollen <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Link Picker f\u00f6r CMB2<\/a> (tillg\u00e4nglig fr\u00e5n alla bra WordPress-pluginf\u00f6rr\u00e5d). En sk\u00e4rmdump som kan ses nedan.<\/p>\n<p>&quot;Link Picker&quot; CMB2-kontrollen i aktion<\/p>\n<p>L\u00e4nkv\u00e4ljaren aktiverar den inbyggda WordPress-dialogrutan &quot;Infoga\/redigera l\u00e4nk&quot; n\u00e4r du klickar p\u00e5 knappen &quot;V\u00e4lj&quot;. Detta kan ses p\u00e5 sk\u00e4rmdumpen nedan:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b39277e2.png\" alt=\"Skapa en anpassad CMB2-l\u00e4nkv\u00e4ljarkontroll f\u00f6r WordPress\" \/>Genom att trycka p\u00e5 knappen kan du v\u00e4lja fr\u00e5n en l\u00e4nk (eller l\u00e4gga till din egen)<\/p>\n<p>Jag \u00e4r s\u00e4ker p\u00e5 att du h\u00e5ller med om att det \u00e4r otroligt praktiskt att ha en kontroll som denna om du vill ge dina webbplatsredigerare m\u00f6jligheten att l\u00e4gga till en l\u00e4nk och \u00e4ven s\u00f6ka i WordPress efter dess interna l\u00e4nkar, ist\u00e4llet f\u00f6r att de m\u00e5ste klippa och klistra in l\u00e4nkarna i en l\u00e4nk f\u00e4lt.<\/p>\n<h2>Introduktion \/ Historia<\/h2>\n<p>F\u00f6r de som inte k\u00e4nner till, finns en metabox p\u00e5 redigeringssk\u00e4rmen f\u00f6r ett WordPress-inl\u00e4gg och kommer sannolikt att inneh\u00e5lla olika formul\u00e4rkontroller (textrutor, rullgardinslistor, kryssrutor etc&#8230;). Dessa kontroller l\u00e5ter dina webbplatsanv\u00e4ndare enkelt kunna \u00e4ndra en anpassad text eller funktionalitet p\u00e5 webbplatsen.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b39277e2.png\" alt=\"Skapa en anpassad CMB2-l\u00e4nkv\u00e4ljarkontroll f\u00f6r WordPress\" \/><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b3a6c2f7.png\" alt=\"Skapa en anpassad CMB2-l\u00e4nkv\u00e4ljarkontroll f\u00f6r WordPress\" \/>Ett exempel p\u00e5 en metabox med olika formul\u00e4rkontroller<\/p>\n<p>WordPress l\u00e5ter dig skapa metaboxar med hj\u00e4lp av funktioner (som t.ex. <code>[add_meta_box](https:\/\/developer.wordpress.org\/reference\/functions\/add_meta_box\/)<\/code>), men att skapa metaboxar p\u00e5 detta s\u00e4tt kan vara en l\u00e5ng process, med mycket kodupprepning (speciellt om du vill anv\u00e4nda samma formul\u00e4rkontroller i flera projekt).<\/p>\n<h2>Varf\u00f6r CMB2?<\/h2>\n<p>N\u00e5gra av er kanske har h\u00f6rt talas om <a href=\"https:\/\/www.advancedcustomfields.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Advanced Custom Fields<\/a> (ACF) som tillhandah\u00e5ller ett GUI (Graphical User Interface) som l\u00e5ter dig skapa metaboxar direkt med WordPress.<\/p>\n<p>ACF enligt mig \u00e4r <strong>inte ett bra verktyg<\/strong> f\u00f6r n\u00e5gon webbl\u00f6sning som skalas. Plugin-programmet \u00e4r f\u00f6r mycket beroende av att data lagras i databasen. Detta orsakar sm\u00e4rta n\u00e4r du distribuerar \u00e4ndringar p\u00e5 en webbplats, eftersom du inte bara kan trycka upp din kod och se \u00e4ndringarna direkt. Ist\u00e4llet m\u00e5ste du g\u00f6ra om arbetet p\u00e5 de olika distributionsmilj\u00f6erna (staging, live, et al). S\u00e5 vi beh\u00f6vde en l\u00f6sning som l\u00e5ter oss skapa metaboxar programm\u00e4ssigt. Ange CMB2.<\/p>\n<p>Innan vi antog CMB2 anv\u00e4nde vi tidigare <a href=\"https:\/\/github.com\/humanmade\/Custom-Meta-Boxes\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">HM Custom Meta Boxes<\/a> fr\u00e5n de d\u00e4r underbara m\u00e4nniskorna p\u00e5 <a href=\"https:\/\/hmn.md\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Human Made<\/a> (som b\u00f6rjade som en gaffel till WebDevStudios f\u00f6reg\u00e5ngare till CMB2,).<\/p>\n<p>Vi \u00e4lskade HM Custom Meta Boxes, och med de enklaste kodavsnitten kunde vi snabbt skapa anpassade Meta Boxes f\u00f6r att g\u00f6ra i stort sett vad som helst!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b3c08039.png\" alt=\"Skapa en anpassad CMB2-l\u00e4nkv\u00e4ljarkontroll f\u00f6r WordPress\" \/>HM Custom Meta Boxes Markup Exempel (detta \u00e4r markeringen f\u00f6r Instagram Meta Box i den f\u00f6rsta sk\u00e4rmdumpen)<\/p>\n<p>S\u00e5 varf\u00f6r flytta till CMB2? Tja, HM Custom Meta Boxes fick tyv\u00e4rr inte s\u00e5 mycket k\u00e4rlek (jag pratade med dess huvudutvecklare och han \u00e4r en v\u00e4ldigt mycket upptagen man), medan CMB2 gick fram\u00e5t med nya funktioner, nya kontroller, och det hade f\u00e5tt dragkraft i WordPress-communityt med m\u00e5nga m\u00e4nniskor som adopterar det och sl\u00e4pper plugins f\u00f6r att ut\u00f6ka det (inklusive flera av v\u00e5ra partnerbyr\u00e5er).<\/p>\n<p>Slutligen, som du kanske har f\u00f6rst\u00e5tt, \u00e4r arbetet med CMB2 lika otroligt enkelt som vi hade vant oss vid, eftersom b\u00e5da plattformarna har en gemensam f\u00f6rfader.<\/p>\n<h2>Handledning<\/h2>\n<p>Innan vi b\u00f6rjar har alla sina egna ideal om hur man skapar ett WordPress-plugin, och jag har provat en hel del, men handledningen om &#8217; <a href=\"https:\/\/tomjn.com\/2015\/06\/24\/root-composition-in-wordpress-plugins\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Root Composition in WordPress<\/a> &#8217; av Tom J Nowell f\u00f6r\u00e4ndrade helt hur jag arbetar. Jag tycker att dess tillv\u00e4gag\u00e5ngss\u00e4tt \u00e4r rent, enkelt, och det g\u00f6r framtida underh\u00e5ll av alla plugin till en enkel sak. Om du tar tag i <a href=\"https:\/\/wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">k\u00e4llan till Link Picker for CMB2-<\/a> plugin, kan du se metoderna han l\u00e4r ut i praktiken.<\/p>\n<h3>Bygga formul\u00e4ret<\/h3>\n<p>F\u00f6r att bygga formen som \u00e5terger L\u00e4nkv\u00e4ljaren \u00e4r det f\u00f6rsta vi beh\u00f6ver g\u00f6ra att koppla in i <code>cmb2_render_[control_name]<\/code>handlingen. Som jag har kallat den h\u00e4r kontrollen &#8217;link_picker&#8217; kan vi slutf\u00f6ra kroken s\u00e5 h\u00e4r:<\/p>\n<pre><code>&lt;?php\nadd_action( 'cmb2_render_link_picker', array( $this, 'cmb2_render_link_picker' ), 10, 5 );\n`\n<\/code><\/pre>\n<p>F\u00f6r er som inte riktigt f\u00f6rst\u00e5r <code>add_action<\/code>kroken fungerar det som f\u00f6ljer:<\/p>\n<ol>\n<li>Det f\u00f6rsta argumentet <code>cmb2_render_link_picker<\/code>\u00e4r namnet p\u00e5 kroken vi vill haka p\u00e5.<\/li>\n<li>Det andra argumentet <code>array( $this, 'cmb2_render_link_picker' )<\/code>\u00e4r funktionen vi vill anropa n\u00e4r denna hook k\u00f6rs. Observera att jag lindar in detta i en array, med <code>$this<\/code>som den f\u00f6rsta parametern, eftersom jag anropar funktionen i en klass. Om du inte arbetar med klasser kan du bara anv\u00e4nda funktionsnamnet <code>cmb2_render_link_picker<\/code>.<br \/>\n3., \u00e4r den <code>10<\/code>ordning som vi vill att funktionen ska aktiveras (ju l\u00e4gre nummer, desto snabbare aktiveras den n\u00e4r \u00e5tg\u00e4rden anropas).<\/li>\n<li>Det <code>5<\/code>\u00e4r m\u00e4ngden parametrar som kommer att skickas till funktionen som jag anropar (detta kommer att bli klart inom kort).<\/li>\n<\/ol>\n<p>D\u00e4refter skapar vi funktionen som renderar formul\u00e4ret:<\/p>\n<pre><code>&lt;?php\n\npublic function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object) {\n\u2026\n}\n`\n<\/code><\/pre>\n<p>Jag har l\u00e4mnat &quot;DocBlock&quot; i koden ovan som beskriver vad var och en av parametrarna som skickas in i <code>cmb2_render_link_picker()<\/code>funktionen g\u00f6r.<\/p>\n<p>Observera att min funktion b\u00f6rjar med <code>public<\/code>deklarationen. Detta beror \u00e5terigen p\u00e5 att jag arbetar inom en klass. Om du inte arbetar med klasser kan du utel\u00e4mna detta.<\/p>\n<p>V\u00e4rdet f\u00f6r detta f\u00e4lt skickas till funktionen via <code>$value<\/code>parametern. N\u00e4r det g\u00e4ller detta f\u00e4lt kommer vi att passera genom en array, eftersom v\u00e5r kontroll har tre separata element:<\/p>\n<ul>\n<li>Texten<\/li>\n<li>URL:en<\/li>\n<li>Om l\u00e4nken \u00f6ppnas i ett nytt f\u00f6nster (eller inte)<\/li>\n<\/ul>\n<p>Eftersom den <code>$value<\/code>inte alltid \u00e4r inst\u00e4lld (till exempel f\u00f6rsta g\u00e5ngen kontrollen renderas) m\u00e5ste vi initiera den med n\u00e5gra standardv\u00e4rden. Vi g\u00f6r detta med f\u00f6ljande kodbit:<\/p>\n<pre><code>&lt;?php\n$value = wp_parse_args( \n    $value, \n    array(\n        'text'  =&gt; '',\n        'url'   =&gt; '',\n        'blank' =&gt; 'false',) );\n<\/code><\/pre>\n<p>Vi kan sedan b\u00f6rja arbeta med att rendera formul\u00e4ret. H\u00e4r \u00e4r ett exempel p\u00e5 den f\u00f6rsta textinmatningskontrollen:<\/p>\n<pre><code>&lt;p&gt;\n    &lt;label for=\"&lt;?php echo $field_type_object-&gt;_id( '_text' ); ?&gt;'\"&gt;\n        &lt;?php echo esc_html( $field_type_object-&gt;_text( 'link_picker_text', 'Text') ); ?&gt;\n    &lt;\/label&gt;\n&lt;\/p&gt;\n&lt;?php \n    echo $field_type_object-&gt;input( \n            array(\n            'class' =&gt; 'cmb_text',\n            'name'  =&gt; $field_type_object-&gt;_name( '[text]' ),\n            'id'    =&gt; $field_type_object-&gt;_id( '_text' ),\n            'value' =&gt; $value['text'],) ); \n?&gt;\n<\/code><\/pre>\n<p>Puh! Det ser lite r\u00f6rigt ut, eller hur? L\u00e5t oss dela upp det rad f\u00f6r rad:<\/p>\n<ol>\n<li>Den inledande stycketaggen.<\/li>\n<li>Inledande etiketttagg f\u00f6r kontrollen, men med <code>for<\/code>attributet automatiskt inst\u00e4llt av <code>$field_type_object<\/code> <code>_id<\/code>parametern. Detta genererar automatiskt ett ID f\u00f6r kontrollen n\u00e4r den renderas.<\/li>\n<li>Texten p\u00e5 v\u00e5r etikett, byggd med text fr\u00e5n kontrollalternativen (eller faller tillbaka till ordet &quot;Text&quot;).<\/li>\n<li>Den avslutande etiketten<\/li>\n<li>Den avslutande stycketaggen.<\/li>\n<li>Starta PHP-deklarationen<\/li>\n<li>Anv\u00e4nd en inmatningskontroll (en del av f\u00f6r <code>$field_type_object<\/code>att skapa en formul\u00e4rinmatning (standardtyp kommer att vara text).<\/li>\n<li>Starta upps\u00e4ttningen av parametrar<\/li>\n<li>St\u00e4ll in klassen f\u00f6r ing\u00e5ngen.<\/li>\n<li>St\u00e4ll in namnet p\u00e5 ing\u00e5ngen, \u00e5terigen med hj\u00e4lp av <code>$field_type_object<\/code>hj\u00e4lparen.<\/li>\n<li>St\u00e4ll in ID f\u00f6r ing\u00e5ngen till samma ID som sattes p\u00e5 etiketttaggen.<\/li>\n<li>F\u00e5 v\u00e4rdet fr\u00e5n <code>$value<\/code>, eftersom detta \u00e4r en array, vi vill ha &quot;text&quot;-nyckeln f\u00f6r denna kontroll.<\/li>\n<li>St\u00e4ng arrayen.<\/li>\n<li>St\u00e4ng inmatningsfunktionen.<\/li>\n<li>St\u00e4ng PHP-deklarationen.<\/li>\n<\/ol>\n<p>Webbadressens formul\u00e4rf\u00e4ltsmarkering \u00e4r ungef\u00e4r densamma, bara f\u00f6r att anv\u00e4nda HTML5-inmatningstyper kan vi st\u00e4lla in en extra parameter &#8217;typ&#8217; till &#8217;url&#8217;:<\/p>\n<pre><code>&lt;?php \n\u2026\n'type'  =&gt; 'url',\n\u2026\n<\/code><\/pre>\n<p>Slutligen vill vi implementera en dropdown. Markeringen \u00e4r mycket bekant:<\/p>\n<pre><code>&lt;?php\necho $field_type_object-&gt;select( \n    array(\n        'class'   =&gt; 'cmb_dropdown',\n        'name'    =&gt; $field_type_object-&gt;_name( '[blank]' ),\n        'id'      =&gt; $field_type_object-&gt;_id( '_blank' ),\n        'options' =&gt; $blank_options,) );\n<\/code><\/pre>\n<p>Observera att <code>$field_type_object<\/code>funktionen vi anv\u00e4nder \u00e4r <code>select<\/code>att generera en rullgardinsmeny. Observera ocks\u00e5 att p\u00e5 rad 6 har vi ett nytt attribut f\u00f6r <code>options<\/code>. In i detta skickar vi en rad &quot;alternativ&quot;. Detta genereras f\u00f6re denna kontroll s\u00e5 h\u00e4r:<\/p>\n<pre><code>&lt;?php \n$blank_options = '';\n$blank_options .= '&lt;option value=\"false\" '. selected( $value['blank'], 'false', false) .'&gt;Opens in same&lt;\/option&gt;';\n$blank_options .= '&lt;option value=\"true\" '. selected( $value['blank'], 'true', false) .'&gt;Opens in new&lt;\/option&gt;';\n<\/code><\/pre>\n<p>Sedan beh\u00f6ver vi bara linda in det i n\u00e5gra <code>&lt;div&gt;<\/code>och vi har v\u00e5r fulla kontroll:<\/p>\n<pre><code>&lt;?php\npublic function cmb2_render_link_picker( $field, $value, $object_id, $object_type, $field_type_object) {\n    $value = wp_parse_args( $value, array(\n        'text'  =&gt; '',\n        'url'   =&gt; '',\n        'blank' =&gt; 'false',) );\n    $blank_options = '';\n    $blank_options .= '&lt;option value=\"false\" '. selected( $value['blank'], 'false', false) .'&gt;Opens in same&lt;\/option&gt;';\n    $blank_options .= '&lt;option value=\"true\" '. selected( $value['blank'], 'true', false) .'&gt;Opens in new&lt;\/option&gt;';\n    ?&gt;\n    &lt;div class=\"link-picker\"&gt;\n        &lt;div class=\"text\"&gt;\n            &lt;p&gt;\n                &lt;label for=\"&lt;?php echo $field_type_object-&gt;_id( '_text' ); ?&gt;'\"&gt;\n                    &lt;?php echo esc_html( $field_type_object-&gt;_text( 'link_picker_text', 'Text') ); ?&gt;\n                &lt;\/label&gt;\n            &lt;\/p&gt;\n            &lt;?php \n                echo $field_type_object-&gt;input( \n                    array(\n                        'class' =&gt; 'cmb_text',\n                        'name'  =&gt; $field_type_object-&gt;_name( '[text]' ),\n                        'id'    =&gt; $field_type_object-&gt;_id( '_text' ),\n                        'value' =&gt; $value['text'],\n                        'desc'  =&gt; '',) ); \n            ?&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"url\"&gt;\n            &lt;p&gt;\n                &lt;label for=\"&lt;?php echo $field_type_object-&gt;_id( '_url' ); ?&gt;'\"&gt;\n                    &lt;?php echo esc_html( $field_type_object-&gt;_text( 'link_picker_url', 'URL') ); ?&gt;\n                &lt;\/label&gt;\n            &lt;\/p&gt;\n            &lt;?php \n                echo $field_type_object-&gt;input( \n                    array(\n                        'class' =&gt; 'cmb_text_url',\n                        'name'  =&gt; $field_type_object-&gt;_name( '[url]' ),\n                        'id'    =&gt; $field_type_object-&gt;_id( '_url' ),\n                        'value' =&gt; $value['url'],\n                        'type'  =&gt; 'url',\n                        'desc'  =&gt; '',) ); \n            ?&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"blank\"&gt;\n            &lt;p&gt;\n                &lt;label for=\"&lt;?php echo $field_type_object-&gt;_id( '_blank' ); ?&gt;'\"&gt;\n                    &lt;?php echo esc_html( $field_type_object-&gt;_text( 'link_picker_blank', 'Window') ); ?&gt;\n                &lt;\/label&gt;\n            &lt;\/p&gt;\n            &lt;?php \n                echo $field_type_object-&gt;select( \n                    array(\n                        'class'   =&gt; 'cmb_checkbox',\n                        'name'    =&gt; $field_type_object-&gt;_name( '[blank]' ),\n                        'id'      =&gt; $field_type_object-&gt;_id( '_blank' ),\n                        'options' =&gt; $blank_options,\n                        'desc'    =&gt; '',) ); \n            ?&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"choose\"&gt;\n            &lt;p&gt;\n                &lt;label&gt;Choose&lt;\/label&gt;\n            &lt;\/p&gt;\n            &lt;button class=\"dashicons dashicons-admin-links js-insert-link button button-primary\" title=\"&lt;?php esc_html_e( 'Insert Link', 'cmb' ); ?&gt;\"&gt;\n                 &lt;span class=\"screen-reader-text\"&gt;&lt;?php esc_html_e( 'Choose Link', 'cmb' ); ?&gt;&lt;\/span&gt;\n             &lt;\/button&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n    &lt;p class=\"clear\"&gt;\n        &lt;?php echo $field_type_object-&gt;_desc();?&gt;\n    &lt;\/p&gt;\n&lt;?php\n}\n<\/code><\/pre>\n<p>Och det \u00e4r allt! Vi har gjort v\u00e5r kontroll! CMB2 hanterar automatiskt all data vi vill spara, s\u00e5 inget att g\u00f6ra d\u00e4r.<\/p>\n<h3>Stilar<\/h3>\n<p>Sk\u00e4rmdumpen av kontrollen vi skapar (n\u00e4ra toppen av det h\u00e4r inl\u00e4gget) har n\u00e5gra anpassade stilar applicerade p\u00e5 den s\u00e5 att den renderas inline. Jag g\u00e5r inte in p\u00e5 hur man stylar formul\u00e4ret idag, men om du \u00e4r nyfiken kan du <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/developers\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ladda ner plugin och se k\u00e4llan<\/a>.<\/p>\n<h3>G\u00f6r kontrollen repeterbar<\/h3>\n<p>F\u00f6r dig som vill bli lite mer avancerad kan du f\u00e5 kontrollen att fungera med CMB2:s repeterbara regioner. F\u00f6r att g\u00f6ra det m\u00e5ste du g\u00f6ra lite arraymapping. Anv\u00e4nd koden nedan f\u00f6r att g\u00f6ra det:<\/p>\n<pre><code>&lt;?php\n\npublic function cmb2_sanitize_link_picker( $check, $meta_value, $object_id, $field_args, $sanitize_object) {\n\n    if (! is_array( $meta_value) ||! $field_args['repeatable']) {\n        return $check;\n    }\n    foreach ($meta_value as $key =&gt; $val) {\n        $meta_value[ $key ] =  null;\n        if(! empty( $val['url'])) {\n            $meta_value[ $key ] = array_map( 'sanitize_text_field', $val );\n        }\n    }\n    return $meta_value;\n}\npublic function cmb2_types_esc_link_picker( $check, $meta_value, $field_args, $field_object) {\n\n    if (! is_array( $meta_value) ||! $field_args['repeatable']) {\n        return $check;\n    }\n    foreach ($meta_value as $key =&gt; $val) {\n        $meta_value[ $key ] =  null;\n        if(! empty( $val['url'])) {\n            $meta_value[ $key ] = array_map( 'esc_attr', $val );\n        }\n    }\n    return $meta_value;\n}\n<\/code><\/pre>\n<h2>Att v\u00e4lja en l\u00e4nk<\/h2>\n<p>Naturligtvis \u00e4r hela po\u00e4ngen med l\u00e4nkv\u00e4ljaren att integrera i WordPresss egen l\u00e4nkvalsfunktionalitet, vilket g\u00f6r att dialogrutan &#8217;Infoga\/redigera l\u00e4nk&#8217; visas n\u00e4r du klickar p\u00e5 knappen &#8217;V\u00e4lj&#8217;.<\/p>\n<p>F\u00f6r att f\u00e5 detta att h\u00e4nda f\u00f6rlitar vi oss starkt p\u00e5 JavaScript. Jag anv\u00e4nder i synnerhet <a href=\"https:\/\/jquery.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jQuery<\/a> f\u00f6r att f\u00e5 saker att h\u00e4nda.<\/p>\n<p>Innan jag visar dig JavaScriptet som startar dialogrutan m\u00e5ste vi f\u00f6rst st\u00e4lla WordPresss egna interna JavaScript i k\u00f6, som kommer att f\u00f6rinl\u00e4sa modalerna och biblioteken som v\u00e5r kod beror p\u00e5. Det ser ut ungef\u00e4r s\u00e5 h\u00e4r:<\/p>\n<pre><code>&lt;?php\nglobal $post_id;\n\nif (isset( $post_id)) {\n    wp_enqueue_media( array( 'post' =&gt; $post_id) );\n}\n\n$plugin_js_url  = plugins_url( 'js\/plugin.js', ROOT );\nwp_enqueue_script( 'wholesomecode', $plugin_js_url, array( 'jquery', 'jquery-ui-core', 'jquery-ui-draggable', 'jquery-ui-droppable', 'thickbox', 'wpdialogs' ), '1.0.0', true );\n<\/code><\/pre>\n<p>Som du kan se \u00e4r m\u00e5nga av de interna WordPress-biblioteken beroende av jQuery f\u00f6r att ladda popupen, s\u00e5 det \u00e4r vettigt att v\u00e5r popup-utl\u00f6sare g\u00f6r detsamma. Detta g\u00f6rs via den <code>\/js\/plugin.js<\/code>som laddas p\u00e5 rad 10 i exemplet ovan.<\/p>\n<pre><code>jQuery(document).ready(function($) {\n\n    var url   = $('body');\n    var text = $('body');\n    var blank = $('body');\n\n    $('body').on('click', '.js-insert-link', function(event) {\n\n        event.preventDefault? event.preventDefault(): event.returnValue = false;\n        event.stopPropagation();\n\n        url            = $(this).closest('.link-picker').find('input.cmb_text_url ');\n        text           = $(this).closest('.link-picker').find('input.cmb_text ');\n        blank          = $(this).closest('.link-picker').find('input.cmb_checkbox ');\n\n        wpActiveEditor = true;\n        wpLink.open();\n        wpLink.textarea = url;\n\n        return false;\n    });\n\n    $('body').on('click', '#wp-link-cancel, #wp-link-backdrop, #wp-link-close', function(event) {\n\n        wpLink.textarea = url;\n        wpLink.close();\n        event.preventDefault? event.preventDefault(): event.returnValue = false;\n        event.stopPropagation();\n        return false;\n    });\n\n    $('body').on('click', '#wp-link-submit', function(event) {\n        console.log(text)\n        var linkAtts = wpLink.getAttrs();\n\n        linkAtts.text = $('#wp-link-text').val();\n\n        url.val(linkAtts.href);\n\n        if( linkAtts.text != '') {\n            text.val(linkAtts.text);\n        }\n\n        if (linkAtts.target == '_blank') {\n            blank.prop('checked', true);\n        } else {\n            blank.prop('checked', false);\n        }\n\n        wpLink.textarea = url;\n        wpLink.close();\n        event.preventDefault? event.preventDefault(): event.returnValue = false;\n        event.stopPropagation();\n        return false;\n    });\n});\n<\/code><\/pre>\n<p>Genom att anv\u00e4nda klasserna som vi lindade runt v\u00e5ra formul\u00e4rkontroller, riktar JavaScript sig mot kontrollerna och skickar det valda resultatet fr\u00e5n l\u00e4nkv\u00e4ljarens popup-f\u00f6nster till de relevanta kontrollf\u00e4lten.<\/p>\n<h2>Anv\u00e4nda kontrollen<\/h2>\n<p>S\u00e5 efter att ha tittat igenom handledningen ovan, och m\u00f6jligen efter att ha <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/developers\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">granskat k\u00e4llkoden<\/a> f\u00f6r <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Link Picker for CMB2-<\/a> plugin, eller bara laddat ner min version, kanske du nu undrar hur du anv\u00e4nder saken med CMB2. Tja, det kan inte vara enklare:<\/p>\n<pre><code>&lt;?php\nfunction wholesomecode_create_meta_boxes() {\n  $prefix = '_profile_';\n\n    $cmb = new_cmb2_box(\n        array(\n            'id'            =&gt; 'cta',\n            'title'         =&gt; __( 'Call to Action', 'cmb2' ),\n            'object_types'  =&gt; array( 'profile' ),\n            'context'       =&gt; 'normal',\n            'priority'      =&gt; 'low',\n            'show_names'    =&gt; true,) );\n\n    $field1 = $cmb-&gt;add_field( \n        array(\n            'name' =&gt; __( 'Link Picker', 'cmb2' ),\n            'id'   =&gt; $prefix. 'cta_link',\n            'type' =&gt; 'link_picker',) );\n}\nadd_action( 'cmb2_admin_init', 'wholesomecode_create_meta_boxes' );\n<\/code><\/pre>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I den h\u00e4r handledningen kommer jag att titta p\u00e5 hur du kan skapa en anpassad kontroll f\u00f6r att ut\u00f6ka funktionaliteten f\u00f6r CMB2 (Custom Meta Boxes 2) av WebDevStudios. Jag utvecklar webbplatser (och webbapplikationer&#8230;<\/p>\n","protected":false},"author":1,"featured_media":224127,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[848,901,724,868],"tags":[1173],"class_list":["post-228048","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-handledningar","category-koda","category-utvecklaren","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228048","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=228048"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228048\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/224127"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=228048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=228048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=228048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}