Search code examples
javascripthtmlmeteoriron-router

How to render templates into templates with IronRouter and Meteor


I read many posts on this, including a good tutorial but I still cannot find what is wrong with my code. My intention is to configure the web page I am designing to be able to work with Iron Router.

It basically displays a number of pictures with captions and, when the user selects one, a message is displayed in a new template and format (that is why I need Iron Router).

I am facing trouble in setting it up: the ApplicationLayout template should render the boost template for each user so all his/her pictures are displayed. However, when it is displayed, I get the html for body.html but not the one in boost.html.

The Java Script helpers and event handlers work fine; I have checked for that already. That is why I only include the code for body.html, boost.html and routes.js. Please note that the code corresponds to three different files: both html files are in the same folder (ui) and the js file is in the lib folder, all inside my project's directory.

Thanks in advance!

body.html

<template name="ApplicationLayout">
    <body>
    {{> sAlert}}
        <div id="background">
        <img src="http://s1.picswalls.com/wallpapers/2015/11/21/beautiful-motivation-wallpaper_10342177_288.jpg" class="stretch" alt="" />
    </div>
        <div class="container">
            <header>
                {{#if currentUser}}
                <h1>Your Boosts! ({{incompleteCount}})</h1>
                {{else}}
                <h1>Community Boosts!</h1>
                {{/if}}
                {{> undoRedoButtons}}

               {{> loginButtons}}

               {{#if currentUser}}
                <form class="new-boosts">
                    <input type="text" name="text" placeholder="Type to add a short description"/>
                    <input type="text" name="image" accept = "image/*" placeholder="Type to add a picture url"/>
                    <input type="number" name="importance" min = "0" placeholder="Type to choose an importance position"/>
                    <textarea class = "text-area" name="message" rows = "10" cols = "5" placeholder="Type a message for yourself"></textarea>
                    <input type="submit" value="Submit" class="new-boosts first">
                </form>
                {{/if}} 
            </header>
            <ul>
                {{#each boosts}}
                    {{> yield}}
                {{/each}}
            </ul>
        </div>
    </body>
    </template>

boost.html

    <template name="boost">

        <article class="image-with-header">
            <img class="image" src="{{image}}" />
        </article>

        <li class="{{#if private}}private{{/if}}">
            <button class="delete">&times;</button>

            {{#if isOwner}}
                <button class="toggle-private">
                {{#if private}}
                 Private
                {{else}}
                  Public
                {{/if}}
                </button>
            {{/if}}

            <span class="text"><strong>{{username}}</strong> - <input type="text" value="{{text}}" name="caption"> - <input type="number" value="{{importance}}" name="importance"> </span>
        </li>
    </template>

routes.js

Router.configure({
   layoutTemplate: 'ApplicationLayout'
});

Router.route('/', function () {
  this.layout('ApplicationLayout');
  this.render('boost');
});

Solution

  • I believe the problem is that you are using {{> yield}} inside an each loop. Try this:

    *.html

    <template name="ApplicationLayout">
        <body>
          {{!-- ... --}}
              <ul>
                {{> yield}}
              </ul>
          {{!-- ... --}}
        </body>
    </template>
    
    <template name="boosts">
      {{#each boosts}}
          {{> boost}}
      {{/each}}
    </template>
    
    <template name="boost">
      {{!-- ... --}}
    </template>
    

    *.js

    // in tempalte file
    Template.boosts.helpers({
      boosts() {
        // return boosts here
      }
    });
    
    // in router file
    
    Router.configure({
       layoutTemplate: 'ApplicationLayout'
    });
    
    Router.route('/', function () {
      this.render('boosts');
    });