Meteor's iron:router isn't doing {{renderRouter}} as expected or documented - meteor

I've got a very simple template problem going on that appears to be similar to this guy's problem, though I've tried to build a simple example to demonstrate the problem and hopefully have someone explain to me how to fix or work around it.
Although as I'm doing some online research, it may be that the official documentation is out of date with the code. The reason I haven't bought into accepting that just yet is that the problem seems to have existed for a while, the dates on such articles in forums appears to be fairly old, and there's talk of it being fixed. There's also talk the feature is gone. What's the new way, if there is one?
I'm using Meteor 0.9.0.1 with iron:router 0.9.1. Specifically, I set up my project like this:
$ meteor create ironTest
$ cd ironTest
$ meteor add iron:router
$ meteor
Pointing my browser at http://localhost:3000/ as instructed, shows the default project. So far so good.
Now make ironTest.html contain this:
<body>
<h1>Before</h1>
{{renderRouter}}
<h2>Afterward</h2>
</body>
<template name="hello">
Hello Template
</template>
<template name="goodbye">
Goodbye Template
</template>
Make ironTest.js contain this:
Router.configure({
autoRender: true // we will experiment with this Boolean shortly
});
Router.map(function () {
this.route('hello');
this.route('goodbye');
});
If you go to the routes http://localhost:3000/hello and http://localhost:3000/goodbye, you'll see the templates correctly render as expected and documented, appended to the <body> element, so it appears after the <h2> element.
According to the current documentation for iron:router, one should be able to set the autoRender property to false, and the template should no longer be appended to the <body> element, but rather be injected where the Handlebars (okay, Spacebars) element {{renderRouter}} is, that is, between the <h1> and <h2> elements.
When I try this, visually it doesn't do anything. Opening a JavaScript Console to look at errors shows none. Although, by deliberately going to an invalid route it will show a missing template router exception, showing the routing code is indeed working.
Does anyone know how to coerce the code above into working?
For the curious, I've got a working simplistic equivalent that might be of use to others working this problem.
This new ironTest.html uses a template (for a layout) with no <body>:
<template name="main">
<h1>Before</h1>
{{> yield}}
<h2>Afterward</h2>
</template>
<template name="hello">
Hello Template
</template>
<template name="goodbye">
Goodbye Template
</template>
This ironTest.js instead uses a layout:
Router.configure({
layoutTemplate : 'main'
});
Router.map(function () {
this.route('hello');
this.route('goodbye');
});
It's worth an aside that this solution doesn't work for me, as I don't want a global layout, and have concern that riddling layouts in the route themselves is a tighter coupling than desired for my purposes.
I'm currently looking for a way to dump debugging log information from the Router as it performs transitions, but that's another story.

Related

Meteor & Flow Router: Marking Dynamically generated paths as 'active'

Needless to say, my experience with Meteor is lacking. I come from a Rails background, where you can do a lot more logic (and magic) in your views than Meteor.
The situation: I've got some routes that look like /things/:_id, and I've named that route 'thing' because it shows only one thing of a user's many owned things:
FlowRouter.route('/things/:_id', {
name: 'thing',
action() {
BlazeLayout.render('appPage', {app: 'thing', sidebar: "thingsListOnThing", header: 'thingTitle'});
}
});
As you can see, I'm also loading a template I've built to list all of the user's owned things on the sidebar for easy navigation. That template, thingsListOnThing is the target of this question.
Get the gist? I'm able to mark the route that dislays a template with a complete list of a user's things as active using zimme:active-route like so:
// A list of all a user's things
<div class="{{isActiveRoute name='things' class='is-active'}}">
List of Things
</div>
This package is great, but it won't help me with routes that look like /things/:_id because, then every link to each individual thing would be is-active on any thing page, not just the one where the current path's :_id matches the _id of the active thing.
I'm really kind of stuck here. My first guess would be to use template helpers, but I'm confused as to where to get started with that.
If need be, please as me to upload any piece of my code you require. I figured it's such a generic question that you guys probably don't need to see all of my code to understand what I'm trying to accomplish.
Using: zimme:active-route
Template Helpers
Template.listOfThings.helpers({
activeListClass(page) {
const active = ActiveRoute.name('thing') && FlowRouter.getParam('_id') === this._id;
return active && 'active';
},
});
Template HTML:
<a class="{{isActivePath 'thing'}}" href="/things/{{_id}}">
<div class="thingListItem {{activeListClass page}}">
{{title}}
</div>
</a>

Why not do without the body tag and use Meteor.startup template instead?

Using meteor release blaze-rc1, does this make sense:
client side
Meteor.startup(function () {
UI.insert(UI.render(Template.main), document.body);
});
<template name="main">
this is the starting template
</template>
Are there side effects? Seems to work fine, and I don't have to worry about chasing down the body tag mixed in my templates. Sorry if this is a noob question, it's my first project with meteor.
Having body tags sprinkled in your code (and head tags for that matter) and expecting it to land in the correct order, feels a little bizarre. Must be my file / page world view.. perhaps I'm just old.
If you don't specify a body tag Meteor automatically puts one in and then renders your template within that body tag.
I don't see any reason why you would really need to include the <body> tag at all. It certainly doesn't seem to do any harm.

