Giter VIP home page Giter VIP logo

ect's Introduction

ECT

Performance focused JavaScript template engine with embedded CoffeeScript syntax.

Just try demo to check all features.

Installation

npm install ect

Features

  • Excellent performance
  • Templates caching
  • Automatic reloading of changed templates
  • CoffeeScript code in templates
  • Multi-line expressions support
  • Tag customization support
  • Node.JS and client-side support
  • Powerful but simple syntax
  • Inheritance, partials, blocks
  • Compatible with express
  • Compatible with RequireJS
  • Backward compatible with eco
  • Syntax highlighting for Sublime Text 2 by TurtlePie

Usage

var ECT = require('ect');

var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });
var html = renderer.render('page', { title: 'Hello, World!' });

or

var ECT = require('ect');

var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });

renderer.render('page', { title: 'Hello, World!' }, function (error, html) {
	console.log(error);
	console.log(html);
});

You may use JavaScript object as root.

var ECT = require('ect');

var renderer = ECT({ root : {
				layout: '<html><head><title><%- @title %></title></head><body><% content %></body></html>',
				page: '<% extend "layout" %><p>Page content</p>'
				}
			});

var html = renderer.render('page', { title: 'Hello, World!' });

With express

app.js

var express = require('express');
var app = express();
var ECT = require('ect');
var ectRenderer = ECT({ watch: true, root: __dirname + '/views', ext : '.ect' });

app.set('view engine', 'ect');
app.engine('ect', ectRenderer.render);

app.get('/', function (req, res){
	res.render('index');
});

app.listen(3000);
console.log('Listening on port 3000');

views/index.ect

<% extend 'layout' %>
<% include 'extra' %>
<div>Hello, World!</div>

views/extra.ect

<div>Include me!</div>

views/layout.ect

<html>
	<body>
		<% content %>
	</body>
</html>

Syntax

Unescaped output

<%- someVar %>

Escaped output

<%= someVar %>

CoffeeScript code

<% for article in @articles : %>
	<% include 'article', article %>
<% end %>

or

<% if @user?.authenticated : %>
	<% include 'partials/user' %>
<% else : %>
	<% include 'partials/auth' %>
<% end %>

Inheritance

<% extend 'layout' %>

Use

<% content %>

in parent template to define the insertion point.

Partials

<% include 'partial' %>

You can redefine data context of partial

<% include 'partial', { customVar: 'Hello, World!' } %>

Blocks

<% block 'blockName' : %>
	<p>This is block content</p>
<% end %>

Use

<% content 'blockName' %>

in parent template to define the insertion point.

Blocks supports more than one level of inheritance and may be redefined.

Options

Renderer

  • root — Templates root folder or JavaScript object containing templates
  • ext — Extension of templates, defaulting to '' (not used for JavaScript objects as root)
  • cache — Compiled functions are cached, defaulting to true
  • watch — Automatic reloading of changed templates, defaulting to false (useful for debugging with enabled cache, not supported for client-side)
  • open — Open tag, defaulting to <%
  • close — Closing tag, defaulting to %>

Compiler middleware

  • root — Base url, defaulting to / (should be equal to root option on the client side)
  • gzip — Compressing templates with gzip, defaulting to false

Client-side support

Download and include coffee-script.js and ect.min.js.

<script src="/path/coffee-script.js"></script>
<script src="/path/ect.min.js"></script>

Use it.

var renderer = ECT({ root : '/views' });
var data = { title : 'Hello, World!' };
var html = renderer.render('template.ect', data);

With server side compiler middleware

Download and include ect.min.js. You don't need to include CoffeeScript compiler, because templates are served already compiled by server side compiler middleware.

<script src="/path/ect.min.js"></script>

Setup server side compiler middleware.

var connect = require('connect');
var ECT = require('ect');

var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });

var app = connect()
	.use(renderer.compiler({ root: '/views', gzip: true }))
	.use(function(err, req, res, next) {
		res.end(err.message);
	});

app.listen(3000);

Use it.

