Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass variables into templates in Meteor?

I've been experimenting with Meteor and ran into something I couldn't figure out. For fun, I was trying to make a slot machine. I had the following HTML:

<div class="slot-wrapper">
  {{> slot}}
  {{> slot}}
  {{> slot}}
</div>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{ number }}</span></div>
    <div class="divider"></div>
  </div>
</template>

I want to have a different number for each slot. Is it possible to pass variables into template? Something like this:

<div class="slot-wrapper">
  {{> slot 1}}
  {{> slot 2}}
  {{> slot 3}}
</div>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{ number i}}</span></div>
    <div class="divider"></div>
  </div>
</template>

Maybe I'm thinking about this the wrong way and there's a better way.

like image 736
Jordan Brown Avatar asked Apr 12 '12 16:04

Jordan Brown


3 Answers

All of the previous answers are overkill or outdated. Here's how you can pass static parameters into templates, directly from HTML+Spacebars code, as of Meteor 0.8.x:

<div class="slot-wrapper">
  {{> slot number="1"}}
  {{> slot number="2"}}
  ...
</div>

<template name="slot">
  <div class="number"><span>{{number}}</span></div>
</template>

All you have to do is pass key="value" parameters in the {{> template}} inclusion call:

{{> slot number="1"}}

Learn more at Spacebars Secrets: Exploring Meteor Templates.


If you want to pass the caller template's data to the child/nested/called template, here's how to do it: pass nothing. Instead, from the nested template, access the parent data context, ../:

<div class="slot-wrapper">
  {{> slot number="1"}}
  {{> slot number="2"}}
  ...
</div>

<template name="slot">
  <div>Machine name: {{../name}}</div>
  <div class="number"><span>{{number}}</span></div>
</template>
like image 66
Dan Dascalescu Avatar answered Nov 14 '22 14:11

Dan Dascalescu


Turns out there is another way.

I was trying to find out how to do this by googling various searches and found this question but nothing that suited my purpose. TomUnite's answer works unless you want to put the nested templates in different places in the parent template.

So after much searching I found 'an' answer in the meteor codebase. (Not saying it's the definitive answer but it does work)

<template name="slots">
  {{> slot one}}
  <div>..something else</div>
  {{> slot three}}
  {{> slot two}}
</template>

<template name="slot">
  <div class="slot">
    <div class="number"><span>{{number}}</span></div>
    <div class="divider"></div>
  </div>
</template>

As you see we can specify the template instances in any order. The second parameter is actually a variable that should be defined, so:

Template.slots.one = {
  number: 1
}
Template.slots.two = {
  number: 2
}
Template.slots.three = {
  number: 3
}

This could be made into more succinct code with a loop or maybe using the underscore.js function _.extend on the slots object. Also, We can pass multiple fields of data into these objects.

like image 14
Joc Avatar answered Nov 14 '22 15:11

Joc


I wanted to leave this as a comment, because it's just a clarification on Joc's answer, but couldn't, so here it is with plus the example I worked with.

Only ONE argument can be passed to the template :

{{> singleItemInfo arg1}}

this argument must be an object such as :

{
    number: 1,
    number2: 2,
    numberComposite: {
        subnum1: 10,
        subnum2: 20
    }
};

the argument values can be accessed via their keys, and the scope can be switched to get the subitems with the

{{#with numberComposite}}

Here's the full code for the example :

<html file>

<body>
    {{ itemsView }}
</body>

<template name="itemsView">
    {{> singleItemInfo arg1}}
</template>

<template name="singleItemInfo">
    arg1 = {{ number }}
    arg2 = {{ number2 }} 
    {{#with numberComposite}}
        subArg1 = {{ subnum1 }}
        subArg2 = {{ subnum2 }}
    {{/with}}
</template>

<javascript file>

Template.itemsView.arg1 = {
    number: 1,
    number2: 2,
    numberComposite: {
        subnum1: 10,
        subnum2: 20
    }
};

OUTPUT:

arg1 = 1 arg2 = 2 subArg1 = 10 subArg2 = 20 
like image 9
jay Avatar answered Nov 14 '22 15:11

jay