Handlebars helper - passing an inline array

6,162 views
Skip to first unread message

Mike Fitzgerald

unread,
Feb 23, 2014, 8:17:27 AM2/23/14
to meteo...@googlegroups.com
Is there a way to do something along the lines of

{{ customHelper ['a','b','c'] }}

When I try it, the argument in my helper is undefined. If I change it back to just a regular string, the argument has the correct value.

Mike Fitzgerald

unread,
Feb 23, 2014, 8:29:48 AM2/23/14
to meteo...@googlegroups.com
For the time being I've modified it to use a regex so that I can just pass a string with the | to do multiple checks. It works, but then I run into another issue.

How can you do something like:

{{#each model.items}}
    {{ customHelper 'demo|{{name}}*' }}
{{/each}}

where the first item in the list is static, but the 2nd condition is based on the current context item (from the foreach). is this possible?

Abigail Watson

unread,
Mar 5, 2014, 2:35:24 PM3/5/14
to meteo...@googlegroups.com
Not right now, although there's talk about it being included in future releases of Spacebars.  But why would you want to do something like this?   It may seem very convenient to do something like this, but I'd suggest that maybe it confuses the object model and the controller a bit too much.  In my opinion, putting arguments and inline JS to handlebar helpers is a slippery slope that leads towards implementing the bad parts of PHP.  

 

On Sunday, February 23, 2014 8:17:27 AM UTC-5, Mike Fitzgerald wrote:

Mike Fitzgerald

unread,
Mar 5, 2014, 2:41:14 PM3/5/14
to meteo...@googlegroups.com
So that I can do a quick compare against multiple string values at once. For something that doesn't require a controller, but also doesn't have it's business logic in the view, but in the helper method.

I have a helper that checks iron routers current route to see if the current route name matches a name or names. This helps for setting the active class on the navigation links.

So saying {{isActive ['products', 'newProduct', 'editProduct']}} in my navigation partial view would have been convenient. However, I changed it to use a regex and it's even easier / scalable now. You can either just have products or use | to include additional route names. 

Abigail Watson

unread,
Mar 5, 2014, 3:09:26 PM3/5/14
to meteo...@googlegroups.com
That's what Handlebars.registerHelper() is good for.  You'll find that this approach lets you reuse your templates more, because it separates the controller logic from the object model. 

Handlebars.registerHelper('isActive', function() {
  if(checkRoute(['products', 'newProduct', 'editProduct'])){
    return true;
  }else{
    return false;
  }
});

Also, I'd gently suggest that referring to the template as a partial view - while very Ruby/Ember/Angular centric - isn't designing for mobile or gui-centric.  And since Meteor is an isomorphic framework, using Javascript on both server and client, it's important to reconcile the server side MVC patterns with client-side MVC patterns. 

I've found that it really helped to start thinking of the templates as partial (object) models, rather than partial views.  Once CSS/LESS is added into the mix, and one starts designing for multiple hardware platforms, it becomes apparent how there can be multiple views of the same workflow component (what you'd call styling or presentation of the same view).  







--
You received this message because you are subscribed to a topic in the Google Groups "meteor-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/meteor-talk/7A6keZhFLh4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to meteor-talk...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Mike Fitzgerald

unread,
Mar 5, 2014, 3:19:54 PM3/5/14
to meteo...@googlegroups.com
Very interesting points that you bring up. Thank you for that, I appreciate it. 

As for the helper. I'm not going to make a helper for each navigation item. So instead, I do use the registerHelper, but it allows for regex.

Handlebars.registerHelper('isActive', function(expression){
   var reg = new RegExp(expression, 'i');
   return reg.test(Router.current().route.name);
}

Allowing me to use it in my partial  (only to separate concerns so that my main layout doesn't contain so much and I can easily move components around)
<nav>
<ul>
    <li class="{{isActive 'dashboard'}}"><a>...</a></li>
    <li class="{{isActive 'products|newProduct|editProduct'}}"><a>...</a></li>
</ul>
</nav>

Abigail Watson

unread,
Mar 5, 2014, 3:53:51 PM3/5/14
to meteo...@googlegroups.com
Interesting.  I can certainly see your rational there.  And you're certainly not alone.  Personally, I've tended towards simply adding extra helpers, like so:

<nav>
  <ul>
    <li id="homePageLink" class="{{isHomePageLinkActive}}"><a>...</a></li>
    <li id="helperPageLink" class="{{isHelperPageLinkActive}}"><a>...</a></li>
  </ul>
</nav>

It's maybe a bit more boilerplate upfront, but I find it keeps the separation of logic real clean, and allows more fine-grained control in the long run.  But it does lead to a lot of links, and I've been thinking of doing a refactor to something using an argument and more like what you're doing.  

Do you color code your files?  How many files are in your project?  I ask, because once I started getting 50+ files in a project, color coding became essential to manage everything, which then turned into an aversion to doing inline javascript in HTML.  

The regex is clever, btw.  


Mike Fitzgerald

unread,
Mar 5, 2014, 4:06:47 PM3/5/14
to meteo...@googlegroups.com
Please excuse my ignorance, but I don't know what you mean by colour coding my files?

I have quite a few files, I've never counted.. but it's getting up there. I haven't had any issues yet findings things using specific patterns. Even on the client side I'm following an MVCish type structure. 

I generally start my base structure off with the top level folders o

client
collections (sit outside and just wrap the necessary stuff in Meteor.isClient/isServer as I've had some issues with pubs/subs not working correctly when nesting them in the client/server folders)
server

inside client I have my views, helpers, controllers, and a single router.js file. Sometimes i'll have an index.js in the root of my client folder for any startup or very client specific stuff that doesn't relate to a controller or view or helper etc.

inside my views I break it up by resource, so clients, products etc.. in each I follow a crud naming convention. index, new, edit, delete. And for each view I have a js file for it's events etc. I had those separated at first, but it didn't feel right and was harder to navigate.

In server, I just have the index.js for server specific things, email templates (I use a meteor method or observe collections to send out emails automatically server side). 

Right or wrong (no idea as there doesn't seem to be a standard yet?), it's working for me so far. I've switched it up here and there and it's a continual learning experience. I try to find blog posts or other snippets from people about how they structure their meteor apps. 

Abigail Watson

unread,
Mar 5, 2014, 5:04:22 PM3/5/14
to meteo...@googlegroups.com
I just mean color coding files...  :)  I use Red for Javascript (Controller), Green for HTML (Object Model), and Blue for CSS/LESS (View).  

If you're using an IDE, you can take it a step further, and not just color code the file icons in the directory, but also choose color pallets for the different languages.  Being able to say 'oh, my view is in blue/purples, my model is in green/oranges, and my controllers are orange/reds'... well, it just helps keep everything organized.  

We were doing what you were doing, but hit a limit of about 80 or 100 files, which is when I started embracing color coding and code-overviews.   Now I'm up to about 200 files, and we're hitting another wall, and looking to do another refactor.  

Not sure what that's going to look like, but I know we need to take a few plays from the Ruby/Angular playbook, and flatten out our directory structure a bit, and put our HTML/CSS/JS in workflow folders.  And maybe look at adding arguments to some of our registered handlebar helpers.  But I don't want to loose the color coding and mental clarity of using HTML/CSS/JS as our MVC.  And that means avoiding inline JS and other extended handlebar arguments.  

So, just kinda mulling things over right now.  Thinking about how arguments to handlebar helpers affect color coding and template reuse, and the like....


Mike Fitzgerald

unread,
Mar 5, 2014, 5:41:53 PM3/5/14
to meteo...@googlegroups.com
Wow.. quite the project. Which IDE are you using? I like the sounds of the colour coding. I'm from a c# background.. so I only really used visual studio before. Now I'm trying sublime (currently using), brackets and webstorm. 

Is there any option to encapsulate some of the functionality (including views etc), into smart packages? I've been doing that for some specific functionality that isn't unique to my application, but that my application still needs to leverage. Anything app specific stays with my app. It has helped and I like that it keeps my app focused on what is unique to it and what it is meant to do.

If you figure out a great solution, I would love to read about it afterwards. 
Reply all
Reply to author
Forward
0 new messages