var renderer = ECT({ root : '/views', ext : '.ect' });
var data = { title : 'Hello, World!' };
var html = renderer.render('template', data);

Note: root folder must be on the same domain to avoid cross-domain restrictions.

License

(The MIT License)

Copyright (c) 2012 Vadim M. Baryshev <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

ect's People

Contributors

baryshev avatar kuba-kubula avatar szinya avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ect's Issues

Как использовать на клиенте без подключения Coffee-Script?

Я уже понял что то про MIddleWare, но не совсем понятно как его реализовать с express.
В данный момент у меня вот такая конструкция

app.use(ECT.compiler({ root: '/view' }))
app.all('/*',function(request,response){
    new rootController(request,response);
}); 

Но запрос /vew/template.html все равно берет на себя последняя конструкция.
Пожалуйста, помогите правильно сделать?

Обработка расширения файла

В директории с шаблонами есть файл select.ect, используя пример из документации

var ECT = require('ect');
var renderer = ECT({ root : __dirname + '/views', ext : '.ect' });
renderer.render('select', {}, function (error, html) {
    ...
});

получаем ошибку, что не найден se.ect. :-)
Поправьте, пожалуйста, создание регулярки в функции TemplateContext.prototype.load хотя бы на что-нибудь типа:

var extExp = new RegExp(ect.options.ext.replace('.','\\.') + '$');

Спасибо!

Error: callback function required

Hi,
i keep getting this error when trying to setup etc with express

Error: callback function required

on

app.engine('.ect', ectRenderer.render);

Node v 0.10.24 Express v 3.4.7

NodeJS ECT Slow rendering

Hi i have simple code that i will render:
150 x FOO.

When i render it with Node.js template (ECT) the response time is: 1855ms
With PHP response time is: 24ms

ECT code:

<?- "FOO"; ?>
<?- "FOO"; ?>
<?- "FOO"; ?>
<?- "FOO"; ?>
<?- "FOO"; ?>
...

PHP code:

<?php echo 'FOO'; ?>
<?php echo 'FOO'; ?>
<?php echo 'FOO'; ?>
<?php echo 'FOO'; ?>
<?php echo 'FOO'; ?>
...

All are no cached.
And how bigger the count the slower becomes NodeJS (ECT)

Is there something that i miss?

Функция Print или зона необработки шаблонизатором

С использованием Marionnete JS появилась необходимость писать шаблоны внутри HTML таким образом

<script id="feature-template" type="text/html">
                    <div class="item">
                        <div class="name"><%= name %></div>
                    </div>
                </script>

Но шаблонизатор ECT пытается показать эти переменные тоже. Можно ли как-нибудь указать зону, что бы она не обрабатывалась, а выводилась как есть?

?= syntax, dealing with undefined values

I tried to do <%-(@opt_time_groups[key].name?=123)%> or <%-(@opt_time_groups[key].name || 123)%> but have got no success and "TypeError: Cannot read property 'name' of undefined" error. Could you tell me please, how do I intended to do that thing in ECT?

Full code is:

<%for key of @opt_time_groups.concat([1..3]) : %>
  <tr>
    <td>
      <input 
        type="text" 
        name="opt_time_groups[<%-key%>][name]" 
        value="<%-@opt_time_groups[key].name || 123%>"
        />
    </td>
  </tr>
<%end%>

Obviously, it's my mistake. Not an issue. The solution is:

<%-if @opt_time_groups[key] then @opt_time_groups[key].name else 123%>

should includes inherit parent properties?

If I do:

res.locals.user = { name: 'Tom' }
res.render('page')

And in page.ect I do:

<% include 'user' %>

I'd like user.ect to have access to @user. Currently I must pass user explicitly:

<% include 'user', { user: @user } %>

This can get tedious for complex page. Is there a better way?

jQuery script rendered?

There is an issue when i try to add jquery file.

Example:

layout.ect

<script src="/js/assets/jquery-1.9.1.min.js"></script>

and in my console is see:

GET /js/assets/jquery.min.map 404 39ms - 56b

in jquery-1.9.1.min.js file there is a declaration on line 2:
//@ sourceMappingURL=jquery.min.map

