11 Tips for Creating Great MooTools Plugins

By Ryan Florence, published 2010-02-16

Part of the issue Migrated Articles From Original Site Structure..

Here’s a sort of “best practices” that I follow when creating mootools classes in no particular order whatsoever.

1. Check the forge before starting

Since the release of the forge I check for work others have already done. If there is something similar I’ll fork it on github, make what I consider to be improvements, and then send a pull request to the original author. I did this with StaticScroll. It had most of what I needed, so I forked it, added the features I needed, and then Luke Ehresman incorporated the changes and updated it on the forge.

2. Extend existing classes

When I first started writing classes with mootools I did a lot of:

initialize: function(element){
  this.tween = new Fx.Tween(element,{
    duration: 'some-horrible-hard-coded-options',
    transition: this.namespaced.options.that.are.lame
  });
  
  // ...
  
  this.tween.start(0,100);
}

Duh. If I’d just extend Tween then I’d get all of it’s options and methods from the start. More often then not I’m just adding some fun to an existing class like Tween or Request.

var Fx.Tween.Toggle = new Class({
  Extends: Fx.Tween
});

3. Add and remove events with methods named attach & detach

I always name the method where I add events attach and always provide myself a way to remove the events with detach. When you’re working with multiple objects sometimes they can bump into each other and you need to detach some events.

//...
initialize: function(element){
  this.element = document.id(element);
  this.bound = this.someMethod.bind(this);
},

attach:function(){
  this.element.addEvent('click', this.bound);
  return this;
},

detach: function(){
  this.element.removeEvent('click', this.bound);
  return this;
}
//...

4. Create Elements in methods named build

I always name any method that creates new elements build or buildMenu, or whatever. I also try not to do any adding of events here, even though Element supports it quite well.

build: function(){
  this.wrapper = new Element('div').inject(this.element);
  return this;
}

5. Store the main element(s) as this.element & this.elements

I do this to keep my world consistent across all plugins. If the class takes an element I call it this.element, even if it’s a “container” or any other tempting name. I do the same for classes with a handful of elements. Though, with event delegation, I usually just need one element.

initialize: function(element){
  this.element = document.id(element);
}

6. Ensure religiously that this always references the class instance

ALWAYS!

7. Write methods to do one thing only

It makes me sad when I pop open a plugin and it’s got one ginormous method that does everything known to geek. You can’t extend classes that have nothing more than a 200 line initialize method. Look at all the -more plugins (and for that matter, any of Aaron Newton’s stuff on clientcide) and you’ll see how he gets a ton of mileage out of his classes.

I get excited when I pop open a class and see that I can easily extend it because it’s got several single purpose methods. Like, really excited. I yell to my wife “Hey, check out the methods on this class! It’s so extendable!” Unfortunately, she never cares because she has no clue what I’m talking about. “I’ve told you a thousand times I don’t know what a moo tool is and I don’t care.”

8. Fire events anytime something awesome happens

Imagine if you were doing ajax stuff and Request didn’t have onSuccess, what’s the point? A class should usually have a custom event fire every time something awesome happens.

Implements: [Options, Events],
//..
beAwesome: function(){
  this.element.beAwesome();
  this.fireEvent('onAwesomeness');
}

9. Create options for things that the class doesn’t need

It’s sometimes hard for me to decide if something should be an option or an argument for the constructor, or something else. When in doubt, I make it an option. In addition to the options object, I tend to have just one argument for the constructor and get really nervous if I want more than two. Additionally, I next-to-never hard-code in strings and numbers and such.

10. Return this with most methods

If you return this with each method then you can chain the methods of your class. Occasionally a method need to return something else, but most of the time you should return this.

doSomethingAwesome: function(){
  // do cool stuff
  return this;
},

doSomethingImportant: function(){
  // do important stuff
  return this;
}

myInstance.attach().doSomethingImportant().doSomethingAwesome().detach();

11. Name my classes Nouns (capitalized) and my methods verbs

Sometimes when a method returns a value, I’ll make it a noun, but generally it’s a verb like ‘jump’, ‘getSomething’, ‘checkStuff’, etc.

Got some patterns of your own? Let’s hear it in the comments!

Hi, I'm Ryan!

Location:
South Jordan, UT
Github:
rpflorence
Twitter:
ryanflorence
Freenode:
rpflo

About Me

I'm a front-end web developer from Salt Lake City, Utah and have been creating websites since the early 90's. I like making awesome user experiences and leaving behind maintainable code. I'm active in the JavaScript community writing plugins, contributing to popular JavaScript libraries, speaking at conferences & meet-ups, and writing about it on the web. I work as the JavaScript guy at Instructure.