Having fun with Mooml & Twitter

Feb 19 2010 Published by Eneko Alonso under uncategorized

Mooml is a templating engine for Mootools. With it, you can create HTML from Javascript using a very clean syntax. Plus, it is extremely useful when you have to generate repeating elements, since Mooml automatically renders arrays of data multiple times. Let’s see an example.

Searching Twitter

Nowadays there are a lot of APIs out there that support JSON or JSONP, which we can use directly from the front end using Javascript. Also, there are other APIs that return tons of JS data, like Google Maps. In this example we are going to be searching Twitter and displaying the search results in a container div, properly rendered as HTML.

The url for searching Twitter is http://search.twitter.com/search.json?q=mootools&show_user=true (searching for Mootools in this case). Check the output:

  1. {
  2.   "results":[
  3.     {
  4.       "profile_image_url":"http://a3.twimg.com/profile_images/547672997/twitterProfilePhoto_normal.jpg",
  5.       "created_at":"Fri, 19 Feb 2010 17:08:55 +0000",
  6.       "from_user":"digitalr3bel",
  7.       "to_user_id":1212494,
  8.       "text":"@davidwalshblog Hi David – im a big fan of your site! Can you recommend a good MooTools tutorial for someone who can already program? thx",
  9.       "id":9343656026,
  10.       "from_user_id":23704390,
  11.       "to_user":"davidwalshblog",
  12.       "geo":null,
  13.       "iso_language_code":"en",
  14.       "source":"<a href="http://apiwiki.twitter.com/" rel="nofollow">API</a>"
  15.     }
  16.     // More results here…
  17.   ],
  18.   "max_id":9343656026,
  19.   "since_id":0,
  20.   "refresh_url":"?since_id=9343656026&q=mootools",
  21.   "next_page":"?page=2&max_id=9343656026&q=mootools",
  22.   "results_per_page":15,
  23.   "page":1,
  24.   "completed_in":0.0352710000000001,
  25.   "query":"mootools"
  26. }

We want to render each result inside out container div. On this example, we will just render the user name, user image and message text. Here is our Mooml template:

  1. Mooml.register('twitter-search-result', function(entry) {
  2.   div({id: "tweet-" + entry.id},
  3.     img({src: entry.profile_image_url, alt: entry.from_user}),
  4.     span(entry.from_user),
  5.     p(entry.text)
  6.   );
  7. });

Since all results are returned into an array, we can pass it directly to Mooml which will render all of the elements in it:

  1. // Data is the JSON response from Twitter
  2. Mooml.render('twitter-search-result', data.results);

So, let’s do a live test. Type something you want to search for and hit the search button to see Mooml in action :)

Search:

How cool is that?

The code

Ok, so here is the whole code I have used in this post for this mini-demo:

  1. <script type="text/javascript" src="http://enekoalonso.com/lib/mootools-1.2.4-core-nc.js"></script>
  2. <script type="text/javascript" src="http://enekoalonso.com/lib/mooml.js"></script>
  3. <script type="text/javascript">
  4. Mooml.register('twitter-search-result', function(entry) {
  5.   div({id: "tweet-" + entry.id},
  6.     img({src: entry.profile_image_url, alt: entry.from_user}),
  7.     span(entry.from_user),
  8.     p(entry.text)
  9.   );
  10. });
  11.  
  12. function searchTwitter() {
  13.   new Element('script', {
  14.     type:'text/javascript',
  15.     src:'http://search.twitter.com/search.json?q={text}&show_user=true&callback=renderData'.substitute({
  16.       text:$('twitter-mooml-search').get('value')
  17.     })
  18.   }).inject(document.head);
  19. }
  20.  
  21. function renderData(data) {
  22.   $('mooml-twitter-demo').empty().adopt(Mooml.render('twitter-search-result', data.results));
  23. }
  24.  
  25. $('twitter-mooml-search-btn').addEvent('click', searchTwitter);
  26. searchTwitter();

