mwp
Accessed through the global mwp
variable. It is also registered in WordPress using the ‘mwp’ handle.
The mwp
javascript framework is a foundation for creating javascript code that is modular, reusable, extensible, and decoupled from specific view implementations (html structures). When following the patterns presented here, you will be able to:
- Create different views that use the same functionality
- Synchronize data and functionality multiple times on the same page
- Refactor your html views (templates) without breaking your javascript
- Extend the functionality provided by other modules to fit your needs
@Module Design Pattern
All new javascript files created using the WP CLI are already scaffolded using the module design pattern. This pattern allows your functions and variables inside your module to remain private and maintain their state since they are outside of the global scope. It also prevents variables and functions that you define from polluting the global scope because all of your code executes inside of a closure.
/**
* Module Design Pattern
*/
(function($, undefined) {
/**
* Module code lives here...
*/
})(jQuery);
The module design pattern is best practice, and should be used to contain all of your javascript code.
@MVVM Design Pattern
The Model/View/ViewModel design pattern is what allows you to keep your html views decoupled from your javascript code.
In essence, instead of your javascript needing to know what your html looks like and having to ‘manipulate it’ as part of its job, your javascript communicates data with the view through a ‘view model’ and allows the view to update itself.
/**
* Create a controller with a basic view model
*/
mwp.controller.model( 'example-controller', {
init: function() {
var self = this;
self.viewModel = {
title: ko.observable( 'Welcome' ),
sayHi: function() {
self.viewModel.title( 'Hello World!' );
}
};
}
});
In the example above, the javascript has no concern as to what the html is supposed to look like to represent its data or functionality. That can be completely decided by the view that wants to use the view model.
<div data-view-model="example-controller">
<h1 data-bind="text: title"></h1>
<button data-bind="click: sayHi">Say Hi!</button>
</div>
@Included Libraries
The mwp
javascript framework leans on a few mainstream libraries as part of its implementation of the MVVM design pattern. Therefore, certain aspects of its capabilities are already well documented on the associated project sites.
Backbone.js > doc
Registered in WordPress using the ‘backbone’ handle
Backbone is used internally when creating controllers and models inside the mwp
framework. Therefore, all mwp.controller
and mwp.model
instances are subclasses of Backbone.Model
.
var WidgetControllerModel = mwp.controller.model( 'acme-widget-controller', { } );
var WidgetModel = mwp.model( 'acme-widget', { } );
Knockout.js > doc
Registered in WordPress using the ‘knockout’ handle
Knockout is used to find html blocks inside your templates that contain the data-view-model
attribute, and bind them to the view model of the associated mwp.controller
.
<div data-view-model="acme-widget-controller"></div>
Knockback.js > doc
Registered in WordPress using the ‘knockback’ handle
Knockback is used to create view model representations of backbone models and collections. If you plan to use kb
in your controller, make sure to enqueue the knockback
script from your plugin. Knockback is not a core dependency of mwp
.
(function($, undefined) {
/**
* Create a model
*/
mwp.model( 'acme-widget', {
/**
* Constructor
*/
initialize: function() {
// model initialization code
}
});
/**
* Create a controller with a basic view model
*/
mwp.controller.model( 'acme-widget-controller', {
init: function() {
var WidgetModel = mwp.model.get('acme-widget');
var widget = new WidgetModel({ title: 'Vaporizer' });
var widgetCollection = new Backbone.Collection([widget]);
this.viewModel = {
widget: kb.viewModel( widget ),
widgetCollection: kb.collectionObservable( widgetCollection ),
};
}
});
})(jQuery);
<div data-view-model="acme-widget-controller">
<h1 data-bind="text: widget.title"></h1>
<ul data-bind="foreach: widgetCollection">
<li data-bind="text: title"></li>
</ul>
</div>
</div>