Coder Social home page Coder Social logo

icanhaz.js's Introduction

                            
    __________            __  __                _     
   /  _/ ____/___ _____  / / / /___ _____      (_)____
   / // /   / __ `/ __ \/ /_/ / __ `/_  /     / / ___/
 _/ // /___/ /_/ / / / / __  / /_/ / / /__   / (__  ) 
/___/\____/\__,_/_/ /_/_/ /_/\__,_/ /___(_)_/ /____/  
                                         /___/        

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

icanhaz.js's People

Contributors

henrikjoreteg avatar rdclark avatar wesen avatar getfatday avatar jogi avatar brianloveswords avatar titanous avatar

Stargazers

Anne Thorpe avatar Alan Wei avatar Filod Lin avatar Kostis Anagnostopoulos avatar Aijaz Bin Qasim avatar Ryan (Narayan) Dhungel avatar Rodrigo Albuquerque avatar frankfanslc avatar likui avatar  avatar  avatar sandergol avatar Damien Golding avatar Joey Lee avatar vulcangz avatar  avatar  avatar  avatar  avatar hisashi avatar  avatar  avatar yc.mao avatar Sasha Beg avatar  avatar Samuel Walker avatar Ibrahim H. avatar GAURAV avatar Chris avatar  avatar  avatar Tadashi Shigeoka avatar Brendan Sparrow avatar oldxu avatar Rildo Moraes avatar Sunny avatar Ernst Salzmann avatar Joshua Fricke avatar Richard Murillo avatar  avatar Amir Mikhak avatar Ruitang Du avatar Justin avatar Miky avatar Christoph Kuper avatar  avatar  avatar Gulshan Kumar avatar  avatar LaiQiang Ding avatar Angus H. avatar Jyd avatar Eric Bauerfeld avatar Eugene Karataev avatar  avatar Peter Craig avatar Eli Mellen avatar  avatar Peter Sekan avatar Ken Wagner avatar Albert Lacarta avatar Thomas Klemz avatar Theun Kohlbeck avatar  avatar thegitfather avatar Masud Zaman avatar Jack Senechal avatar John Van Tuyl avatar  avatar Ciprian Florea avatar  avatar Alun Davey avatar Sonny Lazuardi avatar 平江 avatar Sam Kozin avatar David Fischer avatar Huynh Khac Thao avatar Joe avatar Alisha Ramos avatar Jerzerak avatar 饭食钢 avatar zshuaibin avatar Kostas Minaidis avatar Gunnar avatar Bela Ezsias avatar Misha Tiurin avatar  avatar José Augusto Guimarães avatar Eric Ting avatar Patryk Kordylewski avatar Neel Mehta avatar Radu Paraschiv avatar Michael Wieland avatar Liratanak ANN avatar David Lemayian ✨ avatar  avatar Lucas avatar Wolmar Nyberg Åkerström avatar Thomas Gratier avatar Abhishek B. avatar

Watchers

Dirk Sidney Jansen avatar Thomas LÉVEIL avatar Panagiotis avatar  avatar bihicheng avatar Espen Klem avatar  avatar FrankyYang avatar David Ford avatar James Cloos avatar Nick Weingartner avatar Xianliang Wu avatar Eli Mellen avatar Sam Coughlin avatar  avatar  avatar

icanhaz.js's Issues

Empty array if there is returned if there is no HTML tag in the template.

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 ! ;)

Any recommended way to organize your 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?

"Invalid name: row"

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) {

Render template with dynamic template name

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?

data with contained HTML

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?

's' is undefined

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.

Install via bower - Camelcase Error

command

bower install icanhaz --save

current

ECMDERR Failed to execute "git ls-remote --tags --heads git://github.com/henrikjoreteg/icanhaz.js.git"

should be

git ls-remote --tags --heads [email protected]:HenrikJoreteg/ICanHaz.js.git

basic usage not working

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).

request

I vote for adding

window.Mustache = window.Mustache || Mustache;

after Mustache is defined in the source.

Callbacks

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?

Problem with AddEventListener

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();
}

Provide some kind of External Template Loading

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...

compatibiliy problem between ICanHaz and zepto 0.5 ?

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 ?

Able to specify template name and data through function.

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

Use node-style requires that don't pollute the global namespace

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?

support for arrays

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>

Escaping is not up to date

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

template retrieval without hardcoding template name

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.

Request to register iCanHaz with Bower

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

Extract plain HTML from template?

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?

Compatibility with RequireJS / AMD

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).

GrabTemplates giving an error on html fragment containing templates

I have a complex user-interface inside a window (pop-up) and window content is a dynamically loaded html fragment.

The process is following

  • GET to the server to return window content
  • render content to the container
  • ich.GrabTemplates()
  • do stuff
  • display the window

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

Request: i18n

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:)

problem rendering icanhaz/mustache loop with jquery 1.9.1

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?

more generic for any template engine?

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.

Javascript inside template

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

Support for old IE (duplicate #54)

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...

reload of ich wipes out templates

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. :)

appending to my div then disappearing

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

<script id="users" type="text/html">

{{ type }}

</script>

My div in my html body to display the data

Content goes here

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

Feature Request: Remote templates

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?

Loading html fragments & template name issue

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?

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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.