├── index.js ├── examples ├── views │ ├── fat.mustache │ ├── index.mustache │ ├── nav.mustache │ └── layout.mustache ├── public │ └── application.css └── app.js ├── README.md ├── package.json ├── test └── test.js └── lib └── stache.js /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./lib/stache'); 2 | -------------------------------------------------------------------------------- /examples/views/fat.mustache: -------------------------------------------------------------------------------- 1 | My name is {{name}}, and i wanted to say "{{message}}" -------------------------------------------------------------------------------- /examples/views/index.mustache: -------------------------------------------------------------------------------- 1 | {{helloworld}}!!! You are currently viewing: {{hellopage}}! 2 | 3 | {{>img}} -------------------------------------------------------------------------------- /examples/views/nav.mustache: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Stache is no longer being actively maintained. 2 | ---------------------------------------------- 3 | 4 | But don't worry. Hogan.js is! and it's a part of TJ's consolidate: 5 | 6 | https://github.com/visionmedia/consolidate.js 7 | 8 | Use that instead! :{o 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stache", 3 | "description": "mustache templating for your express apps", 4 | "version": "0.1.0", 5 | "authors": ["Jacob Thornton <@fat>"], 6 | "keywords": ["mustache", "express", "stache"], 7 | "main": "./index.js", 8 | "engines": { "node": ">= 0.4.1" }, 9 | "dependencies": { 10 | "mustache": ">= 0.2.3", 11 | "express": ">= 2.1.0" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/views/layout.mustache: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{title}} 6 | 7 | 8 | 9 | {{>nav}} 10 |
11 | {{{yield}}} 12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var stache = require("../"); 3 | 4 | var options = { 5 | locals: { 6 | two: '2', 7 | four: 'for' 8 | }, 9 | partials: { 10 | three: 'tres {{four}}' 11 | } 12 | }; 13 | 14 | var source = 'one {{two}} {{>three}}'; 15 | 16 | //just render 17 | var rendered = stache.render(source, options); 18 | assert.equal(rendered, 'one 2 tres for'); 19 | 20 | //compile then render 21 | var template = stache.compile(source, options); 22 | var rendered = stache.render(template, options); 23 | assert.equal(rendered, 'one 2 tres for'); 24 | 25 | //compile empty object without freaking out 26 | var rendered = stache.render('feels good man', {}); 27 | assert.equal(rendered, 'feels good man'); 28 | 29 | console.log('looks good boss.') -------------------------------------------------------------------------------- /examples/public/application.css: -------------------------------------------------------------------------------- 1 | /* GENERIC */ 2 | body { 3 | font-family:'helvetica neue', helvetica, arial; 4 | font-size:14px; 5 | } 6 | 7 | img { 8 | display:block; 9 | } 10 | 11 | /* NAVIGATION */ 12 | #navigation { 13 | background: #DDEEF6; 14 | position:fixed; 15 | left:30px; 16 | top:10px; 17 | border-radius: 8px; 18 | list-style: none; 19 | padding: 0; 20 | font-size:12px; 21 | } 22 | 23 | #navigation .title { 24 | font-size:16px; 25 | color:#333; 26 | border-bottom:1px solid #B8D5E3; 27 | padding: 4px 20px 4px 10px; 28 | background-color:transparent !important; 29 | } 30 | 31 | #navigation li:nth-child(2) { 32 | border-top: 1px solid #fff; 33 | } 34 | 35 | #navigation a { 36 | display:block; 37 | color: #456; 38 | text-shadow: 0 1px 0 #fff; 39 | text-decoration:none; 40 | padding: 4px 20px 4px 10px; 41 | } 42 | 43 | #navigation li:last-child { 44 | border-radius: 0 0 8px 8px; 45 | } 46 | 47 | #navigation li:hover { 48 | background:#D1E6F0; 49 | } 50 | 51 | /* WORKSPACE */ 52 | 53 | #workspace { 54 | width:780px; 55 | margin: 20px auto; 56 | } -------------------------------------------------------------------------------- /examples/app.js: -------------------------------------------------------------------------------- 1 | // module depencies 2 | var express = require('express') 3 | , app = express.createServer(); 4 | 5 | // config 6 | app.set('view engine', 'mustache') 7 | app.set("views", __dirname + '/views'); 8 | app.register(".mustache", require('stache')); 9 | app.use(express.static(__dirname + '/public')); 10 | 11 | // helpers 12 | app.helpers({ 13 | helloworld: function(req, res){ 14 | return 'hello world'; 15 | } 16 | }); 17 | 18 | // dynamicHelpers 19 | app.dynamicHelpers({ 20 | hellopage: function(req, res){ 21 | return req.url; 22 | } 23 | }); 24 | 25 | // routes 26 | app.get('/', function (req, res) { 27 | res.render('index', { 28 | locals: { 29 | title: 'Welcome' 30 | } 31 | , partials: { 32 | img: '' 33 | } 34 | }); 35 | }); 36 | 37 | app.get('/user/:name', function (req, res) { 38 | res.render(req.params.name, { 39 | locals: { 40 | title: req.params.name + '\'s page' 41 | , name: req.params.name 42 | , message: 'stache it in your stache!' 43 | } 44 | }); 45 | }); 46 | 47 | //Run 48 | app.listen(3000); 49 | 50 | console.log('example running on port 3000') -------------------------------------------------------------------------------- /lib/stache.js: -------------------------------------------------------------------------------- 1 | /*! written by @fat 2 | * but major props to donpark && bitdrift && mustache.js 3 | */ 4 | var stache = {} 5 | , fs = require('fs') 6 | , path = require("path") 7 | , mustache = require('mustache') 8 | , views = './views' 9 | 10 | stache.compile = function (source, options) { 11 | views = (options && options.settings && options.settings.views) || views 12 | 13 | if (typeof source == 'string') { 14 | return function (options) { 15 | var partials_regex = new RegExp("{{([>-])([^\\/#\\^]+?)\\1?}}+", "g") 16 | , lines = source.split("\n") 17 | , i = 0 18 | , view 19 | 20 | function tag_replace_callback(match, operator, name) { 21 | if (operator == '>' && !options.partials[name]) { 22 | var partialFileName = views + '/' + name + (options.extension || '.mustache') 23 | return path.existsSync(partialFileName) ? fs.readFileSync(partialFileName, "utf-8") : "" 24 | } 25 | return match 26 | } 27 | 28 | options.partials = options.partials || {} 29 | 30 | if (options.body) { 31 | options.yield = options.body 32 | } 33 | 34 | for (i; i < lines.length; i++) { 35 | lines[i] = lines[i].replace(partials_regex, tag_replace_callback, this) 36 | } 37 | 38 | return mustache.to_html(lines.join('\n'), options, options.partials) 39 | } 40 | } else { 41 | return source 42 | } 43 | }; 44 | 45 | stache.render = function(template, options) { 46 | template = stache.compile(template, options) 47 | return template(options) 48 | } 49 | 50 | module.exports = stache --------------------------------------------------------------------------------