15

I managed to add a custom option-select for images with

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 );

Now I need to do almost the same for links. So if I click on Pages -> Add New -> Insert / Edit Link I get this:

enter image description here

Can I add another option-select field for those links? How to do that?

18

The dialog HTML comes from WP_Editors::wp_link_dialog() but no hooks in there.

We could instead use jQuery to append the custom HTML to the link dialog and try to override e.g. the wpLink.getAttrs(), because it's very short ;-)

Demo example:

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' : ''
        };
    }
});

I just did a quick test and it seems to work but needs further testing and adjustments when updating links. Here's an old hack that I did that might need a refresh.

Update

It looks like you want to add the rel="nofollow" option to the link dialog, so let's update the above approach for that case:

We add the rel link attribute with:

/**
 * 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' : ''
    };
}

If the rel attribute is empty, then it will be automatically removed from the link in the editor.

Then we can hook into the wplink-open event that fires when the link dialog is opened. Here we can inject our custom HTML and update it according to the current link selection:

$(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 );
    }

});

where we use the following helper function, based on the getLink() core function, to get the HTML of the selected link:

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;
}

Here's the output:

no follow option

with the following HTML:

html

ps: This could be tested further and might also be extended to support translations

  • I liked this answer a lot cause it looked so easy. Problem though was not just the updating of links, also if I had multiple links on the same site the value remained the last one which was chosen even if from a different link. Could still be useful for someone though! – caramba Jun 2 '16 at 11:25
  • I updated the answer with an no-follow-link example @caramba – birgire Jun 2 '16 at 13:25
  • Hey @birgire, how to retrieve value of href if user don't open the dialog but just use the very first popup box which has the placeholder: Paste URL or type to search? – MinhTri Aug 27 '16 at 10:20
  • 1
    I think I used the mce_external_plugins filter to load the script file or the after_wp_tiny_mce hook to inject the snippet (with the append part as a single line string), to test this. The getAttrs method here will only override the value from the link settings dialog, I haven't looked into how to override the value from the inline input. Maybe override the wp_link_apply command if possible? I think this might be a good new question ;-) @Dan9 – birgire Aug 27 '16 at 10:23
  • @birgire Thank you! Finally, I have found where to get it. WordPress uses tinymce.ui.Control.extend.setUrl in the plugin wp-includes/js/tinymce/plugins/wplink/plugin.js. – MinhTri Aug 27 '16 at 12:17
3

Looking at the core, there's no trace of any filter or action in the wp_link_dialog function, which would have made your life easier...

Investigating how others has solved this problem, there's a plugin that does more or less the same as you want. Basically it deregisters the wplink.js, wp_deregister_script('wplink'); and registers again a modified version of the file, this time including the desired extra field.

Although I don't think this is the best method (taking into account possible subsequent conflicts while updating WordPress), I think that it is the easiest wat to get it.

Hope it helps!

  • Thank you for the information and plugin link. I will also look into the plugin and see how they solved it... – caramba Jun 2 '16 at 8:57
  • I solved it with looking at the source of the plugin mentioned in this answer which can be found on github github.com/ffsantos92/rel-nofollow-checkbox if anyone needs it. I only had to change 5 words or so ... – caramba Jun 2 '16 at 11:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.