{"id":228543,"date":"2022-10-13T20:05:00","date_gmt":"2022-10-13T17:05:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228543"},"modified":"2022-11-09T02:56:45","modified_gmt":"2022-11-08T23:56:45","slug":"criando-um-controle-de-seletor-de-link-cmb2-personalizado-para-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pt-pt\/criando-um-controle-de-seletor-de-link-cmb2-personalizado-para-wordpress\/","title":{"rendered":"Criando um controle de seletor de link CMB2 personalizado para WordPress"},"content":{"rendered":"\n<p>Neste tutorial, veremos como voc\u00ea pode criar um controle personalizado para estender a funcionalidade do <a href=\"https:\/\/wordpress.org\/plugins\/cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">CMB2<\/a> (Custom Meta Boxes 2) do <a href=\"https:\/\/webdevstudios.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WebDevStudios<\/a>.<\/p>\n<p>Eu desenvolvo sites (e aplica\u00e7\u00f5es web) com o <a href=\"https:\/\/wordpress.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress<\/a> CMS (Content Management System), e quando um novo projeto chega voc\u00ea pode garantir que haver\u00e1 um requisito para eu desenvolver &#8216;Custom Meta Boxes&#8217; para permitir que o usu\u00e1rio tenha um bom controle sobre o conte\u00fado e layout dos sites.<\/p>\n<p>Vou detalhar como eu constru\u00ed o controle do CMB2 <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Link Picker para CMB2<\/a> (dispon\u00edvel em todos os bons reposit\u00f3rios de plugins do WordPress). Uma captura de tela da qual pode ser vista abaixo.<\/p>\n<p>O controle CMB2 &#8216;Link Picker&#8217; em a\u00e7\u00e3o<\/p>\n<p>O Link Picker aciona a caixa de di\u00e1logo &#8216;Inserir\/editar link&#8217; do WordPress quando voc\u00ea clica no bot\u00e3o &#8216;Escolher&#8217;. Isso pode ser visto na captura de tela abaixo:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b39277e2.png\" alt=\"Criando um controle de seletor de link CMB2 personalizado para WordPress\" \/>Apertar o bot\u00e3o permite que voc\u00ea escolha um link (ou adicione o seu pr\u00f3prio)<\/p>\n<p>Tenho certeza de que voc\u00ea concordar\u00e1 que ter um controle como esse \u00e9 incrivelmente \u00fatil se voc\u00ea quiser dar aos editores do seu site a capacidade de adicionar um link e tamb\u00e9m pesquisar no WordPress por seus links internos, em vez de recortar e colar os links em um link campo.<\/p>\n<h2>Introdu\u00e7\u00e3o \/ Hist\u00f3ria<\/h2>\n<p>Para quem n\u00e3o sabe, uma meta box fica na tela do editor de uma postagem do WordPress e provavelmente conter\u00e1 v\u00e1rios controles de formul\u00e1rio (caixas de texto, listas suspensas, caixas de sele\u00e7\u00e3o etc\u2026). Esses controles permitem que os usu\u00e1rios do seu site alterem facilmente um texto ou funcionalidade personalizada no site.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b39277e2.png\" alt=\"Criando um controle de seletor de link CMB2 personalizado para WordPress\" \/><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b3a6c2f7.png\" alt=\"Criando um controle de seletor de link CMB2 personalizado para WordPress\" \/>Um exemplo de uma meta box com v\u00e1rios controles de formul\u00e1rio<\/p>\n<p>O WordPress permite criar meta caixas usando fun\u00e7\u00f5es (como <code>[add_meta_box](https:\/\/developer.wordpress.org\/reference\/functions\/add_meta_box\/)<\/code>), mas criar meta caixas dessa maneira pode ser um processo demorado, com muita repeti\u00e7\u00e3o de c\u00f3digo (especialmente se voc\u00ea quiser usar os mesmos controles de formul\u00e1rio em v\u00e1rios projetos).<\/p>\n<h2>Por que CMB2?<\/h2>\n<p>Alguns de voc\u00eas podem ter ouvido falar de <a href=\"https:\/\/www.advancedcustomfields.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Campos Personalizados Avan\u00e7ados<\/a> (ACF), que fornece uma GUI (Interface Gr\u00e1fica do Usu\u00e1rio) que permite criar meta caixas diretamente com o WordPress.<\/p>\n<p>O ACF, na minha opini\u00e3o, <strong>n\u00e3o \u00e9 uma \u00f3tima ferramenta<\/strong> para qualquer solu\u00e7\u00e3o web que seja escal\u00e1vel. O plug-in depende muito dos dados armazenados no banco de dados. Isso causa dor ao implantar altera\u00e7\u00f5es em um site, pois voc\u00ea n\u00e3o pode simplesmente enviar seu c\u00f3digo e ver as altera\u00e7\u00f5es instantaneamente. Em vez disso, voc\u00ea precisa fazer o trabalho novamente nos v\u00e1rios ambientes de implanta\u00e7\u00e3o (staging, live, et al). Ent\u00e3o precis\u00e1vamos de uma solu\u00e7\u00e3o que nos permitisse criar meta boxes programaticamente. Digite CMB2.<\/p>\n<p>Antes de adotarmos o CMB2, anteriormente us\u00e1vamos <a href=\"https:\/\/github.com\/humanmade\/Custom-Meta-Boxes\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">HM Custom Meta Boxes<\/a> daqueles ador\u00e1veis \u200b\u200bhumanos da <a href=\"https:\/\/hmn.md\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Human Made<\/a> (que come\u00e7ou como um fork do precursor do WebDevStudio para o CMB2, &#8216;Custom Meta Boxes&#8217;).<\/p>\n<p>Adoramos HM Custom Meta Boxes e, com os mais simples trechos de c\u00f3digo, poder\u00edamos criar rapidamente Meta Boxes personalizadas para fazer praticamente qualquer coisa!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b3c08039.png\" alt=\"Criando um controle de seletor de link CMB2 personalizado para WordPress\" \/>HM Custom Meta Boxes Markup Example (esta \u00e9 a marca\u00e7\u00e3o para o Instagram Meta Box na primeira captura de tela)<\/p>\n<p>Ent\u00e3o, por que a mudan\u00e7a para o CMB2? Bem, o HM Custom Meta Boxes infelizmente n\u00e3o estava recebendo muito amor (falei com seu desenvolvedor l\u00edder e ele \u00e9 um homem muito ocupado), enquanto o CMB2 estava avan\u00e7ando com novos recursos, novos controles e ganhou for\u00e7a na comunidade WordPress com muitas pessoas adotando-o e lan\u00e7ando plugins para estend\u00ea-lo (incluindo v\u00e1rias de nossas ag\u00eancias parceiras).<\/p>\n<p>Finalmente, como voc\u00ea deve ter percebido, trabalhar com o CMB2 \u00e9 t\u00e3o incrivelmente simples quanto est\u00e1vamos acostumados, pois ambas as plataformas compartilham um ancestral comum.<\/p>\n<h2>Tutorial<\/h2>\n<p>Antes de come\u00e7armos, todo mundo tem seu pr\u00f3prio conjunto de ideais sobre como criar um plugin WordPress, e eu tentei alguns, no entanto o tutorial sobre &#8216; <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> &#8216; de Tom J Nowell, mudou completamente a maneira como eu trabalho. Acho sua abordagem limpa, simples e facilita a manuten\u00e7\u00e3o futura de qualquer plug-in. Se voc\u00ea pegar a <a href=\"https:\/\/wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fonte do<\/a> plugin Link Picker for CMB2, poder\u00e1 ver os m\u00e9todos que ele ensina na pr\u00e1tica.<\/p>\n<h3>Construindo o formul\u00e1rio<\/h3>\n<p>Para construir o formul\u00e1rio que renderiza o Link Picker, a primeira coisa que precisamos fazer \u00e9 entrar na <code>cmb2_render_[control_name]<\/code>a\u00e7\u00e3o. Como chamei esse controle de &#8216;link_picker&#8217;, podemos completar o gancho assim:<\/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>Para aqueles que n\u00e3o entendem muito bem o <code>add_action<\/code>gancho, funciona da seguinte forma:<\/p>\n<ol>\n<li>O primeiro argumento <code>cmb2_render_link_picker<\/code>\u00e9 o nome do gancho ao qual queremos nos conectar.<\/li>\n<li>O segundo argumento <code>array( $this, 'cmb2_render_link_picker' )<\/code>\u00e9 a fun\u00e7\u00e3o que queremos chamar quando esse gancho for executado. Observe que estou envolvendo isso em uma matriz, com <code>$this<\/code>o primeiro par\u00e2metro, porque estou chamando a fun\u00e7\u00e3o dentro de uma classe. Se voc\u00ea n\u00e3o estiver trabalhando com classes, voc\u00ea pode simplesmente usar o nome da fun\u00e7\u00e3o <code>cmb2_render_link_picker<\/code>.<\/li>\n<li>O <code>10<\/code>, \u00e9 a ordem que queremos que a fun\u00e7\u00e3o dispare (quanto menor o n\u00famero, mais cedo ela dispara quando a a\u00e7\u00e3o \u00e9 chamada).<\/li>\n<li>A <code>5<\/code>\u00e9 a quantidade de par\u00e2metros que ser\u00e3o passados \u200b\u200bpara a fun\u00e7\u00e3o que estou chamando (isso ficar\u00e1 claro em breve).<\/li>\n<\/ol>\n<p>Em seguida, criamos a fun\u00e7\u00e3o que renderizar\u00e1 o formul\u00e1rio:<\/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>Deixei o &#8216;DocBlock&#8217; no c\u00f3digo acima que descreve o que cada um dos par\u00e2metros passados \u200b\u200bpara a <code>cmb2_render_link_picker()<\/code>fun\u00e7\u00e3o faz.<\/p>\n<p>Observe que minha fun\u00e7\u00e3o come\u00e7a com a <code>public<\/code>declara\u00e7\u00e3o. Isso novamente \u00e9 porque estou trabalhando dentro de uma classe. Se voc\u00ea n\u00e3o estiver trabalhando com classes, voc\u00ea pode omitir isso.<\/p>\n<p>O valor deste campo \u00e9 passado para a fun\u00e7\u00e3o atrav\u00e9s do <code>$value<\/code>par\u00e2metro. No caso deste campo, estaremos passando por um array, pois nosso controle possui tr\u00eas elementos separados para ele:<\/p>\n<ul>\n<li>O texto<\/li>\n<li>O URL<\/li>\n<li>Se o link abrir em uma nova janela (ou n\u00e3o)<\/li>\n<\/ul>\n<p>Como o <code>$value<\/code>nem sempre est\u00e1 definido (por exemplo, na primeira vez que o controle \u00e9 renderizado), precisamos inicializ\u00e1-lo com alguns valores padr\u00e3o. Fazemos isso com o seguinte trecho de c\u00f3digo:<\/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>Podemos ent\u00e3o come\u00e7ar a renderizar o formul\u00e1rio. Aqui est\u00e1 um exemplo do primeiro controle de entrada de texto:<\/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>Ufa! Isso parece um pouco confuso, n\u00e3o \u00e9? Vamos detalhar, linha por linha:<\/p>\n<ol>\n<li>A marca do par\u00e1grafo de abertura.<\/li>\n<li>A tag de r\u00f3tulo de abertura para o controle, mas com o <code>for<\/code>atributo definido automaticamente pelo <code>$field_type_object<\/code> <code>_id<\/code>par\u00e2metro. Isso gerar\u00e1 automaticamente um ID para o controle quando ele for renderizado.<\/li>\n<li>O texto do nosso r\u00f3tulo, constru\u00eddo usando o texto do array de op\u00e7\u00f5es de controles (ou volta para a palavra &#8216;Texto&#8217;).<\/li>\n<li>A etiqueta de fechamento<\/li>\n<li>A tag de par\u00e1grafo de fechamento.<\/li>\n<li>Iniciar declara\u00e7\u00e3o PHP<\/li>\n<li>Use um controle de entrada (parte do <code>$field_type_object<\/code>para criar uma entrada de formul\u00e1rio (o tipo padr\u00e3o ser\u00e1 texto).<\/li>\n<li>Inicie a matriz de par\u00e2metros<\/li>\n<li>Defina a classe da entrada.<\/li>\n<li>Defina o nome da entrada, novamente usando o <code>$field_type_object<\/code>auxiliar.<\/li>\n<li>Defina o ID da entrada para o mesmo ID que foi definido na etiqueta da etiqueta.<\/li>\n<li>Obtenha o valor do <code>$value<\/code>, como este \u00e9 um array, queremos a chave &#8216;text&#8217; para este controle.<\/li>\n<li>Feche a matriz.<\/li>\n<li>Feche a fun\u00e7\u00e3o de entrada.<\/li>\n<li>Feche a declara\u00e7\u00e3o PHP.<\/li>\n<\/ol>\n<p>A marca\u00e7\u00e3o do campo de formul\u00e1rio de URL \u00e9 praticamente a mesma, apenas para usar tipos de entrada HTML5, podemos definir um par\u00e2metro adicional de &#8216;tipo&#8217; para &#8216;url&#8217;:<\/p>\n<pre><code>&lt;?php \n\u2026\n'type'  =&gt; 'url',\n\u2026\n<\/code><\/pre>\n<p>Finalmente, queremos implementar uma lista suspensa. A marca\u00e7\u00e3o \u00e9 muito familiar:<\/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>Observe que a <code>$field_type_object<\/code>fun\u00e7\u00e3o que estamos usando \u00e9 <code>select<\/code>gerar uma lista suspensa. Observe tamb\u00e9m que na linha 6 temos um novo atributo de <code>options<\/code>. Para isso, estamos passando uma sequ\u00eancia de &#8216;op\u00e7\u00f5es&#8217;. Isso \u00e9 gerado antes deste controle assim:<\/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>Ent\u00e3o tudo o que precisamos fazer \u00e9 envolv\u00ea-lo em alguns <code>&lt;div&gt;<\/code>&#8216;s e temos nosso controle totalmente renderizado:<\/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>E \u00e9 isso! Fizemos nosso controle! O CMB2 lida automaticamente com todos os dados que queremos salvar, portanto, n\u00e3o h\u00e1 nada a fazer l\u00e1.<\/p>\n<h3>Estilos<\/h3>\n<p>A captura de tela do controle que estamos criando (pr\u00f3ximo ao topo desta postagem) tem alguns estilos personalizados aplicados a ela para que seja renderizada em linha. N\u00e3o vou entrar em como estilizar o formul\u00e1rio hoje, mas se voc\u00ea estiver curioso, pode <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/developers\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">baixar o plugin e visualizar o c\u00f3digo-fonte<\/a>.<\/p>\n<h3>Tornando o controle repet\u00edvel<\/h3>\n<p>Para aqueles que desejam ficar um pouco mais avan\u00e7ados, voc\u00ea pode fazer o controle funcionar com as regi\u00f5es repet\u00edveis do CMB2. Para fazer isso, voc\u00ea precisa fazer um pouco de mapeamento de matriz. Para isso use o c\u00f3digo abaixo:<\/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>Escolhendo um link<\/h2>\n<p>\u00c9 claro que o objetivo do seletor de links \u00e9 integrar-se \u00e0 pr\u00f3pria funcionalidade de escolha de links do WordPress, fazendo com que a tela de di\u00e1logo &#8216;Inserir\/editar link&#8217; apare\u00e7a quando o bot\u00e3o &#8216;Escolher&#8217; for clicado.<\/p>\n<p>Para que isso aconte\u00e7a, dependemos muito do JavaScript. Em particular, estou usando <a href=\"https:\/\/jquery.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jQuery<\/a> para fazer as coisas acontecerem.<\/p>\n<p>Antes de mostrar o JavaScript que inicia a caixa de di\u00e1logo, devemos primeiro enfileirar o pr\u00f3prio JavaScript interno do WordPress, que ir\u00e1 pr\u00e9-carregar os modais e bibliotecas das quais nosso c\u00f3digo depende. Isso se parece um pouco com isso:<\/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>Como voc\u00ea pode ver, muitas das bibliotecas internas do WordPress dependem do jQuery para carregar o pop-up, ent\u00e3o faz sentido que nosso gatilho de pop-up fa\u00e7a o mesmo. Isso \u00e9 feito atrav\u00e9s do <code>\/js\/plugin.js<\/code>que \u00e9 carregado na linha 10 do exemplo acima.<\/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>Usando as classes que envolvemos nossos controles de formul\u00e1rio, o JavaScript direciona os controles e envia o resultado selecionado do pop-up do seletor de links para os campos de controle relevantes.<\/p>\n<h2>Usando o controle<\/h2>\n<p>Ent\u00e3o, depois de ver o tutorial acima, e possivelmente depois <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/developers\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">de revisar o c\u00f3digo-fonte<\/a> do plugin <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>, ou apenas baixar minha vers\u00e3o, voc\u00ea pode estar se perguntando como usar a coisa com o CMB2. Bem, n\u00e3o poderia ser mais f\u00e1cil:<\/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\">Fonte de grava\u00e7\u00e3o:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neste tutorial vou ver como voc\u00ea pode criar um controle customizado para estender a funcionalidade do CMB2 (Custom Meta Boxes 2) do WebDevStudios.<\/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":[898,722,846,867],"tags":[1170],"class_list":["post-228543","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo-2","category-desenvolvedor","category-tutoriais","category-wordpress-8","tag-affiai-pt-pt"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/228543","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/comments?post=228543"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/posts\/228543\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media\/224127"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/media?parent=228543"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/categories?post=228543"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pt-pt\/wp-json\/wp\/v2\/tags?post=228543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}