A way to do it is to use the (very convenient) editor:image-edit
and editor:image-update
events triggered by the tinymce wpeditimage
plugin to get/set the dom directly (updated to wrap in wp_enqueue_media
action):
add_action( 'wp_enqueue_media', function () {
add_action( 'admin_footer', function () {
?>
<script type="text/javascript">
jQuery(function ($) {
if (wp && wp.media && wp.media.events) {
wp.media.events.on( 'editor:image-edit', function (data) {
data.metadata.my_setting = data.editor.dom.getAttrib( data.image, 'data-my_setting' );
} );
wp.media.events.on( 'editor:image-update', function (data) {
data.editor.dom.setAttrib( data.image, 'data-my_setting', data.metadata.my_setting );
} );
}
});
</script>
<?php
}, 11 );
} );
To add and populate the settings field, it’s perhaps groovier to hack the output of wp_print_media_templates()
rather than override ImageDetails.initialize()
(updated to wrap in wp_enqueue_media
action):
add_action( 'wp_enqueue_media', function () {
remove_action( 'admin_footer', 'wp_print_media_templates' );
add_action( 'admin_footer', $func = function () {
ob_start();
wp_print_media_templates();
$tpl = ob_get_clean();
// To future-proof a bit, search first for the template and then for the section.
if ( ( $idx = strpos( $tpl, 'tmpl-image-details' ) ) !== false
&& ( $before_idx = strpos( $tpl, '<div class="advanced-section">', $idx ) ) !== false ) {
ob_start();
?>
<div class="my_setting-section">
<h2><?php _e( 'My Settings' ); ?></h2>
<div class="my_setting">
<label class="setting my_setting">
<span><?php _e( 'My Setting' ); ?></span>
<input type="text" data-setting="my_setting" value="{{ data.model.my_setting }}" />
</label>
</div>
</div>
<?php
$my_section = ob_get_clean();
$tpl = substr_replace( $tpl, $my_section, $before_idx, 0 );
}
echo $tpl;
} );
} );