wp.​​media.view.ImageDetails-将设置另存为图像的HTML5 data- *属性


19

我最后要实现的是在“图像详细信息”框中添加了额外的设置,这些设置将<img>作为data-*属性存储在图像标签中

例: <img src="..." data-my_setting="...">


我的密码

我正在创建一个插件,并且在编辑图像时需要创建更多设置。到目前为止,我有以下代码:

jQuery(function($) {

    var imageDetails = wp.media.view.ImageDetails

    wp.media.view.ImageDetails = wp.media.view.ImageDetails.extend({
        // Initialize - Call function to add settings when rendered
        initialize: function() {
            this.on('post-render', this.add_settings);
        },
        // To add the Settings
        add_settings: function() {
            $('.advanced-section').prepend('\
                <h2>My Settings</h2>\
                <input type="text" class="my_setting">\
            ');

            // Set Options
            this.controller.image.set({"data-settings": 'setting-value-here'})
        }
    });

}) // End of jQuery(function($))

我创建了一个新帖子,并添加了一个图像,然后单击它并按下“编辑”(弹出的工具栏中的铅笔图标)。我最终进入了图像详细信息页面,结果如下所示:

在此处输入图片说明

到目前为止,一切都很好。在这行上:

this.controller.image.set({"data-settings": 'setting-value-here'})

我通常会使用jQuery来获取输入的值,但是出于测试目的,我将其更改为的静态值'setting-value-here'。我按了“图像详细信息”框右下角的“更新”。


问题

在文本编辑器中,它显示HTML代码,如下所示:

在此处输入图片说明

这个没有data-settings="setting-value-here",怎么来的?

如果我将其替换为:

 this.controller.image.set({alt: 'setting-value-here'})

确实改变ALT标签alt="setting-value-here"。那么,尝试设置data- *属性时我做错了什么?


解决方案

感谢@bonger(获得了50声望的全额赏金),我得到了以下代码:

PHP:

function add_my_settings() {
    ob_start();
    wp_print_media_templates();
    $tpl = ob_get_clean();
    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;
};

// Hack the output of wp_print_media_templates()
add_action('wp_enqueue_media', $func =
    function() {
        remove_action('admin_footer', 'wp_print_media_templates');
        add_action('admin_footer',  'add_my_settings');
    }
);

JavaScript :(需要使用排队wp_enqueue_script()

// When Image is Edited
wp.media.events.on('editor:image-edit', function(data) {
    data.metadata.my_setting = data.editor.dom.getAttrib( data.image, 'data-my_setting' );
});

// When Image is Updated
wp.media.events.on('editor:image-update', function(data) {
    data.editor.dom.setAttrib( data.image, 'data-my_setting', data.metadata.my_setting );
});

3
我希望我能+2-雄辩,简洁,经过充分研究,所以在主题上很痛。诸如此类的问题是稀有品种。
TheDeadMedic '16

2
谢谢!在询问之前,我总是尽力研究和研究(并广泛调试)我的问题。(当您发现一个非常简单的问题并且OP甚至没有尝试使用谷歌搜索时,我都会讨厌)
Kaspar Lee

Answers:


14

一种方法是使用(非常方便)editor:image-editeditor:image-updatetinymce wpeditimage插件触发的事件来直接获取/设置dom(已更新以进行包装wp_enqueue_media):

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

要添加并填充“设置”字段,破解wp_print_media_templates()而不是覆盖输出ImageDetails.initialize()更新以进行包装wp_enqueue_media)可能更麻烦:

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

2
非常感谢!这非常有用(尽管花了几分钟时间才可以解决问题)。我会接受答案并在悬赏结束之前向您奖励,(我想出一个更好/更简单的答案)
Kaspar Lee

嗯,如果之前运行,那将会发生wp_enqueue_media()。也许更好的方法是使用wp_enqueue_media末尾触发的操作,即将wp_enqueue_media()所有代码包装在add_action( 'wp_enqueue_media', function () { /*the code*/ } );
bonger中

不,反之亦然!
邦杰

我将更新答案...
bonger

1
这是下划线的模板的东西的WP的覆盖underscorejs.org/#template(见wp.template在“WP-包括/ JS / WP-util.js中”)......我想
bonger
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.