As you can see, the code is very basic and so is the Mooml template. The coolest thing here is that you don’t need to iterate over the results to render each element.

Have fun!

No responses yet

Mooml.globalize(): Mooml template functions going global

Feb 01 2010 Published by Eneko Alonso under uncategorized

Since version 1.0.9, Mooml includes a new feature: globalize. It maybe handy for some websites to globalize all the Mooml template functions (div, a, p, span…) to the window object scope, so they can be used anywhere in the code without the need of defining or evaluating a template.

For example, in normal Mootools code we would create a div like this:

  1.  // options can have attributes, css, events and more
  2. var mydiv = new Element('div', options);

With Mooml.globalize() we can do this:

  1. Mooml.globalize(); // Only need to call this once
  2. var mydiv = div(options); // Same options as Mootools new Element()

Mooml globalized functions can also have nested elements, which makes very easy to create dom elements:

  1. var mydiv = div(options,
  2.  p('First paragraph'),
  3.  p('Second paragraph'),
  4.  div('Nested div:',
  5.   span('div content')
  6.  ),
  7.  Mooml.render('nested_template'),
  8.  'Some <b>inline</b> <em>html</em> too'
  9. );

Will generate the dom elements for this html:

  1. <div>
  2.  <p>First paragraph</p>
  3.  <p>Second paragraph</p>
  4.  <div>Nested div:
  5.   <span>div content</span>
  6.  </div>
  7.  <!– nested template here –>
  8.  Some <b>inline</b> <em>html</em> too
  9. </div>

Elements created by Mooml template functions are not automatically injected in the DOM. They are just created like when you use new Element().

Please be aware that using Mooml.globalize() feature will pollute the window object scope, overriding any methods with the same name and/or possibly conflicting with other Javascript libraries. As a tip, Mooml.tags can be edited before calling Mooml.globalize(), so only functions for those tags we are interested on will be created.

No responses yet

Detecting when CSS gets loaded by the browser with Mootools and Asset.css

Jan 27 2010 Published by Eneko Alonso under uncategorized

Asset.css claims to have an onload event in Mootools documentation, but sadly, not all browsers support this feature. Even worse, browsers like Chrome seem to support the event, but never fire it.

After some research and testing at work, we have come up with a solution that overrides Asset.css to detect when CSS gets loaded by the browser using the onload event in those browsers that support it (Internet Explorer and Opera) and doing polling in those that do not (Chrome, Safari and Firefox). Here is the code:

  1. // Add callback support to Asset.css for all browsers
  2. Asset.css = function(source, onLoad) {
  3.   var link = new Element('link', {
  4.     rel: 'stylesheet',
  5.     media: 'screen',
  6.     type: 'text/css',
  7.     href: source
  8.   });
  9.  
  10.   if (("onload" in link) && !Browser.Engines.webkit()) {
  11.     if (onLoad) link.onload = onLoad;
  12.   } else {
  13.     (function() {
  14.       try {
  15.         link.sheet.cssRules;
  16.       } catch (e) {
  17.         setTimeout(arguments.callee, 100);
  18.         return;
  19.       };
  20.       if (onLoad) onLoad();
  21.     })();
  22.   }
  23.  
  24.   link.inject(document.head);
  25.   return link;
  26. }
  27.  
  28. // Load some CSS and show an alert when done
  29. var mycss = new Asset.css('http://example.com/style.css', function() {
  30.   alert('CSS loaded!');
  31. });
  32.  
  33. // Unload the css
  34. mycss.destroy();

Enjoy!

No responses yet

Finally: Singletons, the Mootools way

Jan 18 2010 Published by Eneko Alonso under uncategorized

I have been using for a while the “new new Class” syntax to create singletons on the projects I am working on. This is for many reasons, but specially because I didn’t like other solutions like Class.Mutators, Class.Oclude or extending a plain object with $extend().

