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

มันไม่เปลี่ยนALTalt="setting-value-here"แท็ก ดังนั้นฉันทำอะไรผิดที่พยายามตั้งค่า data- * attribute?


การแก้ไขปัญหา

ขอบคุณ@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

2
ขอบคุณ! ฉันมักจะพยายามค้นคว้า (และแก้ปัญหาอย่างกว้างขวาง) ปัญหาของฉันให้มากที่สุดก่อนที่จะถาม (ฉันเกลียดเมื่อคุณพบคำถามง่าย ๆ จริง ๆ และ OP ไม่ได้ลอง Googling)
Kaspar Lee

คำตอบ:


14

วิธีที่จะทำได้คือการใช้ (สะดวกมาก) editor:image-editและeditor:image-updateเหตุการณ์ที่เกิดขึ้นจากwpeditimageปลั๊กอินtinymce เพื่อรับ / ตั้งค่า 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
ขอบคุณมาก! สิ่งนี้มีประโยชน์มาก (แม้ว่าจะใช้เวลาสองสามนาทีในการทำความเข้าใจ) ฉันจะยอมรับคำตอบและได้รับรางวัลเงินรางวัลให้กับคุณก่อนที่มันจะจบลง (คนของฉันมาด้วยดีกว่า / คำตอบง่าย)
คาสปาร์ลี

หืมมที่จะเกิดขึ้นถ้ามันวิ่งมาก่อนwp_enqueue_media()คือ บางทีอาจจะเป็นวิธีที่ดีกว่าคือการใช้wp_enqueue_mediaการกระทำที่ถูกยิงในตอนท้ายของwp_enqueue_media()เช่นห่อรหัสทั้งหมดในadd_action( 'wp_enqueue_media', function () { /*the code*/ } );
Bonger

ไม่กลับกัน!
bonger

ฉันจะอัปเดตคำตอบ ...
bonger

1
มันคือการแทนที่ WP ของสิ่งที่เทมเพลตขีดล่าง underscorejs.org/#template (ดูwp.templateใน "wp- รวม / js / wp-util.js") .... ฉันคิดว่า
bonger
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.