With Jade template engine i didnt get any 404 errors.
How it come? Do i miss something?

Cannot access globals from functions

I'm trying access the global scope from this function:

// js
<% write = (input) -> %>
    <div class="translated"><%- @translate input %></div>
<% end %>

<%- write 'hello' %>


// data
{
    translate: function(input){ return: 'hello world' }
}

but I get this Error:

Cannot call method 'translate' of undefined in page on line 2

Сделать JS синтаксис.

Вадим, можете пожалуйста сделать то же самое, что вы сделали, но без CoffeeScript, а на чистом JS, как, к примеру, в шаблонизаторе EJS. Я сейчас его использую, но я сравнил скорость ECT и EJS, в некоторых ситуациях ECT выигрывает по производительности в 5 раз. Но во первых не хочется учить новый синтаксис, а во вторых не хочется переписывать шаблоны. Было бы просто замечательно если бы вы сделали это.

undefined value for defined variable?

In a view I have the following code

[[- JSON.stringify @value ]]
[[- field for field, val of @value ]]

that results in the output

name,id,qty,unit,notes,role
{"name":"whatever","id":"234"} 

but if I try to access any field with

[[- @value.name ]]

it returns

TypeError: Cannot read property 'name' of undefined in ...

does anyone know what could be going wrong?
(I never come across this kind of error before in my 5 months of using ECT)

Support passing of blocks and content to partials

Partials are nice but it is difficult to pass in a huge block of html to a partial.

Say we have this template 'test.ect'

<div class="houses">
   <% content %>
</div>

then it would be cool to do something like:

<% include "test.ect" : %>
   <div>A</div>
<% end %>
<% include "test.ect" : %>
  <div>B</div>
<% end %>

Асинхронная загрузка шаблонов.

Мне все же никак не дает покоя факт синхронной загрузки данных на клиенте. Все таки подвисание браузера пусть даже на 100-200 милисекунд это плохо. А если мне надо загрузить сразу 10-20 шаблонов? А если сервер недоступен или не справляется с нагрузкой, так браузер вообще может секунд 5-10 не реагировать на действия пользователя (передвижение курсора, клики).
http://xmlhttprequest.ru/ вот тут есть пример того, как синхронный запрос блокирует браузер на 3 секунды.
Я написал функцию readFileAsync. Функция предельно проста, она принимает 2 аргумента, первый - файл, второй - колбэк. В колбэк передается единственный параметр - ответ от сервера. Я надеюсь вам не сложно будет заменить синхронную загрузку на асинсхонную. Если вдруг нужна будет помощь, я вам помогу.

readFileAsync = function (file, callback) {
    var AJAX;
    try {
        AJAX = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
    try {
        AJAX = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
        AJAX = false;
    }
    }
    if (!AJAX && typeof XMLHttpRequest!='undefined') {
    AJAX = new XMLHttpRequest();
    }
    if (AJAX) {
        AJAX.open('GET', file, true);
        AJAX.send(null);
        AJAX.onreadystatechange = function() {
          if (AJAX.readyState == 4&&AJAX.status == 200) {
                if(typeof callback=="function")callback(AJAX.responseText);
            }
            else if(AJAX.status !== 0 && (AJAX.status < 200 || AJAX.status > 399)) {
                throw new Error ('Failed to load template ' + file);
            }
        }
    } else {
        throw new Error ('Failed to load template ' + file);
    }
}

Пример вызова

readFileAsync("/view/template.html",
function(data){
compiled=eval(data)
})

Вадим, я надеюсь на вас, правда)

Documentation request: eco vs ect

Could you please explain the advantages of using ect other than its performance. PRos and cons of each language in general. It's the utmost necessity if you want to increase the user base. MOre detailed the analysis is, better. Also sorry for my ignorance, but why performance is important? Arent they all get compiled to html at the end. Does performance make any difference to the end user(a web site visitor).

Error: Failed to load template/Error: Failed to lookup view "500" with Expressjs framework

i tred to used this tempate engine with expressjs framework.
if i use temaplet with out layout it works. E.g

