building yui 3 custom modules
DESCRIPTION
Learn how to leverage the YUI 3.x infrastructure to create custom code that can be loaded easily and efficiently onto any page. Also discover how these mashups can combine YUI widgets and utilities with your own code and how to reuse code between different YUI instances. Caridy is a Senior Frontend Engineer and JavaScript Nerd at Yahoo! and an active YUI contributor. He's also the creator of the Bubbling Library YUI Extension.TRANSCRIPT
Building YUI 3 Custom Modules
Caridy Patino Frontend Engineer at Yahoo!
YUI Contributor
Bubbling Library Creator
Overview
- YUI 3 and Modules
- Using Custom Modules in YUI 3
- Extending and Building Custom Modules
- Supporting Legacy Code
- Best Practices / Techniques
What is a module in YUI 3?
YUI 3 Modules
Using a module
YUI().use(‘node’, function (Y) {
Y.one (‘div.status’).setContent (‘ready!’);
});
Using multiple modules
YUI().use(‘node’,‘anim’,function(Y) {
Y.one (‘div.status’).setContent (‘ready!’);
new Y.Anim({ node: '#demo', to: {opacity: 0} });
});
Sandboxing modules
var Y = new YUI();Y.use(‘node’, ‘anim’, function (Y) {
Y.one (‘div.status’).setContent (‘ready!’);
new Y.Anim({ node: '#demo', to: {opacity: 0} });
});
Sandboxing modules
( new YUI ).use(‘node’, ‘anim’, function (Y) {
Y.one (‘div.status’).setContent (‘ready!’);
new Y.Anim({ node: '#demo', to: {opacity: 0} });
});
Sandboxing modules
Different sets of modules
YUI 3 Modules
Different sets of modules
YUI 3 Modules
Community modules
gallery-*
Different sets of modules
YUI 3 Modules
Community modules
gallery-*
Project modules project-*
Community modules
Time Picker
Accordion / Node Accordion
YQL
Project modules
How to use Custom Modules in YUI 3?
Custom Module Registration
- By seed (YUI Loader) YUI().use …
- By inclusion register then YUI().use …
- By configuration YUI( /* config */ ).use …
Registration by seed
<script src=”http://yui.yahooapis.../yui-min.js”></script>
<script>YUI().use (‘node’, ‘anim’, function (Y) {
new Y.Anim({ node: '#demo', to: {opacity: 0} });
Y.one (‘div.status’).setContent (‘ready!’);
});</script>
Registration by inclusion
<script src=”http://yui.yahooapis.../yui-min.js”></script>
<script src=” http://yui.yahooapi.../build/gallery-yql/gallery-yql.js”></script>
<script>
YUI().use (‘gallery-yql’, function(Y) {
new Y.yql('select * from github.user.info where (id=”caridy")', function(r) { r.query; // The result });
});</script>
Registration by configuration
<script src=”http://yui.yahooapis.../yui-min.js”></script><script>YUI({ modules: { 'gallery-yql': { fullpath: 'http://yui.yahooapi.../build/gallery-yql/gallery-yql.js', requires: ["get","event-custom"] } }}).use (‘gallery-yql’, function(Y) { new Y.yql('select * from github.user.info where (id=”caridy")', function(r) { r.query; // The result });});</script>
Organizing configuration
- Global object called “YUI_config” (YAHOO_config in YUI 2.x)
- Multiple config objectsYUI( c1, c2, c3, .., c5 ).use
Organizing configuration (cont.)
YUI_config = { modules: {
‘foo’: { fullpath: ‘/js/foo.js’, requires: [‘node’] },‘bar’: { fullpath: ‘/js/bar.js’, requires: [‘anim’, ‘foo’] }
}};
YUI().use (‘foo’, function (Y) { /* … */});
YUI( MY_YUI_config, { /* c2 */ } ).use (‘bar’, ‘c2-mod’, function (Y) { /* … */});
How to build a Custom Modules?
Defining a module
YUI.add(‘foo’, function (Y) {
// Add the code for your module here. // Here Y is the YUI instance this module // was added to.
}, ‘0.0.1’, { requires: [‘node’] });
Different types of implementations
Utilities Y.oneY.ioY.youtube.play
Different types of implementations
Utilities Classes
Y.AnimY.App.Box
Different types of implementations
Utilities Classes
Plugins
Y.Plugin.NodeAccordion
Different types of implementations
Utilities Classes
Plugins
Mashups &
Legacy
Utilities
YUI.add(‘gallery-youtube’, function (Y) {
Y.youtube = { play: function (node, vid) { /* … */
} };
}, ‘0.0.1’, { requires: [‘node’] });
Classes
Classes (cont.)
YUI.add(‘project-counter’, function (Y) {
function Counter ( config ) {Counter.superclass.constructor.apply(this, arguments);
} Counter.NAME = "counter"; // used as prefix for events Counter.ATTRS = { timestamp: { /* config */ } };
Y.extend(Counter, Y.Base, {initializer : function( cfg ) { /* */ },destructor : function() { /* */ }
});
Y.Counter = Counter; // injecting the new class into the sandbox
}, ‘0.0.1’, { requires: [‘base’, ‘node’] });
Classes (cont.)
YUI().use(’project-counter', function (Y) {
var counter = new Y.Counter({ timestamp: ‘123467890’
});
});
How to use and build plugins in YUI 3?
Plugins: YUI Node
YUI().use('anim', ’gallery-node-accordion', function (Y) {
var node = Y.get("#myaccordion");node.plug( Y.Plugin.NodeAccordion, {
anim: Y.Easing.backIn }); });
Plugins (cont.)
var counter = new Y.Counter({ timestamp: ‘123467890’
});counter.plug(Y.Plugin.AnimCounter, {
effect: Y.Easing.backIn });
Plugins (cont.)
YUI.add('gallery-node-accordion', function(Y) { function NodeAccordion (config) { NodeAccordion.superclass.constructor.apply(this, arguments); } NodeAccordion.NS = "NodeAccordion” NodeAccordion.ATTRS = {}; Y.extend(NodeAccordion, Y.Plugin.Base, {
initializer : function( cfg ) { /* */ },destructor : function() { /* */ }
}); Y.namespace('Plugin'); Y.Plugin.NodeAccordion = NodeAccordion;
}, ’0.0.1' ,{requires:["plugin"]});
How to work with mashups and legacy code in YUI 3?
Mashups
- Using multiple modules
- Include external dependencies (swfobj.js)
- Enhance the DOM structure
- Defining some listeners
Mashups
YUI().use (‘event’, ‘gallery-node-accordion’, ‘project-counter’, function (Y) {
/* mashup these modules to enhance the LHS of a page */
});
Mashups (cont.)
YUI().use (‘project-layout-lhs’, function (Y) {
Y.lhs.doit ({page: ‘products’
});
});
Legacy
- YUI 2.x Tabview- Custom Survey System
Legacy (cont.)
Why to wrap the code?
- Benefit from YUI 3 lazy loading process
- Support incremental migration
- Unique repository per project
Legacy (cont.)
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis…/build/tabview/assets/skins/sam/tabview.css”><script type="text/javascript" src="http://yui.yahooapis…/build/utilities/utilities.js"></script><script type="text/javascript" src=“http://yui.yahooapis…/build/tabview/tabview-min.js"></script>
<script type="text/javascript"> YAHOO.util.Event.onDOMReady(function() {
var t = new YAHOO.widget.TabView("demo");
/* mashup these modules to initialize the tabview and handle the surveys */
}); </script>
Legacy (cont.)
YUI().use (‘node’, ‘yui2-tabview’, function (Y) {
Y.on("domready", function() { var t = new YAHOO.widget.TabView("demo");
/* mashup these modules to initialize the tabview and handle the surveys */
}); });
Legacy (cont.)
YUI().use (‘node’, ‘yui2-tabview’, ‘project-legacy-survey’, function (Y) {
// and now, survey is a YUI 3 Custom Module
});
Recommendations
- Check “Scalable JavaScript Application Architecture” presentation by Nicholas Zakas
- Do a little bit of analysis and design for your modules
- Decide ahead what type of implementation to use
- Consider plugins for advanced functionalities
- Organize your web app as a module repository
Conclusions
- Granularity is good for web applications
- Apps based on modules are easy to debug and test
- Try and share code thru YUI 3 Gallery
- Legacy code can be driven thru Custom Modules
Thanks!
Caridy Patinohttp://caridy.name/http://github.com/caridyhttp://twitter.com/caridy