Lamma is a simple layout manager for your Meteor/Blaze applications. It provides you with a centralized structure to manage all the layouts in your application. You can use it independently, or integrate with Parrot for a super easy solution.
How to Use
First, define your layouts anywhere in the application:
1// All the fields here are option 2// If one is missing, Lamma will make reasonable assumptions 3Layout.register({ 4 body: { 5 default: "home", 6 notFound: "notFound", 7 processor: function (name) { 8 // we are using processor here 9 // just to prefix the template names 10 return "body_" + name; 11 } 12 }, 13 sidebar: { 14 default: "default", 15 notFound: "notFound", 16 processor: function (name) { 17 // we are using processor here 18 // just to prefix the template names 19 return "sidebar_" + name; 20 } 21 } 22});
Once you've defined your layouts, you just need to stick them in wherever you feel is right:
1<body> 2 {{#if currentUser}} 3 {{> navigation}} 4 <div class="bodyContainer"> 5 {{> Layout name="body"}} 6 </div> 7 <div class="sidebarContainer"> 8 {{> Layout name="sidebar"}} 9 </div> 10 {{else}} 11 {{> loginScreen}} 12 {{/if}} 13</body>
The layouts will automatically render their default views. To override the default:
1Layout.set('body', 'about') 2 3// or 4 5Layout.set({ 6 body: 'about', 7 sidebar: 'details' 8});
Whenever you set your layouts, it will:
- take the value you provide it
- run the value through the processor function
- check if the appropriate template exists
- if the template exists, render it
- if the template does not exist, render the error template (if specified)
In this example, we use the processor function to prefix each layout template with either body_
or sidebar_
. This ensures we never have a clash between the two template sets. However, you can run any kind of logic you would like there.
Since Lamma is powered by ReactiveDict, you can also use the get function to see what layout is being rendered:
1Layout.get('body'); // returns 'about' 2Layout.all(); // returns object
Finally, Lamma will provide you errors for you in development mode if your layout is not properly configured.
How to Use With Parrot
Parrot is a new, simple route for Meteor that works great with Lamma.
Parrot manages the values set on the URL, you can easily connect it with Lamma to "automate" your layout renderings. The idea is, rather than use Layout.set
, we would watch some of the values from Parrot and use that to render the appropriate views. All you have to do is tell Lamma to be friends with Parrot:
1Layout.register({ 2 body: { 3 default: "home", 4 notFound: "notFound", 5 // By passing in `true` as a value for Parrot, 6 // you tell the layout manager to use the 7 // section of the URL instead of a parameter 8 Parrot: true, 9 processor: function (name) { 10 return "body_" + name; 11 } 12 }, 13 sidebar: { 14 default: "default", 15 notFound: "notFound", 16 Parrot: "sidebar", 17 processor: function (name) { 18 return "sidebar_" + name; 19 } 20 } 21});
In this case, having the following url:
http://meteor.toys/#documentation/sidebar=compatibility
Would be the same as calling:
1Layout.set({ 2 "body": "documentation", 3 "sidebar": "compatibility" 4});
However, by integrating the two, you don't have to call that function over and over again. Between the default
view, the notFound
view, and the development mode errors, you can trust everything to work right.
What Do Parrots Have to Do With Lammas?
In an ecological sense, absolutely nothing that we know of yet (unconfirmed). In a Meteorological sense, however, you get a really thin router and view system that you can use to predictable manage your application.
Between onRendered, onDestroyed, and template-level subscriptions, you should be able to build your views as self-contained units and pop them in whenever you need them with minimal effort.
Getting Creative with Lamma Processor
You can run virtually any function with-in the processor. In my examples, I just prefix the templates to keep naming simple and avoid clashes. In another case, you might prefer to whitelist which templates may be viewable to which uses:
1 2Layout.register({ 3 body: { 4 default: "home", 5 notFound: "notFound", 6 // By passing in `true` as a value for Parrot, 7 // you tell the layout manager to use the 8 // section of the URL instead of a parameter 9 Parrot: true, 10 processor: function (name) { 11 if (Meteor.user().isAdmin) { 12 return "body_" + name; 13 } else { 14 return "body_notAuthorized"; 15 } 16 } 17 }, 18 anotherExample: { 19 default: "home", 20 notFound: "notFound", 21 // By passing in `true` as a value for Parrot, 22 // you tell the layout manager to use the 23 // section of the URL instead of a parameter 24 Parrot: true, 25 processor: function (name) { 26 adminTemplates = ['view', 'edit']; 27 userTemplates = ['view', 'edit','delete'] 28 29 if (!whitelist(adminTemplates, name)) { 30 return "body_notAuthorized"; 31 } 32 if (Meteor.user().isAdmin) { 33 return "body_" + name; 34 } else { 35 return "body_wtf"; 36 } 37 } 38 }, 39})
That way, if someone tries to get clever with hacking your URLs, you can make them feel even more challenged.