Passing params to template and retain this

Hi meteorites,

I’ve searched for a solution on the www, did not succeed sadly. Before declaring my problem here is some code I have trouble with:

<i class="mdi-action-account-circle prefix"></i>
  <label for="firstName" class="{{active}}">{{i18n 'persons.firstName'}}</label>
  <input id="firstName" type="text" value="{{get 'firstName'}}">
</div>

Having a html file full of that code for multiple inputs is tedious, so I thought it might be clever to use templates for it:

{{> textInput propertyName='firstName' iconName='mdi-action-something' langString='persons.firstName'}}

All my inputs are wrapped inside

{{#with personDetails}}

so I can have a database instance of a person inside all my template helpers 'n stuff.

Now, most of you might know, that using variables in template inclusions overrides this (took me a while to figure that out). Id like to find a way to merge all parameters into this (which has to be the instance of a person object from the collection), or better have it in a variable like parameters inside helpers. So I can create something like this

<template name="genericInput">
  <div class="input-field col {{inputSize}}">
    <i class="{{iconName}} prefix"></i>
    <label for="{{propertyName}}" class="{{active}}">{{i18n langString}}</label>
    <input id="{{propertyName}}" type="text" value="{{get propertyName}}">
  </div>

</template>

Get looks like this:

Template.registerHelper("get", function(property) {
  if (this[property]) {
    return this.get(property);
  }
});

this in the helper is also the instance of a person from the collection.

The i18n function1 in this code is working, and they seem to have found a solution which looks something like this:

/*
  Register handlebars helper
*/
if(Meteor.isClient) {
  if(UI) {
    UI.registerHelper('i18n', function () {
      return i18n.apply(this, arguments);
    });
  } else if(Handlebars) {
    Handlebars.registerHelper('i18n', function () {
      return i18n.apply(this, arguments);
    });
  }
}

but I don’t really understand what’s happening there.

UI and Handlebars.registerHelper are aliases for Blaze and Blaze.registerHelper:

https://github.com/meteor/meteor/blob/devel/packages/blaze/backcompat.js#L1-L7

And to add to the fun, Template.registerHelper is an alias for Blaze.registerHelper:

https://github.com/meteor/meteor/blob/devel/packages/blaze/template.js#L539

So the code sample is dealing with back-level compatibility, and can be simplified (assuming a recent codebase) to:

/*
  Register global helper
*/
if(Meteor.isClient) {
 Template.registerHelper('i18n', function () {
    return i18n.apply(this, arguments);
  });
}

(I have used the documented form.)

The i18n helper you showed is using a classic “monkey-patching” trick for changing the behaviour of another function, which does not have the exposed methods you need.

Not sure if any of that helped!

Hi Rob,

thanks for your reply.

a little, I was wondering what the differences between UI, Blaze and Template were.

But I’m sure monkey-patching is not helping me with the template arguments and retaining this (as you already stated if I’m not mistaken :smile:)

Maybe there is a best practice I didn’t catch yet on how to to passing arguments to templates while retain the original this context, defined with {{#with ...}}?

Hey,

in case someone reads this: I got it figured out. I’m using the .. property in the template call to gain access to the parents properties. Like this

{{> textInput propertyName='firstName' iconName='mdi-action-something' langString='persons.firstName' parent=.. }}

And then using it in the template like this:

<template name="genericInput">
    <div class="input-field col {{inputSize}}">
    <i class="{{iconName}} prefix"></i>
    <label for="{{propertyName}}" class="{{active}}">{{i18n langString}}</label>
    <input id="{{propertyName}}" type="text" value="{{parent.get propertyName}}">
</div>
1 Like

you could always use {{> template data=this …}}
and than access it as {{data.something}} what was before {{this.something}} and you could use it as {{something}} before

Thanks. Seems that .. and this are synonymous.