使用node.js和backbone.js进行模板渲染

有没有人find一个很好的解决scheme来开发可以在服务器和客户端上使用的backbone.js模板?

这对于backbone.js历史堆栈是非常有用的,因为用户可以在浏览器地址栏中共享和链接到真实的URL,并且node.js服务器可以在第一页视图中呈现页面,而在客户端使用相同的模板在随后的页面浏览中重build页面。

这也将为蜘蛛链接的用户和search引擎提供理想的输出,并且不必parsing或执行javascript来查看完全呈现和工作页面。

更新了更多信息:

两种可能的方法似乎是:

1)骨头 – https://github.com/developmentseed/bones

骨头有一些怪癖安装,目前需要旧版本的节点和NPM。

2)胶囊 – https://github.com/andyet/capsule

我还没有尝试过,但似乎相似。 如果有人对这些项目感兴趣,我会感兴趣。

我目前正在研究一个名叫“onecode”的框架 ,它可以满足你的要求。 目前它缺乏文档,但我有一个基于它的工作项目,所以它也可以为你工作。 我也在寻找贡献者。

这是如何工作的。 几乎所有的代码都在客户端和服务器之间共享,包括模型和视图。

  1. 在服务器上,您将创build一个REST API,您可以在其中定义业务规则,安全性,数据库操作以及所有您不能信任的客户端。
  2. 这个API既可以从客户端(使用标准的Backbone Ajax调用),也可以在页面首次被请求时(直接使用重写的$.ajax方法)从服务器本身使用。
  3. 当一个客户端请求一个页面时,服务器创build所有需要的模型和视图,直接请求API并呈现HTML。 此外,它还记得来自API调用的所有数据,以及哪些HTML元素对应于哪个视图。
  4. 模型/查看代码,HTML和数据提供给客户端。 在这里,HTML是完全呈现和function,所以即使用户closuresJavaScript,他可以点击链接和浏览网站(他当然不会得到任何dynamicfunction)。 但是,如果启用了Javascript,则所有模型和视图都会在后台自动重新创build并重新绑定到DOM节点,而不会让用户等待。
  5. 之后,应用程序就像一个单页面应用程序一样工作,只从同一个API请求数据(json),在客户端呈现模板。

这意味着:

  1. 你只写一次演示文稿和dynamic代码。
  2. 第一个请求的页面以快速的方式提供给用户,并不需要等待所有的脚本加载和运行,只需要HTML / CSS即可。
  3. 接下来的页面也非常快,因为只有原始数据被请求,模板在客户端上呈现。 您也可以使其视觉吸引力,而不是通常的页面重新加载。 用户浏览网站时甚至可以播放音乐。
  4. search引擎和社交networking爱你。

架构迫使一些理智的要求,这将使你成为一个更好的开发人员。 就像是:

  1. 服务器操作和业务规则需要单独定义好的API。
  2. 没有全局variables。
  3. 视图的处理比一般的Backbone更严格,更像是可堆叠的UI组件。
  4. HTML呈现和dynamic行为清晰分离。

一个非常简单的例子可以在源码树中find。 我使用Backbone作为模型和视图的基础,而Browserify将js包提供给客户端。

在我的项目中,我使用带EJS的内联模板作为模板引擎。 这有利于保持HTML和代码(我使用CoffeeScript)在同一个地方。 但是该框架能够从外部文件打包模板,以及像Jade这样的其他模板引擎。 请看,如何可以做一个模板的例子 。

请让我知道,如果你有兴趣这种方法,也许会迫使我开始写文档。

我没有用它作为节点,但是我已经很大程度上用了backbone.js的胡子,并且对结果感到满意,并且它有一个端口可以和节点一起使用。

http://mustache.github.com/

在select模板语言方面,您几乎可以select任何基于js的模板语言,包括下划线模板 , 小胡子或把手 – 在Node.js应用程序也可以读取的公共可访问path中设置模板很简单当服务器端生成内容时。

我个人最喜欢的是Jade ,它是用Express开箱的,它实现了一个非常简单,富有performance力的编码风格。