<div>Hello, World!</div>

if i use with layout it thorw exception. E.g

<% extend 'layout' %>
<div>Hello, World!</div>

Here is error:
Error: Failed to load template D:\Mirodil\Dropbox\justdoit\bigshop\views
D:\Mirodil\Dropbox\justdoit\bigshop\views\index.ect
at read (C:\Program Files\nodejs\node_modules\ect\lib\ect.js:245:13)

The problem in the rendering, expressjs pass full path of themplate file and in the tempate it render without any error if in this tempate does not contanins any referens to other templates.

Is it required to define the 'root' variable?

@baryshev
I am making making an Ect renderer plugin for DocPad, a Node static website generator.

DocPad has it's own implementation of templates, but blocks and partials aren't implemented into core (AFAIK).

I need to know if Ect requires the template, partials and blocks folder or if it's optional. I'd like to implement it but if it's not necessary I'll leave it off the initial release.

Thanks!

Add support for async code.

In our app in some very rare cases there is need to directly access db from templates, this could only be done via async query and it would be nice if ECT could support it. i.e such code

<% do @getCount (countFromDB) -> : %>
  <span>The count is <%= countFromDB %></span>
<% end %>

How do I compile to a javascript function that takes a plain javascript object as context and renders it?

I'm trying to write a brunch plugin (see http://brunch.io/) to replace my usage of the eco brunch plugin. See here for the implementation of eco-bruch: https://github.com/brunch/eco-brunch/blob/master/lib/index.js

(Mainly so that I can use <% include 'snippet.eco' %> client-side, but I suppose that would require further work.)

Basically I want to mimic this by compiling to a function render(obj) {return 'some text';} style function that can just be converted to code with .toString() and then that gets bundled up with a bunch of other things and sent through to the browser.

I can't find an easy way to achieve that. Am I missing something?

"locals" variable is not availible in express render

"locals" is the default variable passed to render engine by express app. after few hours or researching, I've found it's possible to access part of "locals" data in "_locals" variable.

here is the example:
//setting locals data
app.use(function(req, res, next){
res.locals.messages = req.flash();
res.locals.user = req.user;
console.dir(res.locals);
next();
});
//accessing it
<% if @_locals and @_locals['messages'] : %>
<% if @_locals.messages['error'] : %>


<%- @_locals.messages['error'] %>

<% end %>
<% end %>

Можно ли обратиться напрямую к контексту (данным) шаблона

Приведу пример

<% include 'partials/showcase', [ '001', '002', '003' ] %>

partials/showcase.ect:

<% for image in @context : %>
    <a href="/img/<% image %>.jpg"><img src="/img/<% image %>_tn.jpg" /></a>
<% end %>

Думаю, кейс понятен. Вопрос в том как обратиться напрямую к переданному контексту. Понятно, что можно передавать { items: [ ... ] }, а потом получать с помощью for image in @items, но не очень красиво.

handling if / else if / else

I get "unexpected indent" errors for an if/else if/else statement. Something like this:

<% if 'one thing': %>
foo
<% else if 'other': %>
bar
<% else: %>
baz
<% end %>

Should that work?

Pre-compile for client side usage

Hi,

congrats for your nice work!

CS syntax in template sounds promising however, on client-side including full CS compiler (39k when gzipped) seems not good enough especially in mobile env.

Is there some way to distribute pre-compiled template to client?

Minify HTML

Is there a way to minify HTML outputs?
Dont see anything about this in documentation.

Documentation is not complete enough.

I love ECT and coffeescript with beautiful syntax.
and We need some supplement like this:
if the templates and the scripts are in the same page, how to render?

Переменные по умолчанию

Делаю многоязыковое приложение.
Приходится на любой вызов рендеринга шаблона передавать переменную, содержащую язык.
Есть ли возможность для каждого HTTP-запроса создавать новый экземпляр ECT с переменными по умолчанию? И ещё, не накладно ли это по ресурсам?

Default block content

Hi Vadim,

Is there a way to put default block content and if child has this block then it will overrule it?

