wp.media.view.ImageDetails - Simpan pengaturan sebagai HTML5 data- * atribut untuk gambar

19

Apa yang akhirnya ingin saya capai adalah pengaturan tambahan yang ditambahkan ke kotak Detail Gambar, yang akan disimpan dalam <img>tag gambar sebagai data-*atribut

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


KODE SAYA

Saya membuat plugin, dan saya perlu membuat lebih banyak pengaturan ketika Anda mengedit gambar. Sejauh ini saya memiliki kode berikut:

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

Saya membuat posting baru dan menambahkan satu gambar, lalu mengkliknya dan menekan Edit (ikon pensil di bilah alat yang muncul). Saya berakhir di halaman detail gambar, dan seperti inilah tampilannya:

masukkan deskripsi gambar di sini

Sejauh ini baik. Di baris ini:

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

Saya biasanya menggunakan jQuery untuk mendapatkan nilai input, tetapi untuk tujuan pengujian saya mengubahnya menjadi nilai statis 'setting-value-here'. Saya menekan 'Perbarui' di sudut kanan bawah kotak Detail Gambar.


MASALAH

Di editor Teks, ini menunjukkan kode HTML seperti ini:

masukkan deskripsi gambar di sini

Ini tidak punya data-settings="setting-value-here", kok bisa?

Jika saya mengganti baris dengan ini:

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

Ini tidak mengubah ALT tag untuk alt="setting-value-here". Jadi apa yang saya lakukan salah mencoba untuk mengatur data- * atribut?


SOLUSINYA

Terima kasih kepada @bonger (yang mendapat karunia penuh 50 Reputasi), saya memiliki kode berikut:

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: (Perlu enqueued menggunakan 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 );
});
Kaspar Lee
sumber
3
Saya berharap saya bisa 2 - fasih, ringkas, baik diteliti, seterusnya-topik itu menyakitkan. Pertanyaan seperti ini adalah jenis langka.
TheDeadMedic
2
Terima kasih! Saya selalu mencoba dan penelitian (dan debug secara ekstensif) masalah saya sebanyak saya bisa sebelum bertanya. (Saya benci kalau Anda menemukan pertanyaan yang sangat sederhana dan OP bahkan belum mencoba Googling)
Kaspar Lee

Jawaban:

14

Cara untuk melakukannya adalah dengan menggunakan (sangat mudah) editor:image-editdan editor:image-updateacara yang dipicu oleh wpeditimageplugin tinymce untuk mendapatkan / mengatur dom secara langsung ( diperbarui untuk membungkus wp_enqueue_mediatindakan):

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

Untuk menambah dan mengisi bidang pengaturan, mungkin lebih baik untuk meretas keluaran wp_print_media_templates()alih - alih menimpa ImageDetails.initialize()( diperbarui untuk membungkus wp_enqueue_mediatindakan):

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;
    } );
} );
bonger
sumber
2
Terima kasih banyak! Ini sangat berguna (meskipun butuh beberapa menit untuk menyadarkan Anda). Saya akan menerima jawabannya dan memberikan hadiah itu kepada Anda tepat sebelum waktunya berakhir (seseorang yang saya berikan dengan jawaban yang lebih baik / lebih sederhana)
Kaspar Lee
Hmm, itu akan terjadi jika dijalankan sebelumnya wp_enqueue_media(). Mungkin cara yang lebih baik adalah dengan menggunakan wp_enqueue_mediaaksi yang dipecat pada akhir wp_enqueue_media(), yaitu bungkus semua kode dalamadd_action( 'wp_enqueue_media', function () { /*the code*/ } );
bonger
Tidak, sebaliknya!
bonger
Saya akan memperbarui jawabannya ...
bonger
1
Ini menimpa WP dari hal-hal template underscore underscorejs.org/#template (lihat wp.templatedi "wp-include / js / wp-util.js") .... Saya pikir
bonger