My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
WritingObjxPlugins  
Overview of how to write your own objx plugins
Featured
Updated Apr 29, 2010 by matr...@mac.com

NOTE: If you do not want to build your own plugin but have an idea, please feel free to Suggest a plugin to our development teams.

Rolling your own objx plugins

The power of objx lies in the ability to easily extend the library with your own plugins. This functionality is borrowed from jQuery and follows a very similar pattern.

Before you start

  1. Research other plugins: Check to make sure your plugin hasn't already been created
    • Have you thought of something new?
    • Can you do better?
  2. Hosting: Figure out where you want to host your plugin
    • Can we encourage you to go open source?
    • Does Google Code work for you?
  3. Concepts: Are you familiar with the objx pattern?

Consider writing an objx action

Actions allow you to easily provide functionality that is accessible (by your users) via a range of mechanisms (calling the function normally, passing a callback, chaining, creating new objx instances, reusing the current objx instance etc.). Most plugins can be written as an action.

A simple mean action

OAction("mean", {

  // provide behaviour for an array
  array: function() {

    var total = 0;
    var a = this.obj(); // get the actual array

    // total it up...
    for (var i = a.length; i--;) {
      total += a[i];
    }

    // return the mean
    return total / a.length;

  }

});
OProvides("mycompany.mean");

The code above provides a simple mean plugin that supports arrays of numbers. While the array function just returns the mean, objx provides a number of mechamisms that can we used to access this value:

var mean = objx([1,2,3]).mean();
// return the mean value as normal

var mean;
objx([1,2,3]).mean(function(m){ mean = m; }).somethingElse();
// mean is set to the mean, and I am able to carry on chaining the object

var o = objx([1,2,3]);
o.mean(ONew).workOnMeanValue();
// passing ONew allows me to get a new objx object wrapping the result, allowing me to perform actions and call methods on that new value.  o will still be the original array.

var o = objx([1,2,3]);
o.mean(OReplace).workOnMeanValue();
// passing OReplace allows me to continue working with o - which has been replaced
  • Learn more about how to use the OAction function

Non-action plugins - The "Hello World" of objx plugins

A static method

objx.hello = function() {
  alert("Hello World");
};

The above code is a complete objx plugin. The static method will alert "Hello World" when called. In fact, there is nothing special about this code at all - it is simply creating a new method called hello in the objx namespace.

You can test this code by calling it:

objx.hello();

You will see the expected "Hello World" alert box.

Writing instance methods: Adding context to your plugin

Now let's try something a little more difficult (and by 'little' I mean 'little'):

objx.fn.hello = function() {
  alert("Hello World");
};

Did you notice the addition of .fn? This tells objx that the hello method is a function that should be considered an instance method. So, it will be available when we wrap an object in the objx keyword like this:

objx("Mat").hello();

Of course our hello method doesn't need to be an instance method at all, since it totally ignores the "Mat" string in our previous code snippet. So let's add some context:

objx.fn.hello = function() {
  alert("Hello " + this.obj());
};

The this.obj() call will get the object that is being enhanced, in our case the "Mat" string.

objx("Mat").hello();

This will alert a box saying "Hello Mat". So we have used the context of the objx keyword in our 'instance' method.

Now we can use it to say hello to anybody:

objx("Omari").hello();  // alerts "Hello Omari"
objx("Simon").hello();  // alerts "Hello Simon"

Getting the enhanced object

To get the object that is being enhanced you should use the obj method:

this.obj()

Internally inside objx the object is stored in a local property called _obj. In the early days of objx, the plugins make direct calls to this._obj instead of going via the obj() method. However when the library gets minified _obj becomes something else and it not predictable (it varies depending on what you use to minify objx) so you must use the this.obj() method.

Ensure chaining is supported

Since our hello method doesn't need to return a particular value (at the moment, nothing is returned) it is an ideal candidate for chaining.

Consider this code snippet:

objx("Mat").hello().reverse().hello();

We are telling objx that we want to say hello first, then reverse the string, then say hello again (to this reversed string). Our hello method will not currently support this, because hello() returns nothing - and reverse() is not a function of null.

To add chaining we return this from the instance method:

objx.fn.hello = function() {
  alert("Hello " + this.obj());
  return this;
};

return this; ensures that the instance that the call was made on will be returned ready for other calls to be made afterwards.

objx("Mat").hello().reverse().hello();

// alerts "Mat"
// then   "taM"

Requiring and providing

  • See also requiring and providing for information about how objx lets you easily describe which plugins you require, and the one you are providing.

Supporting ODebug property

The ODebug property is a boolean value indicating whether additional debugging should take place to help developers while they are first using your plugin. For production, the value will be set to false and most of the errors and checks that are done by your plugin can stop - because by this point, the developer is confident that she has got everything right.

You should use ODebug wherever you have developer time checks, such as ensuring the correct arguments were passed to a method, or that an object follows a particular format etc.

if (ODebug) {
   if (arguments.length === 0 || !objx(arguments[0]).is("something")) {
      OError("my-plugin", "You must provide at least one argument to this method");
   }
}

The above check will be removed if ODebug is set to false and your code will perform better.

Further reading

  • Discover how complex interactions can be coded in a very condensed way by chaining method calls

Sign in to add a comment
Powered by Google Project Hosting