1 | /**
|
2 | * @file Wrapper for underscore's template utility to allow loading templates from files.
|
3 | * @author Rafał Wrzeszcz <rafal.wrzeszcz@wrzasq.pl>
|
4 | * @author <a href="mailto:matthewkastor@gmail.com">Matthew Christopher Kastor-Inare III</a>
|
5 | * @license Apache License 2.0 - See file 'LICENSE.md' in this project.
|
6 | */
|
7 | ;
|
8 |
|
9 | var _ = require('underscore'),
|
10 | fs = require('jsdoc/fs'),
|
11 | path = require('path');
|
12 |
|
13 | /**
|
14 | @module jsdoc/template
|
15 | */
|
16 |
|
17 | /**
|
18 | @class
|
19 | @classdesc Underscore template helper.
|
20 | @param {string} filepath - Templates directory.
|
21 | */
|
22 | exports.Template = function(filepath) {
|
23 | this.path = filepath;
|
24 | this.layout = null;
|
25 | this.cache = {};
|
26 | // override default template tag settings
|
27 | this.settings = {
|
28 | evaluate: /<\?js([\s\S]+?)\?>/g,
|
29 | interpolate: /<\?js=([\s\S]+?)\?>/g,
|
30 | escape: /<\?js~([\s\S]+?)\?>/g
|
31 | };
|
32 | };
|
33 |
|
34 | /** Loads template from given file.
|
35 | @param {string} file - Template filename.
|
36 | @return {function} Returns template closure.
|
37 | */
|
38 | exports.Template.prototype.load = function(file) {
|
39 | return _.template(fs.readFileSync(file, 'utf8'), null, this.settings);
|
40 | };
|
41 |
|
42 | /**
|
43 | Renders template using given data.
|
44 |
|
45 | This is low-level function, for rendering full templates use {@link Template.render()}.
|
46 |
|
47 | @param {string} file - Template filename.
|
48 | @param {object} data - Template variables (doesn't have to be object, but passing variables dictionary is best way and most common use).
|
49 | @return {string} Rendered template.
|
50 | */
|
51 | exports.Template.prototype.partial = function(file, data) {
|
52 | file = path.resolve(this.path, file);
|
53 |
|
54 | // load template into cache
|
55 | if (!(file in this.cache)) {
|
56 | this.cache[file] = this.load(file);
|
57 | }
|
58 |
|
59 | // keep template helper context
|
60 | return this.cache[file].call(this, data);
|
61 | };
|
62 |
|
63 | /**
|
64 | Renders template with given data.
|
65 |
|
66 | This method automaticaly applies layout if set.
|
67 |
|
68 | @param {string} file - Template filename.
|
69 | @param {object} data - Template variables (doesn't have to be object, but passing variables dictionary is best way and most common use).
|
70 | @return {string} Rendered template.
|
71 | */
|
72 | exports.Template.prototype.render = function(file, data) {
|
73 | // main content
|
74 | var content = this.partial(file, data);
|
75 |
|
76 | // apply layout
|
77 | if (this.layout) {
|
78 | data.content = content;
|
79 | content = this.partial(this.layout, data);
|
80 | }
|
81 |
|
82 | return content;
|
83 | };
|