Reply to comment

Using wp.media.view.Modal

There are a lot of demos and tutorials about incorporating the wp.media image uploader and selector, but not much about the other parts of the library.

wp.media.views.Modal is a blank modal view, which the media modal uses as its default container.

This view is demo'd in the Media Guide, but it's not really discussed elsewhere.

Modal displays the large white box that contains the media manager. Within wp.media, it's used only two times. One is when the media manager needs to display in a modal (it can display outside of a modal, as well), and second is EditAttachments, which throws up a modal.

    var modal = new wp.media.view.Modal({
        // A controller object is expected, but let's just pass
        // a fake one to illustrate this proof of concept without
        // getting console errors.
        controller: { trigger: function() {} }
    });

EditAttachments shows one way to write the controller, as an extension of Frames. A Frame is a view with state management. Unfortunately, it's pretty complex, so I couldn't make sense of it.

So, instead, I dug into the code for wp.Backbone.View.

wp.Backbone.View

wp.Backbone.View, the base class for Views, expands upon Backbone's idea of view by adding the following:

constructor(options) - adds views, a collection of Subviews.

abstract method ready(), called when constructor() is called.

remove() - recursively removes child views

render() - you no longer define render. Instead you override prepare()

prepare() - the return value of prepare() is passed as the input into the template(). defined when you extend wp.Backbone.View

template() - defined when you extends wp.Backbone.View

Backbone Views don't have controllers. Instead, you have a Model that is rendered to a view. The view has an events mapping object that's used to attach event handlers to elements. When fields are edited, or buttons clicked, handlers can then read the UI, and copy values into the model. The model, in turn, emits events that force a redraw of the view.

wp.media.controllers.Frame goes whole-hog and has features for managing collections of objects. That's necessary for the media manager, but not really necessary for a less elaborate use.

This minimal example below is enough:

    var formname = 'foo-form';
    var FooView = window.top.wp.Backbone.View.extend({
            events: {
                'change #foo-form--foo': 'formupdate'
            },
            template: wp.template( formname ),
            prepare: function() {
                return this.model.toJSON();
            },
            formupdate: function() {
                this.model.set({foo: $('#foo-form--foo').val());
            }
    });

    var modal = new window.top.wp.media.view.Modal({
            controller: { 
                trigger: function(id) {
                    // events can be caught here
                }
            }
    });

    var FooModel = window.top.Backbone.Model.extend();
    var m = new FooModel({foo:1}); 
    modal.content( new FooView({ model: m }) );
    modal.open();

And the foo form looks like this:

<script id="tmpl-foo-form" type="text/template">
    <input id="foo-form--foo" value="{{ data.foo }}" />
</script>

Note that the value of foo is called "data.foo", not simply "foo". This is a wp.template convention.

So, from the top, let's see what's going on.

First, there are some naming conventions. wp.template's naming convention for templates is that they are all named "tmpl-*". We ask for wp.template('foo-form'), and it will look for "tmpl-foo-form".

Also, not that I suffix forms with "-form". Not required, but it makes things easier. I also use the BEM-like naming convention of "foo-form--foo". The form name followed by -- and then by the element. This naming convention makes it easy to come up with unique names.

Note that when we extend wp.Backbone.View, our options have events and template, but lacks a "render" method. Instead, we have a "prepare" method that prepares the data input for the template function. We just pass the model's properties.

wp.Backbone.View has its own render() method, and we should not override it.

The event handler, formupdate, is like a regular Backbone view event handler.

This example can't do anything useful, but it's something to study and build on.

Reply

The content of this field is kept private and will not be shown publicly.
  • Lines and paragraphs break automatically.

More information about formatting options

6 + 14 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.