Example:
layout.ect

<% if blockExists('menu1') : %>
<% content 'menu1' %>
<% else : %>
<ul class="menu_default"><li>item</li></ul>
<% end %>

child.ect

<% extend layout.ect %>
<% block 'menu1' %>
<ul class="menu1"><li>item</li></ul>
<% end %>

Precompilation of templates

ECT is an excellent template language. I like the way it support the client side templates using the middleware compilation. Is there any way to use the client side templates with pre compiled templates. I don't have a running node middleware on my hosting server. I want to precompile all the templates on my dev server and include the result js directly in my client app. Is there any way to achieve this?

Thanks
-Kesav

Why a colon at the end of a block statement?

from the official site:

<% if @links?.length : %>
    <ul>
        <% for link in @links : %>
            <%- linkHelper link %>
        <% end %>
    </ul>
<% else : %>
    <p>List is empty</p>
<% end %>

What is the purpose of using a colon at the end? It's not a CoffeeScript syntax.
And will it be removed in the future?

Escaped text with breaks

Is there simple "ECT" way to escape the user entered text and add breaks?

I use MongoDB witch has JSON data and it has \n witch i want to translate to breaks.

<%= @company.description.replace(/\n/g, '<br>') %>

This code will escape <br> tags also.

Add support for capture blocks on functions

The following code errors:

ect = require 'ect'
fs  = require 'fs'

ect = ect {}

fs.writeFileSync 'test.ect', '<%- @test do => %>foo<% end %>'

console.log ect.render 'test.ect', test: (str) ->
    "#{str}bar"

fs.unlinkSync 'test.ect'

The expected result should be 'foobar' instead it errors with the following message SyntaxError: missing ) in test.ect.

Works fine on eco and is the only thing stopping me from using this library as a large majority of our views do this to pass HTML to view helpers.

Great library, thanks!

includes

Hi,

I have a file structure like this:

.
├── index.html
└── layouts
    ├── default.html
    └── partials
        └── metas.html

Template root is set to the folder containing index.html and ext is set to .html.

index.html extends layouts/default.html and layouts/default.html includes partials/metas.html.

Is it by design, that I have to write all my includes and extends relative to the template root folder? Like <% include 'layouts/partials/metas' %> in layouts/default.html. At first I thought it should be just <% include 'partials/metas' %> because default.html is already in the layouts folder. It would be cool to use relative include paths.

Easier commandline use

There are command line tools for use iwth node/npm bundled with ECT but they only allow to compile to a template function not directly to a html file. It would be nice to offer support for that.

HTML Preprocessor

Hi, kudos for being the fastest so far!

Is there any way to hook up an HTML preprocessor (Jade comes to mind, but others might do, I'm sorta fond of Slim as well)?

Thanks

coffee-script version

Can you change package.json, so coffee-script depends on the latest coffee-script

coffee-script: ">=1.5.0"

because after require ect

ect = require 'ect'

coffee interpreter acts like 1.5.0 and does not work with my scripts because they made for version 1.6.2 (some sugar with brackets)

Не работает с requirejs

'libs/coffee-script': {
exports: 'CoffeeScript',
init: ()->
return window.CoffeeScript = this
},
'libs/ect': {
deps: ['libs/coffee-script'],
init: () ->
return ECT(root: '/assets/templates', ext: '.ect')
},

Ошибка Uncaught TypeError: Cannot call method 'compile' of undefined in /assets/templates/index.ect

Comments in ECT.

Vadim,

I there a way to leave a comment in a .ect file? I cant find any documentation about that.

Example:

<% /* my comment */ %>
or
<% // my comment %>

Server side compile in rails

Hey guys-

So I serve a JS site using rails (I love my asset pipeline), and am looking to switch over from eco, but this workflow is quite dependent on the https://github.com/sstephenson/ruby-eco gem — which provides the hooks necessary for sprockets, etc...for out of the box compilation.

Does an equivalent gem (or process) exist for ect? Just curious if anyone else has done this process before I jump down a rabbit hole that may be deeper than I want it to be. :)

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.