henrikjoreteg / icanhaz.js Goto Github PK
View Code? Open in Web Editor NEWA clean solution for templating with Mustache.js and jQuery or Zepto
Home Page: icanhazjs.com
License: Other
A clean solution for templating with Mustache.js and jQuery or Zepto
Home Page: icanhazjs.com
License: Other
__________ __ __ _ / _/ ____/___ _____ / / / /___ _____ (_)____ / // / / __ `/ __ \/ /_/ / __ `/_ / / / ___/ _/ // /___/ /_/ / / / / __ / /_/ / / /__ / (__ ) /___/\____/\__,_/_/ /_/_/ /_/\__,_/ /___(_)_/ /____/ /___/ A simple/powerful approach for doing client-side templating with Mustache.js. MIT Licensed ICanHaz.js includes janl's mustache.js (https://github.com/janl/mustache.js/). Much props to Chris Wanstrath for Mustache and Jan Lehnardt for porting it to JS. To get started, read the documentation: http://icanhazjs.com
There is an error at line 338:
else return s.replace(/^\s+/, '').replace(/\s+$/, '');
should be:
else return stuff.replace(/^\s+/, '').replace(/\s+$/, '');
Hello,
I noticed a bug when I use very simple templates, without HTML tag. For instance:
<script id='turnCounter' type='text/html'>
Turn {{turn}}
</script>
When I compile it, it fails.
ich.turnCounter({ turn: 3 }) // => []
I would expect to have "Turn 3". Any idea?
Thanks for ICanHaz anyway, it's very cool with more real-world templates ! ;)
Suppose one has got quite a big application with lots of icanhaz templates (because he likes it) and keeping them in index.html or one single template file is difficult to maintain. And it's just bad to keep everything in one file.
Is there any recommended way to organize templates in files or directories? It's up to the developer - he may create templates
dir in the app's web
dir, containing *.ich
files (I was thinking about that). But maybe there is any convention followed by other icanhaz users?
So I started using iCanHaz today and it's great sofar!
But I keep getting an error in Firebug...
Invalid name: row.
Here is my template:
<script id="row" type="text/html">
<tr>
<td class="editable s_name" data-type="text" data-name="name" data-pk="@{{ pk }}" data-url="./api/updateGroupForm">@{{ name }}</td>
<td class="editable s_desc" data-type="text" data-name="desc" data-pk="@{{ pk }}" data-url="./api/updateGroupForm">@{{ desc }}</td>
<td class="s_delete" data-pk="@{{ pk }}"><i class="fa fa-times _pointer text-danger removeGroup"></i></td>
</tr>
</script>
And here is the Javascript:
$(document).ready(function(){
ich.grabTemplates();
var rowObj;
var row;
rowObj={};
rowObj.pk="1";
rowObj.name="asdf";
rowObj.desc="asdf";
row = ich.row(rowObj);
$('#myTable tbody').append(row);
});
I'm using jQuery and ICanHaz downloaded from bower.io
Looking at Firebug, it throws an error on line 475 (ICanHaz.js):
addTemplate: function (name, templateString) {
if (typeof name === 'object') {
for (var template in name) {
this.addTemplate(template, name[template]);
}
return;
}
if (ich[name]) {
console.error("Invalid name: " + name + "."); /*LINE 475*/
} else if (ich.templates[name]) {
console.error("Template \"" + name + " \" exists");
} else {
ich.templates[name] = templateString;
ich[name] = function (data, raw) {
I've got two templates defined: incomeFormTemplate
and outcomeFormTemplate
. They get the same parameters to be rendered.
Now I can render them like the following:
ich.incomeFormTemplate(params)
ich.outcomeFormTemplate(params)
Is there any way to pass the template name as the parameter to achieve something like:
ich.render('incomeFormTemplate', params)
If so, could it be included in the docs maybe?
This is not really a bug, possibly only something missing in the documentation:
I have data that may contain HTML (yes, i know that's not neccessarily a good thing inside a json)
when i render a template with said json, the HTML will show up as plain text (think of it as using jQuery.text() as opposed to jQuery.html())
Is there any way to render contained html as html?
You need to mark partials with class="partial", which is overcomplicating things. Why not be able to use every template as partial?
Would be cool if this were in NPM :)
where it says
"else return s.replace(/^\s+/, '').replace(/\s+$/, '');"
I think you mean
"else return stuff.replace(/^\s+/, '').replace(/\s+$/, '');"
and it's throwing errors in IE8.
bower install icanhaz --save
ECMDERR Failed to execute "git ls-remote --tags --heads git://github.com/henrikjoreteg/icanhaz.js.git"
git ls-remote --tags --heads [email protected]:HenrikJoreteg/ICanHaz.js.git
Hi, I'm using the most basic ich functionality and not seeing my data output:
My template:
<script id="itemList" type="text/html">
<div>{{foo}}</div>
</script>
My js to render the template:
var renderOpts = {
foo: 'bar'
}
var html = ich.itemList(renderOpts)
console.log(html) //outputs <div></div>
As you can see above, 'bar' is not being rendered in the div. I am using the latest ICanHaz (version 0.10).
I vote for adding
window.Mustache = window.Mustache || Mustache;
after Mustache is defined in the source.
Hi there, the current version wont parse e.g. "user.name". The issue lies within mustache 0.3.0
I updated mustache to 0.4.0-dev which solved the issue.
https://gist.github.com/1373235
Cheers
Is there by chance a way to script a callback while using icanhaz.js?
For example, if I call ich.user(), and my template is <script id="user" type="text/html">, I'd like to have a callback fire each time that template is generated. Does that make sense?
Hi, I have a problem with AddEventListener in IE8, can somebody help me with this?
This is the menu I am trying to use:
http://tympanus.net/codrops/2013/07/30/google-nexus-website-menu
This is the code:
_initEvents : function() {
var self = this;
if( !mobilecheck() ) {
this.trigger.addEventListener( 'mouseover', function(ev) { self._openIconMenu(); } );
this.trigger.addEventListener( 'mouseout', function(ev) { self._closeIconMenu(); } );
this.menu.addEventListener( 'mouseover', function(ev) {
self._openMenu();
document.addEventListener( self.eventtype, self.bodyClickFn );
} );
}
this.trigger.addEventListener( this.eventtype, function( ev ) {
ev.stopPropagation();
ev.preventDefault();
if( self.isMenuOpen ) {
self._closeMenu();
document.removeEventListener( self.eventtype, self.bodyClickFn );
}
else {
self._openMenu();
document.addEventListener( self.eventtype, self.bodyClickFn );
}
} );
this.menu.addEventListener( this.eventtype, function(ev) { ev.stopPropagation(); } );
},
_openIconMenu : function() {
classie.add( this.menu, 'gn-open-part' );
},
_closeIconMenu : function() {
classie.remove( this.menu, 'gn-open-part' );
},
_openMenu : function() {
if( this.isMenuOpen ) return;
classie.add( this.trigger, 'gn-selected' );
this.isMenuOpen = true;
classie.add( this.menu, 'gn-open-all' );
this._closeIconMenu();
},
_closeMenu : function() {
if( !this.isMenuOpen ) return;
classie.remove( this.trigger, 'gn-selected' );
this.isMenuOpen = false;
classie.remove( this.menu, 'gn-open-all' );
this._closeIconMenu();
}
Hi Henrik,
I had posted this as a comment to a closed post, but thought I would open it as it's own post.
I understand that you don't want to push people in one direction or another with respect to remote template loading, but there might be a bigger picture here that you should consider. For example what about those of us using your framework on mobile phones. In frameworks like phonegap it is a benefit to have the whole app be a single page. In my case I end up with a index.html page with 50+ templates in it. My app does not connect to a server so I can point to a local json file that I have to encode by hand (manually embedding HTML in json sucks!). It works, but it is not pretty. It would be much easier if the framework allowed me to point to a files that included all of my templates in pure text format. This way I could put all 50+ in one file, or break them up by module.
I'm not saying I like the current proposed solutions for remote loading, but I think something that takes us SPI (http://en.wikipedia.org/wiki/Single-page_application) and SPI standalone and mobile developer into consideration would be nice.
Just my 2 cents...
When i use very simply IcanHaz and the 0.5 zepto version, iCanHaz do is job but after doing it, i have an error like : Uncaught Error: TYPE_MISMATCH_ERR: DOM Exception 17 and zepto dont work anymore.
Any Idea ?
Hi,
First of all I love ICH, it works really nicely.
I'm sorry if I missed this somewhere from scanning through the code but I think it would be really helpful to be able to call a function and give it the name of the template and the data that I wish to use.
I am trying to write some custom helper code for something I am working on, and I have the template name and the url to load data from embedded in the DOM as such:
<div id="item-container" data-url="/ajax/something" data-template="itemTemplate"/>
When I want to load the contents of the div, I can access the data-url and data-template attributes and use jQuery to load the data, however I have no way to get ICH to render the template for me.. Ideally what I need is an ich.render(template, data); function that I could call so I can programatically use the templates.
Cheers,
Aidan
The current implementation of ICanHaz assigns ich
to the global namespace (window
) automatically. I would rather assign that dependency myself to a local variable, just like in regular node-land. As a browserify user, I expect to write this:
var ich = require('ich');
This convention makes code easier to understand, and there's no mystery about where dependencies are coming from or what's in global scope.
@substack or @thlorenz, what's the best way to make this browserify-friendly?
It would be nice to have support for arrays (as mustache.js does) with the syntax:
{{#.}}
{{array_data}}
{{/.}}
Here's a test with node:
var mustache = require('mustache'),
ich = require('icanhaz'),
template = "<table><tbody>{{#data}}<tr>{{#.}}<td>{{.}}</td>{{/.}}</tr>{{/data}} </tbody></table>",
view = {data: [[0, 2, 3], [4,5,6]]};
console.log('mustache:', mustache.to_html(template, view))
ich.addTemplate('tabler', template);
console.log('icanhaz:', ich.tabler(view))
Which currently gives:
mustache: <table><tbody><tr><td>0</td><td>2</td><td>3</td></tr><tr><td>4</td><td>5</td><td>6</td></tr> </tbody></table>
icanhaz: <table><tbody><tr></tr><tr></tr></tbody></table>
Hi
Mustache has updated the escaping of the values, which is quite important and insecure at the moment
Would love if you would take it into trunk!
See the mustache issue: janl/mustache.js#58
Greets
I can't get the following loop to render properly:
https://github.com/hoffmanc/sritool/blob/master/index.html#L33
Instead of the expected
I'm instead getting
I'm sure I'm just doing something wrong, so feel free to bludgeon me with a clue X 4.
When using AJAX to load my templates, I'm using a format similar to the documentation... my server sends back a JSON object with a "name" parameter and a "template" parameter, and I use ich.addTemplate(name, template).
However, from what I can tell, the only way to a retrieve a template is to use ich.#templateName#(data)... so how can I retrieve a template if the name is stored in a variable and isn't hardcoded? The only solution I've come up with so far is using eval(), but that's not an approach I would like to take.
I'm currently using Bower as a package manager for front-end dependencies (https://github.com/twitter/bower).
It's got a sizeable list of templating scripts registered such as Mustache / Handlebars, and it would be nice to be able to use it to manage iCanHaz.js instead of upgrading manually.
Registration process is fairly simple imo (http://twitter.github.com/bower/ toward the bottom) and anyone can do it, but I wanted to check here first. If it's ok I'd like to register it.
Cheers
Is it somehow possible to extract the html content from a template?
I've i tried using ich.user({}).html()
, but that only returns the inner HTML of the template.
This one for example.
<script type="text/html" id="user">
<div id="a">
<div id="b">
<div id="c">
Content
</div>
</div>
</div>
</script>
When I use html()
i get this data.
<div id="b">
<div id="c">
Content
</div>
</div>
Any ideas?
I use NuGet quite heavily for my project dependencies, and I'd love to use it to install and manage ICH as well.
As I see it, the current implementation of CommonJS conflicts with requirejs, arguably the most popular AMD (Async Module Definition) implementation. When using RequireJS, I get Uncaught ReferenceError: module is not defined
at line 403 (when module.exports is involved).
I have a complex user-interface inside a window (pop-up) and window content is a dynamically loaded html fragment.
The process is following
The problem is that when I open the window two or more times I get an error for each template that is used in the window.
Invalid name: dialogTitle. ICanHaz.js:472
ich.addTemplate
I understand that the problem is that the template is already "grabbed", but is there anyway to tell ICanHaz to either skip or override existing templates? There are quite many templates in the window, so it would be really nice if I could still use GrabTemplates and not manually check the existence and then add template if it doesn't exist in the ICanHaz.
This is slightly related to the issue opened by tonynoy #44
I have seen forks that already have that, like the one from @jimmybyrum - I think at least dot.notation is worth it.
Hi,
I think adding an internationalization plugin would be awesome. Using a template engine with internationalization makes life easy for developers!
One possible solution is to trigger an event with generated content as argument. in this way developers can use their own internationalization plugins as callback functions to this event:)
First of all, I like icanhaz a lot!
I'm not quite sure if it's related to icanhaz or mustache. I got very strange problem with rendering looped values (the problem was also published on stackoverflow).
When trying to render the following:
<script id="myTemplate" type="text/html">
{{#stuff}}
<option value="{{key}}">{{desc}}</option>
{{/stuff}}
</script>
<script>
$(document).ready( function() {
var listOfStuff = {stuff: [
{key: "1", desc: "First"},
{key: "2", desc: "Second"}
]};
var x = ich.myTemplate(listOfStuff);
$("#mySelectBox").append(x);
});
</script>
jquery 1.8.3 works perfectly (look at the fiddle), whereas jquery 1.9.1 crashes (look at different fiddle). If you check out javascript console for 1.9.1 you'll see the following error:
Uncaught Error: Syntax error, unrecognized expression: <option value="1">First</option>
<option value="2">Second</option>
Do you know what is the problem? Is there a known problem with jquery 1.9.1 working with icanhaz or mustache?
would it be more nice to have it more generic and not tie to a special template engine?
it should be like rack - a generic interface for any template engine and you can switch it.
Hello, l need to keep some javascript code inside a template. Unfortunately this doesn't work, e.g.:
<script type="text/html">
... icanhaz template ...
<script type="text/javascript">
... some javascript code (which uses some variables from the template)...
</script>
</script>
Any help? Thanks a lot
Of course with due credit in the readme, etc. Respond here if you're interested.
I re-open this bug with a workaround to support DOMContentLoaded on IE.
According to many url over internet, using onreadystatechange on document almost emulate the DOMContentLoaded on IE, so i add little workaround for IE browsers :
(from line 545) :
if(document.addEventListener) { // W3C
document.addEventListener('DOMContentLoaded', ich.grabTemplates, true);
} else if(document.attachEvent) { // Microsoft
document.attachEvent('onreadystatechange', function() {
if(document.readyState === 'complete' || document.readyState === 'loaded') {
document.detachEvent('onreadystatechange', arguments.callee);
ich.grabTemplates();
}
});
}
Works perfectly, and now IE6+ is supported as expected...
Pretty easy to work around, but when including ICH with yepnope, it seems possible for the library to reinitialize in some edges cases, and in doing so, all the previously imported templates will be wiped out (since they are tagged as already having been processed, so the new copy of ich overwrites the old one and then finds no new templates to import from the DOM). I've just been adding window.ich = window.ich || ich= { all the ich code...; } as a workaround (basically, if the library is already included, don't bother to overwrite it with a new copy), but not sure that's the best/right solution. The right solution is not to include it twice, obviously, but it's not always possible to avoid in some situations. :)
Mustache.js v0.4.0 is out... any plans on upgrading?
Sorry for posting this here, but there doesn't seem to be any support links elsewhere. I am sure I am doing everything the way it is supposed to be, but for some reason after getting my template filled with my data and returning html. I do a simple .append() to my div and it then quickly disappears.
my js code
function showContent(divOfTemplateToDisplay, data) {
var addToContents = ichdivOfTemplateToDisplay;
$("#content").append(addToContents);
// right after here it shows up for a split second, then disappears
}
My script that is my template
{{ type }}
{{firstName}} {{lastName}}
My div in my html body to display the data
I don't think there is any other code running after it to clear or remove the contents.
Thanks
By the way as a newbie to js, jquery, single page apps, iCanHaz is really cool for templating quickly. Easy to understand and get running immediately.
Mark
Would love to be able to link to template files instead of including them in the view directly. It feels weird to show the templates to the users.
Any plans for something like this?
ich doesn't seem to work if there is no html in the template. Seems strange to require markup in the template.
Cheers!
First, kudos for nice library.
Setting it up was pretty much plug and play.
Now the issue I'm encountering:
I'm loading external files/html fragments/strings from the server with require.js.
In those files there's just raw html fragments, which are not enclosed into any script tags.
They are just raw strings. I load them via require.js text plugin, and it returns just raw string
( 'text!templ/home/intro.html'
is how I load the template ).
After that, I just use that text/html fragment like this:
ich.addTemplate('person', loadedHtmlText); content = ich.person(dataobject); this.el.html(content);
Am I doing this properly?
'person' is not either previously declared anywhere, nor is it used as id of any script tags within templates, since
these html fragments have none, they are just raw html.
Anyway, the code is rendered as expected, it all works fine, however the console throws an error:
[19:39:10.212] Invalid name: person. @ http://localhost/projekt/test1/js/libs/ICanHaz.js:472
I'm using the latest repo version, converted with r.js command line tool into require.js module.
(I doubt it's the conversion to blame)
So, I'd just like to hear opinion.
I looked into code, it seems that on line 472, code that creates the issue is a test wether the name/string already exists?
However, my code doesn't have any other, same, already registered template/name.
Dot notation is supposed to work per the mustache docs (eg {{ name.first }}
)
On the latest icanhaz.js the dot notation doesn't seem to be working.
I had a context like this
{ firstname: 'john', a: { blah: 'foo' } }
and {{ firstname }}
works
but {{ a.blah }}
doesn't work
though a (poor) workaround that seems to work is {{ #a }}{{ blah }}{{ /a }}
Perhaps this is a problem with being on an older mustache version?
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.