{"id":228212,"date":"2022-10-13T20:33:00","date_gmt":"2022-10-13T17:33:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228212"},"modified":"2022-11-09T01:18:45","modified_gmt":"2022-11-08T22:18:45","slug":"creacion-de-un-control-de-seleccion-de-enlaces-cmb2-personalizado-para-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/creacion-de-un-control-de-seleccion-de-enlaces-cmb2-personalizado-para-wordpress\/","title":{"rendered":"Creaci\u00f3n de un control de selecci\u00f3n de enlaces CMB2 personalizado para WordPress"},"content":{"rendered":"\n<p>En este tutorial, ver\u00e9 c\u00f3mo puede crear un control personalizado para ampliar la funcionalidad de <a href=\"https:\/\/wordpress.org\/plugins\/cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">CMB2<\/a> (Custom Meta Boxes 2) de <a href=\"https:\/\/webdevstudios.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WebDevStudios<\/a>.<\/p>\n<p>Desarrollo sitios web (y aplicaciones web) con <a href=\"https:\/\/wordpress.org\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">WordPress<\/a> CMS (Sistema de gesti\u00f3n de contenido), y cuando llega un nuevo proyecto, puede garantizar que habr\u00e1 un requisito para m\u00ed para desarrollar &#8216;Meta Boxes personalizados&#8217; para permitir que el usuario tenga un control preciso sobre el contenido y el dise\u00f1o de los sitios.<\/p>\n<p>Detallar\u00e9 c\u00f3mo constru\u00ed el Selector de enlaces de control <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">CMB2 para CMB2<\/a> (disponible en todos los buenos repositorios de complementos de WordPress). Una captura de pantalla de la cual se puede ver a continuaci\u00f3n.<\/p>\n<p>El control CMB2 &#8216;Link Picker&#8217; en acci\u00f3n<\/p>\n<p>El Selector de enlaces activa el cuadro de di\u00e1logo integrado de WordPress &#8216;Insertar\/editar enlace&#8217; cuando hace clic en el bot\u00f3n &#8216;Elegir&#8217;. Esto se puede ver en la siguiente captura de pantalla:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b39277e2.png\" alt=\"Creaci\u00f3n de un control de selecci\u00f3n de enlaces CMB2 personalizado para WordPress\" \/>Presionar el bot\u00f3n le permite elegir entre un enlace (o agregar uno propio)<\/p>\n<p>Estoy seguro de que estar\u00e1 de acuerdo en que tener un control como este es incre\u00edblemente \u00fatil si desea que los editores de su sitio puedan agregar un enlace y tambi\u00e9n buscar en WordPress sus enlaces internos, en lugar de tener que cortar y pegar los enlaces en un enlace. campo.<\/p>\n<h2>Introducci\u00f3n \/ Historia<\/h2>\n<p>Para aquellos que no lo saben, un meta cuadro vive en la pantalla del editor de una publicaci\u00f3n de WordPress, y probablemente contendr\u00e1 varios controles de formulario (cuadros de texto, listas desplegables, casillas de verificaci\u00f3n, etc.). Estos controles permiten a los usuarios de su sitio web cambiar f\u00e1cilmente un texto personalizado o una funcionalidad en el sitio.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b39277e2.png\" alt=\"Creaci\u00f3n de un control de selecci\u00f3n de enlaces CMB2 personalizado para WordPress\" \/><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b3a6c2f7.png\" alt=\"Creaci\u00f3n de un control de selecci\u00f3n de enlaces CMB2 personalizado para WordPress\" \/>Un ejemplo de un cuadro meta con varios controles de formulario<\/p>\n<p>WordPress le permite crear metacuadros usando funciones (como <code>[add_meta_box](https:\/\/developer.wordpress.org\/reference\/functions\/add_meta_box\/)<\/code>), pero crear metacuadros de esta manera puede ser un proceso largo, con mucha repetici\u00f3n de c\u00f3digo (especialmente si desea usar los mismos controles de formulario en varios proyectos).<\/p>\n<h2>\u00bfPor qu\u00e9 CMB2?<\/h2>\n<p>Algunos de ustedes pueden haber o\u00eddo hablar de <a href=\"https:\/\/www.advancedcustomfields.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Advanced Custom Fields<\/a> (ACF) que proporciona una GUI (interfaz gr\u00e1fica de usuario) que le permite crear metaboxes directamente con WordPress.<\/p>\n<p>En mi opini\u00f3n, ACF <strong>no es una gran herramienta<\/strong> para ninguna soluci\u00f3n web escalable. El complemento depende demasiado de los datos almacenados en la base de datos. Esto causa dolor al implementar cambios en un sitio, ya que no puede simplemente subir su c\u00f3digo y ver los cambios al instante. En su lugar, debe volver a hacer el trabajo en los diversos entornos de implementaci\u00f3n (escenario, en vivo, etc.). As\u00ed que necesit\u00e1bamos una soluci\u00f3n que nos permitiera crear metaboxes program\u00e1ticamente. Introduzca CMB2.<\/p>\n<p>Antes de adoptar CMB2, anteriormente us\u00e1bamos <a href=\"https:\/\/github.com\/humanmade\/Custom-Meta-Boxes\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">HM Custom Meta Boxes<\/a> de esos encantadores humanos en <a href=\"https:\/\/hmn.md\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Human Made<\/a> (que comenz\u00f3 como una bifurcaci\u00f3n del precursor de WebDevStudio para CMB2, &#8216;Custom Meta Boxes&#8217;).<\/p>\n<p>Nos encantaban los metaboxes personalizados de HM, y con los fragmentos de c\u00f3digo m\u00e1s simples, \u00a1pod\u00edamos crear r\u00e1pidamente metaboxes personalizados para hacer casi cualquier cosa!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-169316-61e80b3c08039.png\" alt=\"Creaci\u00f3n de un control de selecci\u00f3n de enlaces CMB2 personalizado para WordPress\" \/>Ejemplo de marcado de metaboxes personalizados de HM (este es el marcado para el metabox de Instagram en la primera captura de pantalla)<\/p>\n<p>Entonces, \u00bfpor qu\u00e9 cambiar a CMB2? Bueno, HM Custom Meta Boxes lamentablemente no estaba recibiendo mucho cari\u00f1o (habl\u00e9 con su desarrollador principal y \u00e9l es un hombre muy, muy ocupado), mientras que CMB2 avanzaba con nuevas caracter\u00edsticas, nuevos controles y hab\u00eda ganado terreno. en la comunidad de WordPress con muchas personas que lo adoptan y lanzan complementos para ampliarlo (incluidas varias de nuestras agencias asociadas).<\/p>\n<p>Finalmente, como se habr\u00e1 dado cuenta, trabajar con CMB2 es tan incre\u00edblemente simple como nos hab\u00edamos acostumbrado, ya que ambas plataformas comparten un ancestro com\u00fan.<\/p>\n<h2>Tutorial<\/h2>\n<p>Antes de comenzar, todos tienen su propio conjunto de ideales sobre c\u00f3mo crear un complemento de WordPress, y he probado algunos, sin embargo, el 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\">Composici\u00f3n ra\u00edz en WordPress<\/a> &#8216; de Tom J Nowell, cambi\u00f3 por completo mi forma de trabajar. Encuentro su enfoque limpio, simple, y hace que el mantenimiento futuro de cualquier complemento sea pan comido. Si toma la <a href=\"https:\/\/wordpress.org\/plugins\/link-picker-for-cmb2\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">fuente del complemento Link Picker for CMB2<\/a>, puede ver los m\u00e9todos que ense\u00f1a en la pr\u00e1ctica.<\/p>\n<h3>Construyendo el formulario<\/h3>\n<p>Para crear el formulario que muestra el Selector de enlaces, lo primero que debemos hacer es engancharnos a la <code>cmb2_render_[control_name]<\/code>acci\u00f3n. Como he llamado a este control &#8216;link_picker&#8217;, podemos completar el gancho as\u00ed:<\/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 aquellos de ustedes que realmente no entienden el <code>add_action<\/code>gancho, funciona de la siguiente manera:<\/p>\n<ol>\n<li>El primer argumento <code>cmb2_render_link_picker<\/code>es el nombre del gancho al que queremos engancharnos.<\/li>\n<li>El segundo argumento <code>array( $this, 'cmb2_render_link_picker' )<\/code>es la funci\u00f3n que queremos llamar cuando se ejecuta este gancho. Tenga en cuenta que estoy envolviendo esto en una matriz, <code>$this<\/code>como el primer par\u00e1metro, porque estoy llamando a la funci\u00f3n dentro de una clase. Si no est\u00e1 trabajando con clases, puede usar simplemente el nombre de la funci\u00f3n <code>cmb2_render_link_picker<\/code>.<\/li>\n<li>El <code>10<\/code>, es el orden en que queremos que se active la funci\u00f3n (cuanto menor sea el n\u00famero, antes se activar\u00e1 cuando se llame a la acci\u00f3n).<\/li>\n<li>El <code>5<\/code>es la cantidad de par\u00e1metros que se pasar\u00e1n a la funci\u00f3n que estoy llamando (esto quedar\u00e1 claro en breve).<\/li>\n<\/ol>\n<p>A continuaci\u00f3n, creamos la funci\u00f3n que representar\u00e1 el formulario:<\/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>He dejado el &#8216;DocBlock&#8217; en el c\u00f3digo anterior que describe lo que <code>cmb2_render_link_picker()<\/code>hace cada uno de los par\u00e1metros pasados \u200b\u200ba la funci\u00f3n.<\/p>\n<p>Tenga en cuenta que mi funci\u00f3n comienza con la <code>public<\/code>declaraci\u00f3n. Esto nuevamente se debe a que estoy trabajando dentro de una clase. Si no est\u00e1 trabajando con clases, puede omitir esto.<\/p>\n<p>El valor de este campo se pasa a la funci\u00f3n a trav\u00e9s del <code>$value<\/code>par\u00e1metro. En el caso de este campo, pasaremos a trav\u00e9s de una matriz, ya que nuestro control tiene tres elementos separados:<\/p>\n<ul>\n<li>El texto<\/li>\n<li>la direcci\u00f3n URL<\/li>\n<li>Si el enlace se abre en una nueva ventana (o no)<\/li>\n<\/ul>\n<p>Debido a <code>$value<\/code>que no siempre est\u00e1 configurado (por ejemplo, la primera vez que se representa el control), debemos inicializarlo con algunos valores predeterminados. Hacemos esto con el siguiente bit 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>Entonces podemos ponernos a trabajar en la representaci\u00f3n del formulario. Aqu\u00ed hay un ejemplo del primer control 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>\u00a1Uf! Eso se ve un poco desordenado, \u00bfno? Vamos a desglosarlo, l\u00ednea por l\u00ednea:<\/p>\n<ol>\n<li>La etiqueta del p\u00e1rrafo de apertura.<\/li>\n<li>La etiqueta de apertura del control, pero con el <code>for<\/code>atributo establecido autom\u00e1ticamente por el <code>$field_type_object<\/code> <code>_id<\/code>par\u00e1metro. Esto generar\u00e1 autom\u00e1ticamente una ID para el control cuando se represente.<\/li>\n<li>El texto de nuestra etiqueta, creado con el texto de la matriz de opciones de controles (o recurre a la palabra &#8216;Texto&#8217;).<\/li>\n<li>La etiqueta de la etiqueta de cierre<\/li>\n<li>La etiqueta del p\u00e1rrafo de cierre.<\/li>\n<li>Iniciar declaraci\u00f3n de PHP<\/li>\n<li>Use un control de entrada (parte del <code>$field_type_object<\/code>para crear una entrada de formulario (el tipo predeterminado ser\u00e1 texto).<\/li>\n<li>Inicie la matriz de par\u00e1metros.<\/li>\n<li>Establece la clase de la entrada.<\/li>\n<li>Establezca el nombre de la entrada, nuevamente usando el <code>$field_type_object<\/code>ayudante.<\/li>\n<li>Establezca la ID de la entrada en la misma ID que se configur\u00f3 en la etiqueta.<\/li>\n<li>Obtenga el valor de <code>$value<\/code>, ya que se trata de una matriz, queremos la clave de &#8216;texto&#8217; para este control.<\/li>\n<li>Cierra la matriz.<\/li>\n<li>Cierra la funci\u00f3n de entrada.<\/li>\n<li>Cierra la declaraci\u00f3n de PHP.<\/li>\n<\/ol>\n<p>El marcado del campo de formulario de URL es muy similar, solo que para usar tipos de entrada HTML5 podemos establecer un par\u00e1metro adicional de &#8216;tipo&#8217; en &#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 un men\u00fa desplegable. El marcado es muy 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>Tenga en cuenta que la <code>$field_type_object<\/code>funci\u00f3n que estamos usando es <code>select<\/code>generar un men\u00fa desplegable. Tambi\u00e9n tenga en cuenta que en la l\u00ednea 6 tenemos un nuevo atributo de <code>options<\/code>. En esto estamos pasando una cadena de &#8216;opciones&#8217;. Esto se genera antes de este control as\u00ed:<\/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>Luego, todo lo que tenemos que hacer es envolverlo en algunos <code>&lt;div&gt;<\/code>y tenemos nuestro control completamente 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>\u00a1Y eso es! \u00a1Hemos hecho nuestro control! CMB2 maneja autom\u00e1ticamente todos los datos que queremos guardar, as\u00ed que no hay nada que hacer all\u00ed.<\/p>\n<h3>Estilos<\/h3>\n<p>La captura de pantalla del control que estamos creando (cerca de la parte superior de esta publicaci\u00f3n) tiene algunos estilos personalizados aplicados, por lo que se muestra en l\u00ednea. No entrar\u00e9 en c\u00f3mo dise\u00f1ar el formulario hoy, pero si tiene curiosidad, puede <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/developers\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">descargar el complemento y ver la fuente<\/a>.<\/p>\n<h3>Hacer que el control sea repetible<\/h3>\n<p>Para aquellos de ustedes que quieran avanzar un poco m\u00e1s, pueden hacer que el control funcione con las regiones repetibles de CMB2. Para hacer eso, necesita hacer un poco de mapeo de matriz. Para hacer eso, use el siguiente c\u00f3digo:<\/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>Elegir un enlace<\/h2>\n<p>Por supuesto, el objetivo del selector de enlaces es integrarse en la funci\u00f3n de selecci\u00f3n de enlaces de WordPress, haciendo que aparezca la pantalla de di\u00e1logo &#8216;Insertar\/editar enlace&#8217; cuando se hace clic en el bot\u00f3n &#8216;Elegir&#8217;.<\/p>\n<p>Para que esto suceda, confiamos en gran medida en JavaScript. En particular, estoy usando <a href=\"https:\/\/jquery.com\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">jQuery<\/a> para hacer que las cosas sucedan.<\/p>\n<p>Antes de mostrarle el JavaScript que inicia el cuadro de di\u00e1logo, primero debemos poner en cola el propio JavaScript interno de WordPress, que precargar\u00e1 los modales y las bibliotecas de las que depende nuestro c\u00f3digo. Eso se parece un poco a esto:<\/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 puede ver, muchas de las bibliotecas internas de WordPress dependen de jQuery para cargar la ventana emergente, por lo que tiene sentido que nuestro activador de ventana emergente haga lo mismo. Esto se hace a trav\u00e9s del <code>\/js\/plugin.js<\/code>que se carga en la l\u00ednea 10 del ejemplo anterior.<\/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 las clases que envolvimos en nuestros controles de formulario, el JavaScript apunta a los controles y empuja el resultado seleccionado desde la ventana emergente del selector de enlaces a los campos de control relevantes.<\/p>\n<h2>Uso del control<\/h2>\n<p>Entonces, despu\u00e9s de leer el tutorial anterior, y posiblemente despu\u00e9s de <a href=\"https:\/\/en-gb.wordpress.org\/plugins\/link-picker-for-cmb2\/developers\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">revisar el c\u00f3digo fuente<\/a> del complemento <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>, o simplemente descargar mi versi\u00f3n, es posible que ahora se pregunte c\u00f3mo usar la cosa con CMB2. Bueno, no podr\u00eda ser m\u00e1s 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\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/wholesomecode.ltd\" class=\"external external_icon\">wholesomecode.ltd<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>En este tutorial, ver\u00e9 c\u00f3mo puede crear un control personalizado para ampliar la funcionalidad de CMB2 (Custom Meta Boxes 2) por WebDevStudios. Desarrollo sitios web (y aplicaciones web&#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":[892,716,840,861],"tags":[1172],"class_list":["post-228212","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-desarrollador","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/228212","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=228212"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/228212\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/224127"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=228212"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=228212"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=228212"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}