Agregar opciones personalizadas al cuadro de diálogo wplink

16

Logré agregar una opción de selección personalizada para imágenes con

function attachment_field_credit( $form_fields, $post ) {
    $field_value = get_post_meta( $post->ID, 'first_image', true );
    $isSelected1 = $field_value == '1' ? 'selected ' : '';
    $isSelected2 = $field_value != '1' ? 'selected ' : '';
    $form_fields['first_image'] = array(
        'label' => __( 'Use as first image' ),
        'input' => 'html',
        'html' => "<select name='attachments[{$post->ID}][first_image]' id='attachments[{$post->ID}][first_image]'>
                    <option ".$isSelected1." value='1'>Yes</option>
                    <option ".$isSelected2."  value='2'>No</option>
                   </select>"
    );
    return $form_fields;
}
add_filter( 'attachment_fields_to_edit', 'attachment_field_credit', 10, 2 );

Ahora necesito hacer casi lo mismo para los enlaces. Entonces, si hago clic en Pages -> Add New -> Insert / Edit Linkme sale esto:

ingrese la descripción de la imagen aquí

¿Puedo agregar otro campo de selección de opción para esos enlaces? ¿Como hacer eso?

caramba
fuente

Respuestas:

18

El diálogo HTML proviene WP_Editors::wp_link_dialog()pero no hay ganchos allí.

En su lugar, podríamos usar jQuery para agregar el HTML personalizado al cuadro de diálogo de enlace e intentar anular, por ejemplo wpLink.getAttrs(), el , porque es muy corto ;-)

Ejemplo de demostración:

jQuery( document ).ready( function( $ ) {
    $('#link-options').append( 
        '<div> 
            <label><span>Link Class</span>
            <select name="wpse-link-class" id="wpse_link_class">
                <option value="normal">normal</option>
                <option value="lightbox">lightbox</option>
           </select>
           </label>
       </div>' );

    wpLink.getAttrs = function() {
        wpLink.correctURL();        
        return {
            class:      $( '#wpse_link_class' ).val(),
            href:       $.trim( $( '#wp-link-url' ).val() ),
            target:     $( '#wp-link-target' ).prop( 'checked' ) ? '_blank' : ''
        };
    }
});

Acabo de hacer una prueba rápida y parece funcionar, pero necesita más pruebas y ajustes al actualizar los enlaces. Aquí hay un viejo truco que hice que podría necesitar una actualización.

Actualizar

Parece que desea agregar la rel="nofollow"opción al cuadro de diálogo de enlace, así que vamos a actualizar el enfoque anterior para ese caso:

Agregamos el relatributo de enlace con:

/**
 * Modify link attributes
 */
wpLink.getAttrs = function() {
    wpLink.correctURL();        
    return {
        rel:        $( '#wpse-rel-no-follow' ).prop( 'checked' ) ? 'nofollow' : '',
        href:       $.trim( $( '#wp-link-url' ).val() ),
        target:     $( '#wp-link-target' ).prop( 'checked' ) ? '_blank' : ''
    };
}

Si el relatributo está vacío, se eliminará automáticamente del enlace en el editor.

Entonces podemos conectarnos al wplink-openevento que se dispara cuando se abre el diálogo de enlace. Aquí podemos inyectar nuestro HTML personalizado y actualizarlo de acuerdo con la selección de enlace actual:

$(document).on( 'wplink-open', function( wrap ) {

    // Custom HTML added to the link dialog
    if( $('#wpse-rel-no-follow').length < 1 )
        $('#link-options').append( '<div> <label><span></span> <input type="checkbox" id="wpse-rel-no-follow"/> No Follow Link</label></div>');

    // Get the current link selection:
    var _node = wpse_getLink();

    if( _node ) {
        // Fetch the rel attribute
        var _rel = $( _node ).attr( 'rel' );

        // Update the checkbox
        $('#wpse-rel-no-follow').prop( 'checked', 'nofollow' === _rel );
    }

});

donde usamos la siguiente función auxiliar, basada en la getLink()función central, para obtener el HTML del enlace seleccionado:

function wpse_getLink() {
    var _ed = window.tinymce.get( window.wpActiveEditor );
    if ( _ed && ! _ed.isHidden() ) {
        return _ed.dom.getParent( _ed.selection.getNode(), 'a[href]' );
    } 
    return null;
}

Aquí está la salida:

sin opción de seguimiento

con el siguiente HTML:

html

ps: Esto podría probarse más y también podría ampliarse para admitir traducciones

Birgire
fuente
Me gustó mucho esta respuesta porque parecía muy fácil. Sin embargo, el problema no era solo la actualización de enlaces, también si tenía varios enlaces en el mismo sitio, el valor seguía siendo el último que se eligió, incluso si provenía de un enlace diferente. ¡Aunque podría ser útil para alguien!
caramba
Actualicé la respuesta con un ejemplo de no-seguir-enlace @caramba
birgire
Hola @birgire, ¿cómo recuperar el valor de hrefsi el usuario no abre el cuadro de diálogo, sino que usa el primer cuadro emergente que tiene el marcador de posición Paste URL or type to search:?
MinhTri
1
Creo que usé el mce_external_pluginsfiltro para cargar el archivo de secuencia de comandos o el after_wp_tiny_mcegancho para inyectar el fragmento (con la parte anexa como una sola cadena de línea), para probar esto. El getAttrsmétodo aquí solo anulará el valor del cuadro de diálogo de configuración del enlace, no he investigado cómo anular el valor de la entrada en línea. Tal vez anular el wp_link_applycomando si es posible? Creo que esta podría ser una buena pregunta nueva ;-) @ Dan9
birgire
@birgire ¡Gracias! Finalmente, he encontrado dónde conseguirlo. WordPress utiliza tinymce.ui.Control.extend.setUrlen el complemento wp-includes/js/tinymce/plugins/wplink/plugin.js.
MinhTri
3

Mirando el núcleo, no hay rastro de ningún filtro o acción en la wp_link_dialogfunción, lo que habría hecho su vida más fácil ...

Investigando cómo otros han resuelto este problema, hay un complemento que hace más o menos lo mismo que tú quieres. Básicamente, elimina el registro de wplink.js wp_deregister_script('wplink');y vuelve a registrar una versión modificada del archivo, esta vez incluyendo el campo adicional deseado.

Aunque no creo que este sea el mejor método (teniendo en cuenta posibles conflictos posteriores al actualizar WordPress), creo que es el wat más fácil de obtener.

¡Espero eso ayude!

Capiedge
fuente
Gracias por la información y el enlace del complemento. También miraré el plugin y veré cómo lo resolvieron ...
caramba
Lo resolví mirando la fuente del complemento mencionado en esta respuesta que se puede encontrar en github github.com/ffsantos92/rel-nofollow-checkbox si alguien lo necesita. Solo tuve que cambiar 5 palabras más o menos ...
caramba