02 Feb

Integrating custom widgets in WordPress using RequireJS and Almond

A couple of days ago I embarked on a quest to write my own WordPress widget. The widget was to consist of a main file (widget.js), some libraries and another module encapsulating an algorithm I needed in the widget. That meant that I faced the task of including all that in my WordPress page. This is how I solved it:

1. RequireJS

The easiest way to integrate my own widget with all its dependencies into the WordPress project seemed to be via RequireJS. RequireJS is a JavaScript file and module loader which makes it unnecessary to reference every single required script file in the html document. Instead, the only reference needed is require.js. This results in the following script tag in my WordPress page:

With the data-main attribute, I specify a single entry point for RequireJS. RequireJS will load the widget.js file first and check it for further dependencies. The dependencies are passed as an array of names to the module definition. Additionally, I use a configuration object (requirejs.config) to list any paths which are not found directly under the base url, so that my widget.js file looks like that:

Though this is a standard way to include modules in a project, it did not work for me. The problem was that the WordPress project resides on one server, and the widget on another, and as it turned out, RequireJS could not cope with this cross domain request. So I needed to find a workaround.

2. RequireJS Optimizer

My next step was to use the RequireJS optimizer. The optimizer combines all JavaScript files and modules into one single file. Once this optimized file is created, we can reference it in the html. Since this newly created optimized.js file contains widget.js as well as any other libraries and modules required by the widget, we no longer need to load RequireJS into the html page. So I replaced the script tag from above by a new one:

In order to create the optimized.js file, we have two options: either attach all necessary arguments to the basic command line command, or create a build file which specifies the arguments. I opted for the latter and created a widget.build.js specifying the base url, the path of the output file, etc.

Now all I needed to do in the command line is pass the build file’s name to the optimizer:

r.js.cmd -o widget.build.js

Using the RequireJS optimizer and referencing the optimized script file instead of require.js in the html’s script tag solved the problem of the cross domain request, but with this problem solved, another arose: running the application in the browser, I got an error “define is not defined”. Obviously, WordPress was unfamiliar with the define() call, which was used at some place within the optimized.js file.

3. Almond.js

As a solution to this new problem, I decided to use Almond, an AMD API shim which replaces RequireJS. In order to use Almond, we use the RequireJS optimizer to create one single file, as we did before. The only difference is that now we pass the path to the almond.js file as name tag to the optimizer. Again, we can do that either in the command line or in a build file. Here is my final build file with the Almond reference:

Feeding these parameters to the RequireJS optimizer, I finally succeeded in loading my widget into the WordPress page. Whew!

Share this

Leave a reply