Now, after discussing a little bit on the Mootools email list about what was the best way to create singletons, I have created Class.Singleton so we can create singletons the Mootools way. Here is how it works:

  1. var MySingleton = new Class.Singleton({
  2.     initialize: function(){
  3.         // code here
  4.     },
  5.     method1: function(){
  6.         // code here
  7.     },
  8.     method2: function(){
  9.         // code here
  10.     }
  11. });

Using inheritance, mixins, etc

Class.Singleton works like defining any other Mootools class using Class(), so we can have inheritance, mixins, etc.

  1. var BaseClass = new Class({
  2.     initialize: function() {
  3.         // Initialization code here
  4.         console.log('BaseClass initialized.');
  5.     },
  6.     method1: function() {
  7.         // some code
  8.     }
  9. });
  10.  
  11. var MySingleton = new Class.Singleton({
  12.     Extends: BaseClass,
  13.     initialize: function() {
  14.         this.parent();
  15.         console.log('MySingleton singleton initialized.');
  16.     },
  17.     method1: function() {
  18.         this.parent();
  19.         // more code
  20.     }
  21. });

Hope you like it!

Repository url: http://github.com/eneko/Class.Singleton

No responses yet

Mooml: Mootools markup language (intro)

Jan 17 2010 Published by Eneko Alonso under uncategorized

It was a month ago when I found about Jaml, an excellent small Javascript library created by Ed Spencer which allows generating HTML code using very nice and clean templates. At work we use Mootools in most of our projects, so I thought it would be nice to improve Jaml by taking advantage of the power of Mootools. And this is the result.

Mooml: Mootools markup language

What is Mooml? Mooml is a templating system that allows generating HTML snippets very easily, without all the ugly nested “new Element” calls or string concatenation. With Mooml you can save templates for later use or evaluate snippets on the fly.

Download: http://mootools.net/forge/p/mooml
Source: http://github.com/eneko/mooml

Let’s see an example

Required HTML:

  1. <div class="node">
  2.   <h2>Node Title</h2>
  3.   <p>Node body here.</p>
  4. </div>

Node title and body are variables, so let’s save them on a Json format for now.

  1. var data = {
  2.   title: 'Node Title',
  3.   body: 'Node body here'
  4. }

Using Mootools “new Element” we would have to code something like this:

  1. var el = new Element('div', {'class': 'node'}).adopt([
  2.   new Element('h2', {text: data.title}),
  3.   new Element('p', {text: data.body})
  4. ]);

That code is much better than plain Javascript, but still messy. We could use the new Elements.from included in Mootools More 1.2.4, but that would require us writing the html as a string, which rapidly gets messy concatenating variables, etc.

  1. var el = Elements.from('<div class="node"><h2>' + data.title + '</h2><p>' + data.body + '</p></div>');

With Mooml…

With Mooml, we can create a template for that piece of code, and reuse it later as many times as we need:

  1. Mooml.register('node', function(data) {
  2.   div({'class': 'node'},
  3.     h2(data.title),
  4.     p(data.body)
  5.   )
  6. });
  7. document.body.grab(Mooml.render('node', data));

We can also execute the template directly as a function:

  1. document.body.grab(Mooml.templates.node(data));

Finally, with Mooml we can evaluate templates on the fly, without having to store them for later:

  1. document.body.grab(Mooml.evaluate(function(data) {
  2.   div({'class': 'node'},
  3.     h2(data.title),
  4.     p(data.body)
  5.   )
  6. }, data));

More examples soon :)

One response so far

I never use $$ on my projects (and barely use $)

Jan 15 2010 Published by Eneko Alonso under uncategorized

On all the projects I’ve worked on, I always try to follow the MVC arquitectural pattern, separating the model from the view *and* creating a controller. It may be a simple controller in charge of a tab-set, or an accordion. Or it may be a full size controller in charge of the whole page structure, on sites that make an extensive use of javascript.

