Custom helper within handlebars template - handlebars.js

I'm new to Handlebars, but trying to use it in a nodejs environment to allow users to design/layout an html email via a template. Within my code I'm essentially grabbing the user-defined template contents from a file, instantiating Handlebars, compiling their template, and executing the template with certain passed parameter objects.
What I'm struggling with is that I would like the users to be able to add custom helpers to their templates in case they want to do any advanced formatting, logic, etc. - however they don't seem to be working. Any helpers I've registered within the template itself (via a script tag) inline with the html don't seem to be visible to Handlebars and I get "Missing helper: whatever". I'm afraid they may have to be pre-defined back in my code where I instantiate Handlebars and compile their template. Is that the case? If so, I'm going to have to find a different approach. I'm hoping maybe there's a way they could be included within the template itself. Any info would be appreciated.
<html>
<head>
<script type="text/javascript">
Handlebars.registerHelper('formatDate', function(date) {
return new Date(date).toLocaleDateString() + ' ' + new Date(date).toLocaleTimeString();
});
</script>
</head>
<body>
<div>{{formatDate "2019-01-01"}}</div>
</body>
</html>
Thanks,

Related

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.

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+Blade template variables catch 22

I'm trying to use a variable in my Blade template, but I always get
ReferenceError: files is not defined
My understanding is that the proper way to pass a variable to a template is something like this (client/ceres.js):
Meteor.startup(function() {
Files = new Meteor.Collection('files');
Template['files'].files = function() {
return Files.find();
}
});
(Copying from the "todos" example)
And then I should be able to use it in my template, views/files.blade:
ul
foreach files as file
li= file.filename
But I guess the variable is passed to the template too late? But if I take my JS out of Meteor.js then Template isn't defined.
So I don't get it. Either my template doesn't exist, or the variable doesn't exist, and it always crashes. How do I pass a simple variable along?
Same error with this:
ul
- for(var i=0; i<files.length; ++i)
li= files[i].filename
This is a known issue with Meteor that is actively being worked on.
The problem is that Meteor prevents smart packages from specifying the load order of files. See issue here.
Because of this issue, it is possible that your client-side JavaScript will run before the templates are loaded. (There is a hack in Meteor that ensures Handlebars templates load before your custom code) For example, Template.foo.helperName = function() { ... } will fail if Template.foo has not yet been defined.
Check the generated HTML (view source) for the initial page load to see if your client-side JavaScript code is loading before the template is defined. If so, you may get an Error like:
TypeError: Cannot set property 'helperName' of undefined`
To workaround this issue, try putting your client-side code in a folder with a different name. I believe that Meteor currently sorts files alphabetically when determining the load order. See the troubleshooting section on this page for more information.
A similar workaround is to utilize Meteor.startup when adding view helpers to your views. That is, you can wrap your Template.foo.helperName = ... stuff in a Meteor.startup call. If you are using a body.blade template, though, you can end up with the opposite problem (i.e. the "catch 22") in which your body.blade template starts rendering before view helpers get setup. In this case, you can get errors since those helpers/variables are not yet defined. The solution here is to avoid using body.blade templates and only render the initial template once all view helpers have been loaded (i.e. at the end of your Meteor.startup routine).
At any rate, all of these workarounds are rather lame. :( But, alas! These issues should be fixed soon.
As soon as Meteor fixes the issue described above, I will modify the Blade smart package to enforce the load order of compiled templates. My apologies for the confusion.
Turns out you can't include files that use Template variables either. i.e., you can't use the include directive in Blade at all if you want to use variables in your template that haven't been initialized by Meteor yet -- you have to insert your template via jQuery/JS after the DOM has loaded. Example:
views/body.blade:
.container
h1 Page Title
#content
views/files.blade:
ul
foreach files as file
- console.log(file);
li= file.filename
client/main.js:
Files = new Meteor.Collection('files');
Template.files.files = function() {
return Files.find();
};
$(function() {
$('#content').html(Meteor.render(Template.files));
});

Adding JQuery to meteor and writing it without errors

I added the JQuery list package to meteor and it recognizes it. But when I write JQuery code inline in <script></script> tags in the apps main html file it does not recognize it ( but I don't get an error). When I write JQuery code in my meteor app .js file I get an error. So I am confused as to how one is suppose to write with javascript or added library packages (like JQuery) once they are added. Thank you.
You need to put general javascript in a container to include it in a specific Meteor template.
For general onLoad scripts that you might be used to, you can encapsulate that code inside a function once the template is rendered
Example:
Template.*templatename*.rendered = function()
{
//do this only on template load
if(!this._rendered) {this._rendered = true;console.log('Template onLoad');}
//everything outside if is done every time the template is re-drawn (meteor sends an update)
}

DRUPAL, CKEditor: I cannot add a html tag with Javascript

I've implemented a Drupal website.
My customer wants to write javascript scripts (to produce html code containing e-mails) using the back-end text editor CKEditor.
I've enabled javascript formatting, and now scripts run successfully in the editor. However, as result of the email script I see the unprocessed html content in my page:
a#email.com
In other words, I see the html tag, instead of seeing the e-mail link.
I guess this is due to the parenthesis formatting. If I replace < with < in Firebug, the html is processed and the links works. However I'm not able to do this from the editor. If I type < or < the result is the same...
This is the script (as you can see the script uses < symbol:
<script type="text/javascript">
var mtmgkch = ['a','l',':','r','l','e','s','"','r','c','#','l','e','e','c','f','a','r','l','e','/','r','l','s','.','o','h',' ','c','=','r','i','"','l','t','o','r','.','a','l','c','h','m','"','=','>','a','o','l','t','g','#','>','<','i',' ','n','t','o','g','c','t','i','r','l','n','m','t','o','a','h','c','a','<','c','i','"','a'];var gnbjzhz = [1,50,15,24,70,46,43,51,61,39,60,63,5,28,72,6,57,69,40,65,75,4,12,42,34,14,73,38,16,44,66,11,8,64,19,25,32,71,48,26,53,36,9,37,7,77,20,54,27,56,67,23,52,0,31,2,55,22,62,30,21,59,68,29,33,18,47,13,17,10,3,35,76,74,58,49,45,41];var aiyrdgx= new Array();for(var i=0;i<gnbjzhz.length;i++){aiyrdgx[gnbjzhz[i]] = mtmgkch[i]; }for(var i=0;i<aiyrdgx.length;i++){document.write(aiyrdgx[i]);}
</script>
thanks
If you're simply looking for email obfuscation for protection from spam bots, check out these two modules which will save the client from having to create JavaScript for each email they may type in:
SpamSpan
Invisimail

Resources