你可以在这里find一个关于如何将Backbone.js和Express(使用Jade作为模板语言)链接在一起的好书写。

大多数示例倾向于如何设置一个完全呈现客户端的RESTful应用程序(而不是你真的以后)。

但是,如果你从一个可公开访问的文件夹中的模板中获取你的Web应用程序(我build议保持视图分开 – 预处理你的模板,并把html传递到你的视图,所以你保持模板特定),那么你就可以从Backbone.js加载它们,并使用Backbone.js的历史堆栈处理更改。

你可以使用JSDOM来渲染你的页面,如下所示

 // specify a catch all route app.get('/namespace/*', function (req, res, next) { // load the dom jsdom.env({ html: html, src: src, features: { FetchExternalResources: false, ProcessExternalResources: false }, done: function (err, window) { // overwrite Backbone's sync method with a server-side one window.Backbone.sync = sync window.$(function () { window.Backbone.history.start({ silent: true }) // load requested url var matched = window.Backbone.history.loadUrl(req.originalUrl.substr(1)) if (matched) // if matched: return resulting html res.end(window.document.innerHTML) else next() }) } }) }) 

因此,您还必须指定以下variables

 var sync = function(method, model, options, error) { // your server side sync method } var html = fs.readFileSync(path.join(__dirname, 'views/index.htm'), 'utf-8') var src = [ fs.readFileSync(path.join(__dirname, 'public/javascripts/jquery.js'), 'utf-8'), fs.readFileSync(path.join(__dirname, 'public/javascripts/underscore.js'), 'utf-8'), fs.readFileSync(path.join(__dirname, 'public/javascripts/backbone.js'), 'utf-8'), fs.readFileSync(path.join(__dirname, 'public/javascripts/your-backbone-stuff.js'), 'utf-8') ] 

不幸的是,我没有find一个解决scheme来复制创build的窗口/文档对象以供重用。

而且这个解决scheme仅适用于例如search引擎,因为它没有从Backbone Views到那里相应的DOM节点的客户端映射。

尝试https://github.com/flatiron/plates

在这两种环境中都能很好地工作,没有DSL,并且有一个干净的API

https://github.com/BorisMoore/jsrender试试jsrender

它是从jQuery tmpl重写的,不需要jQuery或任何DOM。 它是独立的在一个单一的文件,作者保持非常新鲜。

jsrender是模板的stringreplace引擎。 我们将它用于NodeJS中的dynamic和静态页面。 我们还将其用于非HTML模板,例如XML,CSV和基于文本的电子邮件。 虽然现在还不是生产模式,但是我们已经使用了几个月,发展到目前为止非常稳定。

看看http://borismoore.github.com/jsrender/demos/demos.html上的一些很酷的演示。

最简单的,你可以做foreach循环。 但是,如果你正在走专家路线或冒险,你可以让JS代码运行(内联或作为函数,也就是助手)。 当然,在表示层中有代码是不好的,但是有时用你最喜欢的语言来进行简单的odd()/ even()或者n + 1计算并不会有什么坏处。 只要确保你在层次之间有一个很好的理解并承担风险。

使用nunjucks模板的Node.js对我来说工作的非常好,因为我需要非SGML网页内容的非XML模板(nunjucks允许在文本模板中设置模板分隔符 – 对于jinja2来说,英)

这是一个在NodeJS中渲染Underscore / Backbone模板的非常简单的例子。 我已经使用NPM安装了Underscore。

 var http = require('http'), _ = require('underscore'); http.createServer(function (req, res) { var template = "<h1><%=message%></h1>" res.end(_.template( template, {message: "Hello world"})); }).listen(8080, 'localhost'); 

我尝试了很多解决scheme, http ://ezeljs.com/绝对是最简单和最容易实现的。 这是有道理的。

Backbone项目的样板,共享代码服务器/客户端,渲染服务器/客户端,并通过模块化架构进行扩展。

使用Jade模板,用于服务器和客户端。 Browserify和使用Jade转换,绝对是我在客户端和服务器上共享模板的首选方法。