UNPKG

3.86 kBtext/coffeescriptView Raw
1eco = require 'eco'
2mongoose = require 'mongoose'
3fs = require 'fs'
4findit = require 'findit'
5
6
7# REGEXs
8
9name_regex = /"(\w|\d|_|\/)+"/
10block_start_regex = /<% ?block "(\w|\d|_)+" ?%>/g
11block_end_regex = /<% ?endblock ?%>/g
12parent_regex = /^<% ?parent "(\w|\d|_|\/)+" ?%>/g
13include_regex = /<% ?include "(\w|\d|_|\/)+" ?%>/g
14
15# HELPERS
16
17get_name = (tag) -> name_regex.exec(tag)[0].replace('"', '').replace('"', '')
18
19parse_includes = (src, templates) ->
20 tags = src.match(include_regex)
21 while tags?
22 tags.each (tag) ->
23 name = get_name tag
24
25 if templates[name]?
26 include_src = templates[name]
27 else
28 include_src = "<p>Error: Template <b>#{ name }</b> not found.</p>"
29
30 src = src.replace(tag, include_src)
31 tags = src.match(include_regex)
32 src
33
34
35read_blocks = (src) ->
36 blocks = {}
37 tags = src.match(block_start_regex)
38 if tags
39 tags.each (tag) ->
40 name = get_name tag
41 start = src.search(tag)
42 end = start + src.substring(start).search(block_end_regex)
43 content = src.substring(start, end).replace(tag, '')
44 blocks[name] = content
45 blocks
46
47
48replace_blocks = (src, blocks) ->
49 tags = src.match(block_start_regex)
50 if tags
51 tags.each (tag) ->
52 name = get_name tag
53 start = src.search(tag)
54 end = start + src.substring(start).search(block_end_regex)
55 content = src.substring(start, end).replace(tag, '')
56
57 src = src.replace content, blocks[name] if blocks[name]?
58 src
59
60
61clear_blocks = (src) ->
62 src.replace(block_start_regex, '').replace(block_end_regex, '')
63
64
65parse_parents = (src, templates) ->
66 blocks = read_blocks(src)
67
68 tags = src.match(parent_regex)
69 while tags?
70 name = get_name tags.first()
71
72 if templates[name]?
73 parent_src = templates[name]
74 else
75 parent_src = "<p>Error: Template <b>#{ name }</b> not found.</p>"
76
77 parent_blocks = read_blocks(parent_src)
78 blocks = Object.merge( parent_blocks, blocks)
79 tags = parent_src.match(parent_regex)
80
81 src = parent_src if parent_src?
82 src = replace_blocks src, blocks
83 src = clear_blocks src
84
85
86generate = (name, templates) ->
87 #
88 # Note: Recursion is not catched
89 #
90 src = templates[name]
91
92
93 src = parse_parents src, templates
94 src = parse_includes src, templates
95
96
97app.get '/js/templates.js', (req, res) ->
98 funcs = []
99 Object.each app.templates, (name, src) ->
100 if name.has('/_') or name.startsWith('_')
101 try
102 f = eco.compile(src)
103 catch err
104 f = -> console.log "Eco template '#{name}' has compilation problem: #{err}"
105 funcs.push "'#{name}': #{f.toString()}"
106
107 src = """var __templates = { #{ funcs.join(", ") } };
108 var render = function(name, context){
109 if (context == null) { context = {}; }
110 context.conf = #{JSON.stringify(app.conf)};
111 if (__templates[name] == null) { return 'Template <b>' + name + '</b> not found.'; }
112 return __templates[name](context);
113 }"""
114 res.contentType 'application/javascript'
115 res.send src
116
117
118# Load templates from files
119load_templates = ->
120 templates = {}
121 findit.sync app.conf.templates_path, (f) ->
122 if f.endsWith('.html')
123 name = f.remove(app.conf.templates_path + '/').remove('.html')
124 src = fs.readFileSync(f, 'utf-8')
125 templates[name] = src
126 templates
127
128module.exports = load_templates()
129
130
131# Express res.render overriding
132
133http = require('http')
134res = http.ServerResponse.prototype
135
136res.render = (name, context={}) ->
137 templates = load_templates()
138
139 if templates[name]?
140 src = generate(name, templates)
141 try
142 html = eco.render src, context
143 catch err
144 html = "Error: Template <b>#{name}</b> <i>#{err}</i>"
145 else
146 html = "Error: Template <b>#{name}</b> not found."
147
148 @send html