Append button to WordPress Image Details modal

Here’s an alternative technique to manipulating the template. I adapted the solution below from this post.

In the approach below, the print_media_templates hook, which is triggered at the bottom of wp-includes/media-template.php, is used to output some JavaScript that removes the default image details underscores template (<script type="text/html" id="tmpl-image-details">) and replaces it with a duplicated version which we can modify to suit our needs.

I’ve added Hello, world! in the modified template, and the Replace button too (more on that in a second). One of the drawbacks of this approach is that if/when the WordPress core is updated, our forked template won’t reflect any changes to this particular media template.

Another problem here is that simply adding the button is not enough. You can activate the button by removing the HTML comments (<!-- and -->) that I wrapped it in if you want to proceed anyway. Using the standard Replace button on an image that is not part of the media library will trigger an error in the console, but seems to work never-the-less. Ideally, a custom button should be created or the JS controller that handles the Replace button’s functionality should be implemented (which I’m not sure how to do).

add_action( 'print_media_templates', 'wpse_print_media_templates' );
function wpse_print_media_templates() { ?>
    <script>
        // Idea via http://unsalkorkmaz.com/wp3-5-media-gallery-edit-modal-change-captions-to-title/
        jQuery( document ).ready( function( $ ){
            jQuery( "script#tmpl-image-details:first" ).remove();
        });
    </script>

    <script type="text/html" id="tmpl-image-details">
        <div class="media-embed">
            <div class="embed-media-settings">
                <div class="column-image">
                    <div class="image">
                        <img src="https://wordpress.stackexchange.com/questions/268100/{{ data.model.url }}" draggable="false" alt="" />

                        <# if ( data.attachment && window.imageEdit ) { #>
                            <div class="actions">
                                <input type="button" class="edit-attachment button" value="<?php esc_attr_e( 'Edit Original' ); ?>" />
                                <input type="button" class="replace-attachment button" value="<?php esc_attr_e( 'Replace' ); ?>" />
                            </div>
                        <# } else if ( ! data.attachment && window.imageEdit ) { #>
                            <!--
                                <div class="actions">
                                    <input type="button" class="replace-attachment button my-theme"  value="<?php esc_attr_e( 'Replace' ); ?>" />
                                </div>
                             -->
                        <# } #>
                        <h1>Hello, world!</h1>
                    </div>
                </div>
                <div class="column-settings">
                    <?php
                    /** This filter is documented in wp-admin/includes/media.php */
                    if ( ! apply_filters( 'disable_captions', '' ) ) : ?>
                        <label class="setting caption">
                            <span><?php _e('Caption'); ?></span>
                            <textarea data-setting="caption">{{ data.model.caption }}</textarea>
                        </label>
                    <?php endif; ?>

                    <label class="setting alt-text">
                        <span><?php _e('Alternative Text'); ?></span>
                        <input type="text" data-setting="alt" value="{{ data.model.alt }}" />
                    </label>

                    <h2><?php _e( 'Display Settings' ); ?></h2>
                    <div class="setting align">
                        <span><?php _e('Align'); ?></span>
                        <div class="button-group button-large" data-setting="align">
                            <button class="button" value="left">
                                <?php esc_html_e( 'Left' ); ?>
                            </button>
                            <button class="button" value="center">
                                <?php esc_html_e( 'Center' ); ?>
                            </button>
                            <button class="button" value="right">
                                <?php esc_html_e( 'Right' ); ?>
                            </button>
                            <button class="button active" value="none">
                                <?php esc_html_e( 'None' ); ?>
                            </button>
                        </div>
                    </div>

                    <# if ( data.attachment ) { #>
                        <# if ( 'undefined' !== typeof data.attachment.sizes ) { #>
                            <label class="setting size">
                                <span><?php _e('Size'); ?></span>
                                <select class="size" name="size"
                                    data-setting="size"
                                    <# if ( data.userSettings ) { #>
                                        data-user-setting="imgsize"
                                    <# } #>>
                                    <?php
                                    /** This filter is documented in wp-admin/includes/media.php */
                                    $sizes = apply_filters( 'image_size_names_choose', array(
                                        'thumbnail' => __('Thumbnail'),
                                        'medium'    => __('Medium'),
                                        'large'     => __('Large'),
                                        'full'      => __('Full Size'),
                                    ) );

                                    foreach ( $sizes as $value => $name ) : ?>
                                        <#
                                        var size = data.sizes['<?php echo esc_js( $value ); ?>'];
                                        if ( size ) { #>
                                            <option value="<?php echo esc_attr( $value ); ?>">
                                                <?php echo esc_html( $name ); ?> &ndash; {{ size.width }} &times; {{ size.height }}
                                            </option>
                                        <# } #>
                                    <?php endforeach; ?>
                                    <option value="<?php echo esc_attr( 'custom' ); ?>">
                                        <?php _e( 'Custom Size' ); ?>
                                    </option>
                                </select>
                            </label>
                        <# } #>
                            <div class="custom-size<# if ( data.model.size !== 'custom' ) { #> hidden<# } #>">
                                <label><span><?php _e( 'Width' ); ?> <small>(px)</small></span> <input data-setting="customWidth" type="number" step="1" value="{{ data.model.customWidth }}" /></label><span class="sep">&times;</span><label><span><?php _e( 'Height' ); ?> <small>(px)</small></span><input data-setting="customHeight" type="number" step="1" value="{{ data.model.customHeight }}" /></label>
                            </div>
                    <# } #>

                    <div class="setting link-to">
                        <span><?php _e('Link To'); ?></span>
                        <select data-setting="link">
                        <# if ( data.attachment ) { #>
                            <option value="file">
                                <?php esc_html_e( 'Media File' ); ?>
                            </option>
                            <option value="post">
                                <?php esc_html_e( 'Attachment Page' ); ?>
                            </option>
                        <# } else { #>
                            <option value="file">
                                <?php esc_html_e( 'Image URL' ); ?>
                            </option>
                        <# } #>
                            <option value="custom">
                                <?php esc_html_e( 'Custom URL' ); ?>
                            </option>
                            <option value="none">
                                <?php esc_html_e( 'None' ); ?>
                            </option>
                        </select>
                        <input type="text" class="link-to-custom" data-setting="linkUrl" />
                    </div>
                    <div class="advanced-section">
                        <h2><button type="button" class="button-link advanced-toggle"><?php _e( 'Advanced Options' ); ?></button></h2>
                        <div class="advanced-settings hidden">
                            <div class="advanced-image">
                                <label class="setting title-text">
                                    <span><?php _e('Image Title Attribute'); ?></span>
                                    <input type="text" data-setting="title" value="{{ data.model.title }}" />
                                </label>
                                <label class="setting extra-classes">
                                    <span><?php _e('Image CSS Class'); ?></span>
                                    <input type="text" data-setting="extraClasses" value="{{ data.model.extraClasses }}" />
                                </label>
                            </div>
                            <div class="advanced-link">
                                <div class="setting link-target">
                                    <label><input type="checkbox" data-setting="linkTargetBlank" value="_blank" <# if ( data.model.linkTargetBlank ) { #>checked="checked"<# } #>><?php _e( 'Open link in a new tab' ); ?></label>
                                </div>
                                <label class="setting link-rel">
                                    <span><?php _e('Link Rel'); ?></span>
                                    <input type="text" data-setting="linkRel" value="{{ data.model.linkClassName }}" />
                                </label>
                                <label class="setting link-class-name">
                                    <span><?php _e('Link CSS Class'); ?></span>
                                    <input type="text" data-setting="linkClassName" value="{{ data.model.linkClassName }}" />
                                </label>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </script>       
    <?php
}

Leave a Comment