twitter / hogan.js Goto Github PK
View Code? Open in Web Editor NEWA compiler for the Mustache templating language
Home Page: http://twitter.github.io/hogan.js
License: Apache License 2.0
A compiler for the Mustache templating language
Home Page: http://twitter.github.io/hogan.js
License: Apache License 2.0
it is not compatible with IE browser. there is a script error
Higher Order Sections is not working when I use the command line to precompile the templates.
I think we've outgrown my little hand-rolled testing functions. We should switch to something good.
With a directory structure like:
project /
|
+--static /
|
+--templates /
| |
| +--title.mustache
|
+--js /
|
+--templates.js
When running:
hulk static/templates/*.mustache > static/js/templates.js
the output names the template templates.static/templates/title
which is illegal in JS. This is due to not getting the basename of the file first, or perhaps slugifying the path in some predictable and safe way.
The short term fix is to run:
cd static/mustache && hulk *.mustache > ../js/templates.js
Can we add / update the gh-pages to include 1.0.5 build?
@sayrer (regarding some comments in #10 and #7) why not put HoganTemplate inside the iife that produces Hogan and include it as part of the return statement?
var Hogan = (function () {
var HoganTemplate = (function () {
// ...
})();
// in the generate function, use Hogan.Template rather than HoganTemplate so that
// the template can be replaced
// ...
return {
Template: HoganTemplate,
// ...
};
})();
then you only have a single export (Hogan
) and don't have the inconsistency of HoganTemplate
in the browser and Hogan.Template
in node
var hogan = require('hogan.js');
var compile = hogan.compile;
var compiled = compile('{{test}}');
var rendered = compiled.render({
test: "hi"
});
Error when compile is called:
TypeError: Cannot read property '{{test}}||false' of undefined
at /home/contra/Desktop/Projects/slate/node_modules/hogan.js/lib/compiler.js:339:23
Assigning hogan to another variable causes it to lose this
. Using Hogan.
instead of this.
should fix the issue
I know the Mustache specification does not support inheritance, but I would like the feature. Perhaps the implementation at mustache.java could serve as inspiration.
Hey guys,
I noticed lambda functions are not supported in precompiled templates. The core reason for this appears to be that the official Mustache specification reads:
Lambdas are a special-cased data type for use in interpolations and sections.
(...)
When used as the data value for a Section tag, the lambda MUST be treatable as an arity 1 function, and invoked as such
(passing a String containing the unprocessed section contents). The returned value MUST be rendered against the current
delimiters, then interpolated in place of the section.
Unfortunately, this behavior requires that when a lambda function is used, the original (unprocessed) source of the template is available. In order to remedy this situation, I created a fork that works on the processed section contents instead (I've not created a pull request as it deliberately diverts from the spec to create the desired result).
Anyway, I think it's good to make you aware of this fork, and I'm looking for any feedback you guys can give me. Also, if you prefer I create a pull request for this, I can do that too.
One more question, I tried running the test suite through run.js to see if my changes had any unintended side-effects, but run.js gave me no output whatsoever. Probably I'm just unaware how to properly run the suite, but I didn't see instructions either, so if someone can point me to how to properly run the test suite that would be great.
You can find my fork right here: https://github.com/arendjr/hogan.js
Regards,
Arend jr.
If I'm understanding it correctly, the Apache license requires you to include the licensing info in the file. Currently, http://twitter.github.com/hogan.js/builds/1.0.3/hogan.min.js does not include that info, which would make anyone linking to it technically in violation, right?
I'm trying to get partials to work in Express, but in the absence of being able to put a path in the partial statement it gets very complicated.
I'm still learning logic-less templating (as well as Express), so please let me know if I'm going about this the wrong way.
Thanks!
I have a module called Bogus.js that extends Hogan.js with the ability to deal with Backbone.js models.
Bogus.js exports the exact same API as Hogan.js. The two implementation differences are the Hogan.generate
function and the Hogan.Template
class, which I both extend.
Extending Hogan.generate
is a bit tricky, though, and I wonder if there's something you think I should be doing differently, or perhaps something you'd like to change on your side to support this case. Here's the current implementation of my generate
.
The asString
case is easy, but for the other case I need either a Function
, or the function body so I can create it myself, to pass to the Template
constructor. As you can see now from the current implementation, I'm slicing to get to the function body.
I had a problem with 2.0 (false template sections was outputting function (s) { this.buf += s; }
the first render call), so I tried in 3.0
x = new Hogan.Template(Hogan.compile('blah', {asString:1}))
x.render()
this no longer works with version 3.0 ?
this is within the browser... source created with make release
This bug can cause strings returned from method calls in the template
context to be rendered as Mustache.
The fix is already checked in here:
1eff200
Fix conformance bug with method calls and interpolation. Previously,
methods invoked for interpolations were being reprocessed as Mustache
in the event that they contained Mustache tags. This is counter to the
spec, which states that only values returned from "lambda" calls are
to be interpreted this way. This error could be a security concern if
Mustache processing functions are run over input that could contain
Mustache tags, although the usable tags are limited to those matching
the context object the template was invoked with.
This patch also removes support for the Mustache.js render argument to
lambda processing, since combining that function with spec-compliant
lambda processing could result in another variant of the bug above.
This is a backwards incompatible change for version 2.0.
The current implementation of template.render() assumes that you know exactly what partials (if any) a given template references, which makes calling this method elsewhere somewhat problematic โ you need to supply the partial as an argument to the call, which makes dynamically assembling calls to render a bit tricky.
Perhaps I'm missing some crucial detail of how partials are implemented, but if not I'd like to request a feature: that partials can be registered elsewhere (as Handlebars does) and then whenever a template is called it uses a previously registered partial of the appropriate name as it needs to.
Sometime between node-0.6.8 and node-0.6.11, the way NPM untars package files seems to have changed, and I believe this has revealed a latent problem with Hogan's package tar.gz file as published to the NPM registry.
In particular, none of the directories in the archive seem to have the execute permission flag set, which means that, once unpacked, it is impossible to actually read their contents (without altering the permission flags). This didn't bug the old NPM, but the current one will complain when attempting to install Hogan, along these lines:
npm ERR! path /tmp/npm-1330464275415/1330464275783-0.16246374556794763/___package.npm/package/bin/hulk
npm ERR! code EACCES
npm ERR! message EACCES, permission denied '/tmp/npm-1330464275415/1330464275783-0.16246374556794763/___package.npm/package/bin/hulk'
If you download, untar, and inspect the package file, you can see what's up:
$ curl -k -o hogan.tar.gz https://registry.npmjs.org/hogan/-/hogan-1.0.5-dev.tgz
[...]
$ tar xzf hogan.tar.gz
$ ls -alF package/
total 64
drwxrwxr-x 8 ec2-user ec2-user 4096 Feb 28 21:32 ./
drwxr-xr-x 9 ec2-user ec2-user 4096 Feb 28 21:32 ../
drw-rw-r-- 2 ec2-user ec2-user 4096 Jan 28 21:44 bin/
-rw-rw-r-- 1 ec2-user ec2-user 14 Jan 28 21:44 .git_ignore
-rw-rw-r-- 1 ec2-user ec2-user 89 Jan 28 21:44 .gitmodules
drw-rw-r-- 2 ec2-user ec2-user 4096 Jan 28 21:44 lib/
-rw-rw-r-- 1 ec2-user ec2-user 10349 Jan 28 21:44 LICENSE
-rw-rw-r-- 1 ec2-user ec2-user 1324 Jan 28 21:44 Makefile
-rw-rw-r-- 1 ec2-user ec2-user 558 Jan 28 21:44 package.json
-rw-rw-r-- 1 ec2-user ec2-user 2607 Jan 28 21:44 README.md
drw-rw-r-- 4 ec2-user ec2-user 4096 Jan 28 21:44 test/
drw-rw-r-- 2 ec2-user ec2-user 4096 Jan 28 21:44 tools/
drw-rw-r-- 6 ec2-user ec2-user 4096 Jan 28 21:44 web/
drw-rw-r-- 2 ec2-user ec2-user 4096 Jan 28 21:44 wrappers/
$
I'd expect all the directories to show up as drwxrwxr-x
, which is what you'll see in pretty much every other NPM package (or tarball in general for that matter).
Compiling without the asString
option and then compiling with the asString
option produces the same object output since the result is cached.
Hi Friends,
I'm trying to access a function {{#reverse}}
inside of a list loop {{#badges.accepted}}
like so:
{{#badges.accepted}} <a href='{{#reverse}}backpack.details, {"badgeId": "{{id}}" }{{/reverse}}'> <img id="id.{{id}}" src="{{meta.imagePath}}" width="64px"/> </a> {{/badges.accepted}}
It's not working, the reverse
function is never called, and I think it's because it's trying to find a reverse attribute within the context of the badges.accepted
loop. Is there a way to access the outside context? Something like (totally making this up) {{#../reverse}}
? I'm new to mustache, so this might not actually be a Hogan issue, but thought I'd check. I looked for an IRC channel, or some other place to ask this, but couldn't find anything handy.
Thanks,
Chris
I was really pleased to see template inheritance added to hogan, as we use mustache.java, but have a requirement that our templates be useable both server-side & client-side.
I was trying out some test cases with template inheritance after building hogan.js, but ran into an issue when replacing content in a parent template with something containing a partial.
Simple test page here:
https://gist.github.com/2258867
Hi there,
I am using hogan.js compiling on the fly from templates stored in a script tag
<script type="text/html" id="template-id">{{hulk}}</script>
This works fine everywhere except ie7 where it just renders all the templates blank. I can see hogan is getting the html from inside the script tag but once it comes to template.render()
, nothing!
Thanks
spec tests https://github.com/janl/mustache.js/tree/master/spec/_files
this are not passed because of escaping:
for this i've got "TypeError: undefined is not a function"
Hogan.compile result depends on options.delimiters, but Hogan.cacheKey doesn't use options.delimiters in key calculation. This can probably lead to incorrect result from Hogan.compile.
It would be useful if there was some kind of build script, that would automagically extract the HoganTemplate function, into a separate .js file that could be included in a web-browser, when parsing "pre-compiled" templates. It would make using tools like this more straight-forward:
https://github.com/danielstocks/hedgehog
Right now, you'll have to manually extract the HoganTemplate function from the hogan.js script, to avoid including the whole library in the browser.
Dust.js already does something like this:
https://github.com/akdubya/dustjs/tree/master/dist
Thanks for allt the great work on hogan.js btw, loving it so far!
@fat says he needs it
I'm having an odd problem running hulk
I install the module, get an odd error from env, and nothing else. I've tried a few other node modules, and this is the only one giving me issues... Below is the output from my term session.
[pthrasher@hiro] ------------------------------------------------------ 19:31:01
~) npm install -g hogan
/opt/Developer/.nvm/v0.6.1/bin/hulk -> /opt/Developer/.nvm/v0.6.1/lib/node_modules/hogan/bin/hulk
[email protected] /opt/Developer/.nvm/v0.6.1/lib/node_modules/hogan
[pthrasher@hiro] ------------------------------------------------------ 19:31:11
~) hulk
env: node\r: No such file or directory
[pthrasher@hiro] ------------------------------------------------------ 19:31:23
~) node /opt/Developer/.nvm/v0.6.1/lib/node_modules/hogan/bin/hulk
USAGE: hulk ./templates/*.mustaches
NOTE: hulk supports the "*" wildcard and allows you to target specific extensions too
[pthrasher@hiro] ------------------------------------------------------ 19:32:00
~) npm install hogan
[email protected] ./node_modules/hogan
[pthrasher@hiro] ------------------------------------------------------ 19:32:12
~) hulk
env: node\r: No such file or directory
[pthrasher@hiro] ------------------------------------------------------ 19:32:18
~) node ./node_modules/hogan/bin/hulk
USAGE: hulk ./templates/*.mustaches
NOTE: hulk supports the "*" wildcard and allows you to target specific extensions too
[pthrasher@hiro] ------------------------------------------------------ 19:38:59
~) head -35 /opt/Developer/.nvm/v0.6.1/lib/node_modules/hogan/bin/hulk
#!/usr/bin/env node
/*
* Copyright 2011 Twitter, Inc.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var hogan = require('../lib/hogan.js'),
path = require('path'),
fs = require('fs');
var specials = ['/', '.', '*', '+', '?', '|','(', ')', '[', ']', '{', '}', '\\'],
specialsRegExp = new RegExp('(\\' + specials.join('|\\') + ')', 'g'),
templates;
// Escape special regexp characters
function esc(text) {
return text.replace(specialsRegExp, '\\$1');
}
// Check for dirs and correct ext (<3 for windows)
function extractFiles(args) {
var usage = 'USAGE: hulk ./templates/*.mustaches\n' +
The CSS in the following file is missing the Opera compatible vendor extension for transitions in the .button class.
https://github.com/twitter/hogan.js/blob/master/web/stylesheets/layout.css
Line 130:
.button {
-webkit-transition: background-color .3s ease-in-out;
-moz-transition: background-color .3s ease-in-out;
-o-transition: background-color .3s ease-in-out;
transition: background-color .3s ease-in-out;
}
We have a lib/ directory, so we should have a bin/ directory to go along with it.
It would be handy to have hogan generate compiled functions on the command line. I see @bradleywright already has something going there.
hogan.js-template in npm is still at 1.0.4-dev and I'd like to use it with 2.0.0 precompiled templates... please.
Okay, this is a bit crazy I admit... but basically the server-side compiler thinks there's a mustache variable because of the regex in the inline Hogan.js script on the client.
It would be nice if the compiler would ignore this, because then you can have the same templating engine on both the client and the server. For my purposes, this script must be inlined (and not external), so it'd be nice if this would be supported.
UPDATE: Okay, it looks like the render is actually what does not work. It compiles fine.
Now that I've gotten some clarifications on how the lambda tests from the spec are supposed to be run, I've got Hogan perfectly compliant while passing an uncovered case that it was previously failing. But, the lambda code is now slightly repetitious (wherever you see 'typeof foo == "function"').
This test (added by me):
function testHtmlTagInData() {
var text = "foo {{bar}}";
var t = Hogan.compile(text);
var s = t.render(
{
bar: '<b>bar</b>'
}
);
var expected = 'foo <b>bar</b>';
is(s, expected, "Html tag in data compiled correctly");
}
fails with:
FAIL: Html tag in data compiled correctly
Expected |foo%20%3Cb%3Ebar%3C%2Fb%3E|
Got |foo <b>bar</b>|
Can it be fixed?
Minified version should be provided for client side use preferably with a version number in the file name (I don't see the current version of hogan.js anywhere?).
The examples on the main hogan website show require('hogan')
when it should be require('hogan.js')
Aside from that, rock on!
Dustin
This does not work:
var text = "{{^check}}{{i18n}}No{{/i18n}}{{/check}}";
text += "{{#check}}{{i18n}}Yes{{/i18n}}{{/check}}";
var tree = Hogan.parse(Hogan.scan(text));
// outputs "# check"
console.log(tree[0].tag + " " + tree[0].name);
// outputs "Yes"
console.log(tree[1].nodes[0].nodes[0]);
i18n must be a section as it seems and "name" attribute was renamed to "n". Somehow.
For transparency and insight into our release cycle, releases will be numbered with the follow format:
<major>.<minor>.<patch>
If so, why is the current version 1.0.5-dev
?
At http://twitter.github.com/hogan.js/, the drop in script snippet (<script src="http://twitter.github.com/hogan.js/builds/1.0.5/hogan.js"></script>) is useless because the src attribute URL resolves to a 404.
For our project, we've come up with a nice way to use hulk to render all of our templates into an actual usable import for require.js, but I'm not sure what the best approach is or your motivations behind how it's done the way it is now, so I'm opening up the discussion here.
In my fork, I've modified it so that each .mustache file found is compiled down to a ".template.js" file wrapped in the define(..) block needed: mattrobenolt/hogan.js@74c211...2636f6
Obviously this isn't going to cover all uses, so we should introduce options that can be passed through to control the output, something like: hulk *.mustache --amd
These wrappers could coincide with the templates being used to build Hogan.js as a whole.
The end result is us being able to do:
define(['my/path/hello.template'], function(hello) {
console.log(hello.render());
});
Hi guys
from the previous issues and commit messages it looks like Hogan can now do inheritance.
Can you write an example / doc / test to show the syntax, please?
Ta!
Maybe I'm doing it wrong but when I use hulk, all that happens is the result of the compiled template prints out to the console http://cl.ly/1Y271e0j2H2A1547231y. Not sure what I am doing wrong. Also could be helpful if there were some docs on this.
This is the command that results in just printing out the template.
$ hulk test.mustache
as per the Mustache spec (and as implemented in Mustache.js), an empty string should be counted as falsey when boolean coercion is in place for rendering sections.
given the following template {{#test}}blah{{/test}}
and context {test: ""}
the result from rendering it should be an empty string. Hogan actually outputs "blah"
Hello,
I'm trying to use precompiled templates on my website created with hulk.
// file templates.js
var templates = {};
templates.myTemplate = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<div class=\"myData\">");t.b("\n" + i);t.b(t.v(t.f("LASTNAME",c,p,0)));t.b(", ");t.b(t.v(t.f("FIRSTNAME",c,p,0)));t.b("<br/>");t.b("\n" + i);t.b(t.v(t.f("ADDRESS",c,p,0)));t.b(" <br/>");t.b("\n" + i);t.b(t.v(t.f("DESCRIPTION",c,p,0)));t.b("<br/>");t.b("\n" + i);t.b("</div>");return t.fl(); },partials: {}, subs: { }});
Calling hogan and templates.js:
<script src="http://twitter.github.com/hogan.js/builds/2.0.0/hogan-2.0.0.js"></script>
<script type="text/javascript" src="templates.js"></script>
Now I want to render this one, easiest way via console:
templates.myTemplate.render();
But here I get an error: TypeError: Property 'r' of object # is not a function.
What I'm doing wrong? Any hints are welcome!
Thanks, Jan
The issue is that compiler produces string layout with unsupported by the hogan.js format.
Code:
Hogan.generate = function(tree, text, options) {
serialNo = 0;
var context = { code: '', subs: {}, partials: {} }; // <<<<<<<<
Hogan.walk(tree, context);
if (options.asString) {
return this.stringify(context, text, options);
}
return this.makeTemplate(context, text, options);
}
produces:
var templates = {};
templates.myTemplate = new Hogan.Template({main: function(c, p, i) {
var t = this;
t.b(i = i || "")
....
....
.....
return t.fl();
}, partials: {}, subs: { } });
So the resulting templates.myTemplate does not have the .r() method
As an temporary solution I have taken halk script from "hulk" branch
have to
var Hogan = require('hogan.js');
instead of
var Hogan = require('hogan');
if the name
property in package.json is hogan.js
.
Get hogan.js running against TravisCI: http://about.travis-ci.org/docs/user/languages/javascript-with-nodejs/
Then add a build status indicator to the README, bam!
The box announcing "Alternatively, drop hogan.js in your browser by adding the following script." right at the top of the GH-pages page for hogan.js links to a file that doesn't exist: http://twitter.github.com/hogan.js/builds/1.0.5/hogan.js
Perhaps create a tag that means "allow html unescaped output", similar to jade?
http://stackoverflow.com/questions/6926247/nodejs-jade-escape-markup
http://stackoverflow.com/a/10014082
Could hogan support this?
Are there plans to publish to NPM?
The "//goo.gl/OCK7V" link recommended in the documentation at http://twitter.github.com/hogan.js/ redirects to http://twitter.github.com/hogan.js/1.0.0/hogan.js which does not yet exist.
Compiling templates on the server (via Java SCriptEngine for example) returns an object. How can that object be transferred to the client? JSON.stringfy?
Wouldn't it benefital just to transfer the generated code to the client?
This can't be done atm
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.