TransWikia.com

Insert HTML markup to page content from the Media Frame modal

WordPress Development Asked by Mads Hansen on January 28, 2021

TL;DR

How do I get the HTML markup created in the Media Frame modal and insert it into the editor/page content?


I’m trying to insert media from a custom router-tab in the media frame.
But I have no idea how to take the HTML markup created in the media frame and place it into the page content.

My code so far is based on the Github repo custom_media_menu.js created by Fab1en.
https://gist.github.com/Fab1en/4586865

jQuery(document).ready(function(){

// custom state : this controller contains your application logic
wp.media.controller.Custom = wp.media.controller.State.extend({

    initialize: function(){
        // this model contains all the relevant data needed for the application
        this.props = new Backbone.Model({ custom_data: 'controller state model data.' });
        this.props.on( 'change:custom_data', this.refresh, this );
    },

    // called each time the model changes
    refresh: function() {
        // update the toolbar
        this.frame.toolbar.get().refresh();
    },

    // called when the select button in toolbar is clicked
    customAction: function(){
        console.log('controller.custom, toolbar button clicked. this.props; custom data', this.props.get('custom_data'));
    }

});




// custom toolbar : contains the buttons at the bottom
wp.media.view.Toolbar.Custom = wp.media.view.Toolbar.extend({

    initialize: function() {
        _.defaults( this.options, {
            event: 'custom_event',
            close: false,
            items: {
                custom_event: {
                    text: wp.media.view.l10n.customButton, // added via 'media_view_strings' filter,
                    style: 'primary',
                    priority: 80,
                    requires: false,
                    click: this.customAction
                }
            }
        });

        wp.media.view.Toolbar.prototype.initialize.apply( this, arguments );
    },


    // called each time the model changes
    refresh: function() {
        // you can modify the toolbar behaviour in response to user actions here
        // disable the button if there is no custom data
        var custom_data = this.controller.state().props.get('custom_data');
        this.get('custom_event').model.set( 'disabled', ! custom_data );

        // call the parent refresh
        wp.media.view.Toolbar.prototype.refresh.apply( this, arguments );
    },


    // triggered when the button is clicked
    customAction: function(){
        this.controller.state().customAction();
    }
});




// custom content : this view contains the main panel UI
wp.media.view.Custom = wp.media.View.extend({
    className: 'media-custom',

    // bind view events
    events: {
        'input':  'custom_update',
        'keyup':  'custom_update',
        'change': 'custom_update',
        'click': 'custom_update'
    },

    initialize: function() {
        // create an input
        this.input = '<input type="text" value="' + this.model.get('custom_data') + '" />';

        // insert it in the view
        this.$el.append(this.input);

        // re-render the view when the model changes
        this.model.on( 'change:custom_data', this.render, this );
    },

    render: function(){
        this.input.value = this.model.get('custom_data');
        return this;
    },

    custom_update: function( event ) {
        console.log('view.custom, custom update');
        this.model.set( 'custom_data', event.target.value );
    }
});




// supersede the default MediaFrame.Post view
var oldMediaFrame = wp.media.view.MediaFrame.Select;
wp.media.view.MediaFrame.Select = oldMediaFrame.extend({

    initialize: function() {
        oldMediaFrame.prototype.initialize.apply( this, arguments );

        this.states.add([
            new wp.media.controller.Custom({
                id:         'my-action',
                menu:       'default', // menu event = menu:render:default
                content:    'custom',
                title:      wp.media.view.l10n.customMenuTitle, // added via 'media_view_strings' filter
                priority:   200,
                toolbar:    'main-my-action', // toolbar event = toolbar:create:main-my-action
                type:       'link'
            })
        ]);

        this.on( 'content:render:custom', this.customContent, this );
        this.on( 'toolbar:create:main-my-action', this.createCustomToolbar, this );
        this.on( 'toolbar:render:main-my-action', this.renderCustomToolbar, this );
    },

    createCustomToolbar: function(toolbar){
        toolbar.view = new wp.media.view.Toolbar.Custom({
            controller: this
        });
    },

    customContent: function(){
        // custom content view
        var view = new wp.media.view.Custom({
            controller: this,
            model: this.state().props
        });

        this.content.set( view );
    },

});
}); // END document .ready

The first code-block you encounter extends on wp.media.controller.State and has a property called customAction that’s called when the insert button is pressed. But I don’t know which function to use to place the customAction stuff in the content and replacing the Gutenberg upload placeholder.

From looking around on the Stack-forums, I get the feeling that is has something to do with state.
But when reading the Backbone JS documentation Controller and States isn’t mentioned.
So that must be something added in the WordPress implementation.
I’ve been reading some of the core implementation, but I don’t find it obvious whats going on.
https://core.trac.wordpress.org/browser/tags/5.5.1/src/js/media/views/media-frame.js

Any hints on how to insert the markup, or where I can read up on the WordPress Media Frame implementation, will be much appreciated.

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP