How to change the default delimiter of Handlebars.js?
Solution 1
This is not possible with "standard" Handlebars. https://github.com/wycats/handlebars.js/issues/227
Solution 2
Although it may be true that you can't configure Handlebars' expression delimiters, that's not the only way to resolve the conflict between Handlebars and Blade. Blade provides syntax that allows you to avoid the conflict by designating what should be passed on to Handlebars. (This is fitting, since Blade created the conflict to begin with, and it's necessary, since Blade is processing the template before Handlebars ever sees it.) Just prepend @
before the curly braces that you want Blade to ignore and pass as-is to Handlebars. Here's a very short snippet of a much larger example:
...
<link
rel="stylesheet"
type="text/css"
href="{{ asset("css/bootstrap.theme.3.0.0.css") }}"
/>
<title>Laravel 4 Chat</title>
</head>
<body>
<script type="text/x-handlebars">
@{{outlet}}
</script>
...
{{outlet}}
will be passed to Handlebars, but {{ asset("css/bootstrap.theme.3.0.0.css") }}
will be handled by Blade.
Solution 3
I created handlebars-delimiters on GitHub / npm to make it easy to use custom delims with Handlebars.
var Handlebars = require('handlebars');
var useDelims = require('handlebars-delimiters');
var a = Handlebars.compile('{{ name }}<%= name %>')({name: 'Jon'});
console.log(a);
//=> 'Jon<%= name %>'
// Pass your instance of Handlebars and define custom delimiters
useDelims(Handlebars, ['<%=', '%>']);
var b = Handlebars.compile('{{ name }}<%= name %>')({name: 'Jon'});
console.log(b);
//=> '{{ name }}Jon'
The idea for the compile function came from https://stackoverflow.com/a/19181804/1267639
Suggestions for improvement or pull requests are welcome!
Solution 4
I've made this function. Hope it can be useful for someone..
/**
* change the delimiter tags of Handlebars
* @author Francesco Delacqua
* @param string start a single character for the starting delimiter tag
* @param string end a single character for the ending delimiter tag
*/
Handlebars.setDelimiter = function(start,end){
//save a reference to the original compile function
if(!Handlebars.original_compile) Handlebars.original_compile = Handlebars.compile;
Handlebars.compile = function(source){
var s = "\\"+start,
e = "\\"+end,
RE = new RegExp('('+s+'{2,3})(.*?)('+e+'{2,3})','ig');
replacedSource = source.replace(RE,function(match, startTags, text, endTags, offset, string){
var startRE = new RegExp(s,'ig'), endRE = new RegExp(e,'ig');
startTags = startTags.replace(startRE,'\{');
endTags = endTags.replace(endRE,'\}');
return startTags+text+endTags;
});
return Handlebars.original_compile(replacedSource);
};
};
//EXAMPLE to change the delimiters to [:
Handlebars.setDelimiter('[',']');
Solution 5
Instead of changing the delimiters you can create files with your handlebars templates in without the .blade
extension. Just include these files in your blade template. E.g
Blade Template File - template.blade.php
@extends('master.template')
@section('content')
@include('handlebars-templates/some-template-name')
@stop
some-template-name File - some-template-name.php
<script type="text/x-handlebars" data-template-name="content">
<div>
<label>Name:</label>
{{input type="text" value=name placeholder="Enter your name"}}
</div>
<div class="text">
<h1>My name is {{name}} and I want to learn Ember!</h1>
</div>
</script>
Related videos on Youtube
George D.
I love everything that has to do with Web Design/development.
Updated on June 04, 2022Comments
-
George D. almost 2 years
I need to use handlebars.js and I also use Blade template engine from Laravel (PHP Framework). The tags {{}} conflict with blade's placeholders that are exactly the same.
How can I change those {{var}} to something like <% var %> ?
-
George D. over 11 yearsThe workaround I did is to regex replace them with JS. I used this code -> var templatecontent = $("#template").html().replace(/<%/, '{{').replace(/%>/, '}}'); var template = Handlebars.compile(templatecontent);
-
George D. over 11 yearsBut its a workaround, not sure if its the right thing to do here.
-
-
Matt Ball over 11 yearsSure, or store the templates outside of the HTML entirely, as suggested on GH: github.com/wycats/handlebars.js/issues/227#issuecomment-9950931
-
George D. over 10 yearsThe trick you are saying is on laravel 4.1 ? Let me know about the version please.
-
samuraiseoul about 10 yearsBeautiful! Works for me! Thanks so much!
-
MortalViews about 10 yearsThis should be the accepted answer, and its not a trick,, but a proper solution.
-
Christian Michael almost 10 yearsWhat about triple curly braces? Currently Blade Template doesn't offer @{{{var}}}
-
lud almost 10 years@Christian hmmm you will need to escape the text yourself @{{ e($var) }}
-
Christian Michael almost 10 years@niahoo handlebars currently has this {{{var}}} for unescaped value / expression. Is this what you're suggesting? @{{ e('{var}') }} ?
-
lud almost 10 years@ChristianMichael e() is a PHP function which does escaping. I was wrong, we must escape before then print with double braces, I don't know how to do. Best may be this forumsarchive.laravel.io/viewtopic.php?id=1451
-
itsjavi almost 10 yearsnice approach I will use it that way
-
Ander Biguri over 9 yearsWhile this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.
-
Stefan over 9 years@AnderBiguri: how is this a link? ;-)
-
Ander Biguri over 9 years@Stefan Sorry, it gets "autowritteng" while moderating. The point is, there is no explanation in this answer. Just gives an answer, but not explaining why or why not.
-
Stefan over 9 years@AnderBiguri: agreed.
-
littlegreen over 9 yearsThis is nice, but often I want to put Blade tags within my Handlebars templates and then it's not handy.
-
Kevin Campion almost 9 yearsIt seems not working with Handlebars v3.0.3. I created a new answer based with your source code, and it works now. Thank you!
-
mikemaccana over 8 years+1 making real libraries, putting them on GitHub where we can send PRs and file issues, and publishing them on npm rather than having people copy paste the same solutions from StackOverflow.
-
Mark Lester almost 4 yearsthere are 3 principal layers of potential template execution imo. On first execution, essentially on a domain/language, at server delivery (good old CGI time) and in the client. I am using {% {@ and {{ respectively. I am also using {"some text"} as effectively shorthand for {%__ "some text"%}, meaning call the __ helper to translate "some text" at first exec . All of these are facilitated by this. thx