(function($) { $.fn.thePlugin = function(options) { // build main options before element iteration: var opts = $.extend({}, $.fn.thePlugin.defaults, options); var $this = $(this); var thePlugin = { index: 0, otherVar: true, init: function() { if(window.console) window.console.log('init() called. this = ', this); }, doThat: function(){ var a = thePlugin.otherVar; if(window.console) window.console.log('doThat() called.'); }, getIndex: function(){ // the interesting thing here is that from the HTML (public) 'this' will return the api object, not the thePlugin object because that's where it's called from. if(window.console) window.console.log("internal thePlugin.getIndex() called. this = ", this, "thePlugin = ", thePlugin); // this works because we're accessing thePlugin object directly: if(window.console) window.console.log(thePlugin.doThat); // this works because we're calling the function through the API itself: if(window.console) window.console.log(this.doAwesome); // this will not work for an API function (from the outside) because doThat is not returned in the API: if(window.console) window.console.log(this.doThat); return thePlugin.index; } }; if (opts.api) { var api = { getIndex: thePlugin.getIndex, doAwesome: thePlugin.doThat, opts: opts, obj: $this }; $this.data('thePlugin.api', api); }; return this.each(function() { // start the action here thePlugin.init(); }); }; // plugin defaults $.fn.thePlugin.defaults = { optionA: 'testing', api: true }; // public function/method $.fn.thePlugin.ver = function() { return "jquery.thePlugin version " + ver; }; })(jQuery);