Meteor - Understanding template 'rendered' calls

I'm a bit of a newb in Meteor so this is possibly a trivial question for you Meteor masters out there.
I use a template which has a couple of child templates:
<template name="parent">
{{> child1}}
{{> child2}}
</template>
I noticed that parent.rendered and child1.rendered functions are invoked when reactive data under child2 changes.
My understanding of meteor docs is that only child2.rendered should be called. So, what I am seeing should not happen, yet for a reason which is beyond me, it does.
To rule out any noise, I gutted the child1 template (to contain only an empty div). Still, its rendered function is called.
Can anyone provide insight?
As of Meteor 0.7.0.1, the parent template will be re-rendered but the sibling child templates will not.
Here is a simple example Meteor app that shows this in action:
https://github.com/alanning/meteor-subtemplate-isolate-test
Keep in mind that Meteor UI is getting a drastic overhaul before Meteor 1.0 lands so a lot of things may change with respect to how templating works.
Just hypothesizing here, but I think the entire page rerenders when any reactive data changes. For example, if you were to have data in Session.get('test') and the only time the value of that is inserted into the DOM is in child2, I believe the entire page still rerenders.

Using external scripts in Meteor executed from "script src"

I want to use a script on my web site and I know that I must put all scripts separated from the template in a .js file. But I don't know how to do it this time when the script is executed directly in the script src:
<script type="text/javascript" src="http://svenskfotboll.se/widget.aspx?scr=table&ftid=39662&b1=%23006bb7&f1=%23ffffff&b2=%23bfd4f3&f2=%23000000&b3=%23ffffff&f3=%23000000&b4=%23ececec&bo=%23ffffff&s=1"></script>
What is the best practice to get it to work in Meteor?
I'd go to that url, get that script, and save it in a file in your project. However, there wasn't anything actually at that url when I just checked it out. That would definitely be a problem too :)
EDIT: You can also stick in the head tag.
EDIT 2: if you want it to display in a template, like if it's a widget such as yours, you can insert it manually every time the template re-renders. It's pretty simple, actually. First we've got the template code:
Template.myWidget.rendered = function () {
$('#my-widget').html('<script src="src-here.js"></script');
}
And then the actual template:
<template name="myWidget">
<div id="my-widget">Loading...</div>
</template>
Finally, wherever you want the widget to appear in your html, just insert {{>myWidget}}
Use jQuery.getScript(): http://api.jquery.com/jquery.getscript/
In your case:
$.getScript( "http://svenskfotboll.se/widget.aspx?scr=table&ftid=39662&b1=%23006bb7&f1=%23ffffff&b2=%23bfd4f3&f2=%23000000&b3=%23ffffff&f3=%23000000&b4=%23ececec&bo=%23ffffff&s=1" );
You can also specify callback for success or failure (please see documentation linked above).

Meteor Spiderable not returning full content?

The following is my current code,
https://github.com/daslicht/kiss
After cloning it to my server I have added the spiderable package
and added phantomjs to the $PATH.
The basic structure of my app is essentially a Master Details layout,
on the left we have a list of headlines(Master)
and on the right the according details to each Headline.
So far so good..., when I call one page with:
http://78.47.126.11:3000/?_escaped_fragment_=blog/SbZayHyqKmZhCEHme/1
I get my Headlines displayed but not the according Details.
Do you have any idea what could be going wrong ?
Currently it is running as bundle with forever.
Best Regards
Marc
If think the Spiderable package won't show stuff from MongoDB, only static template-stuff.
So in this example only the static stuff will show, not the DB-loop:
<template name="main">
{{> thisWillBeOutputted}}
</template>
<template name="thisWillBeOutputted">
<h1>This will be displayed, sweet!</h1>
{{#each thisLoopFetchesStuffFromDBAndWontShow}}
<!-- stuff in this loop won't be displayed :( -->
<p>Something which won't be displayed: {{dbDoc.something}}</p>
{{/each}}
</template>
To summarize (what I believe is correct):
The Spiderable package better than not displaying anything for bots (which is the case with vanilla-meteor), but it's not as good as a good-old-PHP/whatever-site.
EDIT
I misunderstood your problem. What I would do is add <meta name="fragment" content="!"> to your head instead of going with the escaped-fragment thing. More here: https://developers.google.com/webmasters/ajax-crawling/docs/getting-started
I'm still pretty sure your DB-stuff won't get picked up by Google though. But I could be wrong!
If I understood, your app is ignoring 'blog/SbZayHyqKmZhCEHme/1'.
The error is because:
https://github.com/meteor/meteor/issues/487
The spiderable package does not currently reattach the escaped
fragment back onto the url sent to phantomjs, so it's not possible for
the page to display the correct content.
For example if googlebot encounters a url:
http://domain.com/#!page
It will make a request from the server:
http://domain.com/?_escaped_fragment_=page
However at the moment, the spiderable package will call phantomjs with
the following url:
http://domain.com/
My solution is to create your own spiderable package with fix by 'https://gist.github.com/4096777'

Resources