Either way, I always have a controller for a dynamic section of the page and the controller always works with the container of that section. If I need to reference any element inside the container I will use this.container.getElementById() or this.container.getElements(), which will do a search only on the child elements of the container and not on the whole dom tree of the page.

Yes, it is very usual to see nowadays code that alters the links of a page ('a'), images or whatever. Every time we use $ or we are searching the whole page. And coding like that is just a waste of resources.

No responses yet

Creating HTML blocks with Mootools

Sep 02 2009 Published by Eneko Alonso under uncategorized

Sometimes we need to create HTML from JS. There are multiple ways to do this, from using innerHTML to creating element by element appending child to parents, setting attributes, etc. And there are as many different opinions about what is the right way to do it.

Meanwhile, once thing I missed from jQuery, not available on Mootools, was the ability to do something like this:

  1. var element = jQuery('<div id="foo">bar</div>');

In Mootools, the equivalent should be:

  1. var element = new Element('<div id="foo">bar</div>');

But that does not work.

On the Mootools mailing list, someone was asking about how to implement this and we just found a different approach, which instead of using the Element class, extends the String class like this:

  1. String.implement({
  2.  toElement: function() {
  3.    return new Element('div', {html:this}).getFirst();
  4.  }
  5. });

Now you can do this:

  1. var element  = '<div id="foo">bar</div>'.toElement();

To try it, paste this snippet on Firebug’s console:

  1. String.implement({
  2.  toElement: function() {
  3.    return new Element('div', {html:this}).getFirst();
  4.  }
  5. });
  6. console.log('<div id="foo">bar</div>'.toElement().get('id'));

Nice, uh? Of course, the HTML can be as complex as you need and where do you get the content of the string is up to you :)

3 responses so far

Fixing issues with ‘change’ event on text fields ala Mootools

Aug 14 2009 Published by Eneko Alonso under uncategorized

Very nice snippet to solve a few annoying issues with the change event:
http://www.meiocodigo.com/2009/08/13/new-changed-event/

No responses yet

Setters & Getters on Mootools classes

Jul 20 2009 Published by Eneko Alonso under uncategorized

Although I haven’t need them for my classes, I thought it would be very cool to have the possibility to use them. Setters and Getters are very popular in modern programming languages, since they let you do some actions when a member/property of an object is being accessed or modified. Setters and Getters are native on Javascript objects.

  1. // Setter on plain JS
  2. var b = {
  3.   saveCount: 0,
  4.   set count (c) {
  5.     console.log('Setting count (B):' + c);
  6.     this.saveCount = c;
  7.   },
  8.   get count () {
  9.     console.log('count is being accessed (B)');
  10.     return this.saveCount;
  11.   }
  12. }
  13. b.count = 5;
  14. console.log("Count (B): " + b.count);

Well, Mootools objects created using Class do not support that syntax. Fortunately, we can use the __defineSetter__ and __defineGetter__ functions:

  1. // Setter in Mootools
  2. var A = new Class({
  3.   saveCount: 0,
  4.   initialize: function() {
  5.     this.__defineSetter__("count", this.setCount);
  6.     this.__defineGetter__("count", this.getCount);
  7.   },
  8.   setCount: function(c) {
  9.     console.log('Setting count(A):' + c);
  10.     this.saveCount = c;
  11.   },
  12.   getCount: function() {
  13.     console.log('count is being accessed (A)');
  14.     return this.saveCount;
  15.   }
  16. });
  17.  
  18. var a = new A();
  19. a.count = 5;
  20. console.log("Count(A): " + a.count);

Nice, uh?

No responses yet

Mootools stuff to review

Jul 15 2009 Published by Eneko Alonso under uncategorized

Two interesting things I have to review;
MooTools: Bubbling Controllers
MooTools: Ignoring the next click

No responses yet

Next »