|
1 | | -Embedded JavaScript templates |
| 1 | +# @photostructure/ejs (DEPRECATED) |
2 | 2 |
|
3 | | -[](https://www.npmjs.com/package/@photostructure/ejs) |
4 | | -[](https://github.com/photostructure/ejs/actions/workflows/build.yml) |
5 | | -[](https://snyk.io/test/npm/@photostructure/ejs) |
6 | | - |
7 | | -## Installation |
| 3 | +This package is deprecated. Please use [`ejs`](https://www.npmjs.com/package/ejs) instead. |
8 | 4 |
|
9 | 5 | ```bash |
10 | | -$ npm install @photostructure/ejs |
11 | | -``` |
12 | | - |
13 | | -## Fork information |
14 | | - |
15 | | -This is an actively maintained fork of [mde/ejs](https://github.com/mde/ejs) sponsored by [PhotoStructure](https://photostructure.com/). |
16 | | - |
17 | | -Changes from upstream: |
18 | | - |
19 | | -- TypeScript types included (and tested with `tsd`) |
20 | | -- Removed CLI support (dropped `jake` runtime dependency) |
21 | | -- Updated all development dependencies (eslint, lru-cache v7+ compatibility, etc.) |
22 | | -- Security fixes from upstream |
23 | | -- Modern GitHub Actions with OIDC signing and [signed git tags](https://github.com/photostructure/git-ssh-signing-action) |
24 | | - |
25 | | -## Features |
26 | | - |
27 | | -- Control flow with `<% %>` |
28 | | -- Escaped output with `<%= %>` (escape function configurable) |
29 | | -- Unescaped raw output with `<%- %>` |
30 | | -- Newline-trim mode ('newline slurping') with `-%>` ending tag |
31 | | -- Whitespace-trim mode (slurp all whitespace) for control flow with `<%_ _%>` |
32 | | -- Custom delimiters (e.g. `[? ?]` instead of `<% %>`) |
33 | | -- Includes |
34 | | -- Client-side support |
35 | | -- Static caching of intermediate JavaScript |
36 | | -- Static caching of templates |
37 | | -- Complies with the [Express](http://expressjs.com) view system |
38 | | - |
39 | | -## Example |
40 | | - |
41 | | -```ejs |
42 | | -<% if (user) { %> |
43 | | - <h2><%= user.name %></h2> |
44 | | -<% } %> |
45 | | -``` |
46 | | - |
47 | | -Try EJS online at: https://ionicabizau.github.io/ejs-playground/. |
48 | | - |
49 | | -## Basic usage |
50 | | - |
51 | | -```javascript |
52 | | -let template = ejs.compile(str, options); |
53 | | -template(data); |
54 | | -// => Rendered HTML string |
55 | | - |
56 | | -ejs.render(str, data, options); |
57 | | -// => Rendered HTML string |
58 | | - |
59 | | -ejs.renderFile(filename, data, options, function (err, str) { |
60 | | - // str => Rendered HTML string |
61 | | -}); |
62 | | -``` |
63 | | - |
64 | | -It is also possible to use `ejs.render(dataAndOptions);` where you pass |
65 | | -everything in a single object. In that case, you'll end up with local variables |
66 | | -for all the passed options. However, be aware that your code could break if we |
67 | | -add an option with the same name as one of your data object's properties. |
68 | | -Therefore, we do not recommend using this shortcut. |
69 | | - |
70 | | -### Important |
71 | | - |
72 | | -You should never give end-users unfettered access to the EJS render method, If you do so you are using EJS in an inherently un-secure way. |
73 | | - |
74 | | -### Options |
75 | | - |
76 | | -- `cache` Compiled functions are cached, requires `filename` |
77 | | -- `filename` The name of the file being rendered. Not required if you |
78 | | - are using `renderFile()`. Used by `cache` to key caches, and for includes. |
79 | | -- `root` Set project root for includes with an absolute path (e.g, /file.ejs). |
80 | | - Can be array to try to resolve include from multiple directories. |
81 | | -- `views` An array of paths to use when resolving includes with relative paths. |
82 | | -- `context` Function execution context |
83 | | -- `compileDebug` When `false` no debug instrumentation is compiled |
84 | | -- `client` When `true`, compiles a function that can be rendered |
85 | | - in the browser without needing to load the EJS Runtime |
86 | | - ([ejs.min.js](https://github.com/mde/ejs/releases/latest)). |
87 | | -- `delimiter` Character to use for inner delimiter, by default '%' |
88 | | -- `openDelimiter` Character to use for opening delimiter, by default '<' |
89 | | -- `closeDelimiter` Character to use for closing delimiter, by default '>' |
90 | | -- `debug` Outputs generated function body |
91 | | -- `strict` When set to `true`, generated function is in strict mode |
92 | | -- `_with` Whether or not to use `with() {}` constructs. If `false` |
93 | | - then the locals will be stored in the `locals` object. Set to `false` in strict mode. |
94 | | -- `destructuredLocals` An array of local variables that are always destructured from |
95 | | - the locals object, available even in strict mode. |
96 | | -- `localsName` Name to use for the object storing local variables when not using |
97 | | - `with` Defaults to `locals` |
98 | | -- `rmWhitespace` Remove all safe-to-remove whitespace, including leading |
99 | | - and trailing whitespace. It also enables a safer version of `-%>` line |
100 | | - slurping for all scriptlet tags (it does not strip new lines of tags in |
101 | | - the middle of a line). |
102 | | -- `escape` The escaping function used with `<%=` construct. It is |
103 | | - used in rendering and is `.toString()`ed in the generation of client functions. |
104 | | - (By default escapes XML). |
105 | | -- `outputFunctionName` Set to a string (e.g., 'echo' or 'print') for a function to print |
106 | | - output inside scriptlet tags. |
107 | | -- `async` When `true`, EJS will use an async function for rendering. (Depends |
108 | | - on async/await support in the JS runtime. |
109 | | -- `includer` Custom function to handle EJS includes, receives `(originalPath, parsedPath)` |
110 | | - parameters, where `originalPath` is the path in include as-is and `parsedPath` is the |
111 | | - previously resolved path. Should return an object `{ filename, template }`, |
112 | | - you may return only one of the properties, where `filename` is the final parsed path and `template` |
113 | | - is the included content. |
114 | | - |
115 | | -This project uses [JSDoc](http://usejsdoc.org/). For the full public API |
116 | | -documentation, clone the repository and run `jake doc`. This will run JSDoc |
117 | | -with the proper options and output the documentation to `out/`. If you want |
118 | | -the both the public & private API docs, run `jake devdoc` instead. |
119 | | - |
120 | | -### Tags |
121 | | - |
122 | | -- `<%` 'Scriptlet' tag, for control-flow, no output |
123 | | -- `<%_` 'Whitespace Slurping' Scriptlet tag, strips all whitespace before it |
124 | | -- `<%=` Outputs the value into the template (escaped) |
125 | | -- `<%-` Outputs the unescaped value into the template |
126 | | -- `<%#` Comment tag, no execution, no output |
127 | | -- `<%%` Outputs a literal '<%' |
128 | | -- `%%>` Outputs a literal '%>' |
129 | | -- `%>` Plain ending tag |
130 | | -- `-%>` Trim-mode ('newline slurp') tag, trims following newline |
131 | | -- `_%>` 'Whitespace Slurping' ending tag, removes all whitespace after it |
132 | | - |
133 | | -For the full syntax documentation, please see [docs/syntax.md](https://github.com/photostructure/ejs/blob/main/docs/syntax.md). |
134 | | - |
135 | | -### Includes |
136 | | - |
137 | | -Includes either have to be an absolute path, or, if not, are assumed as |
138 | | -relative to the template with the `include` call. For example if you are |
139 | | -including `./views/user/show.ejs` from `./views/users.ejs` you would |
140 | | -use `<%- include('user/show') %>`. |
141 | | - |
142 | | -You must specify the `filename` option for the template with the `include` |
143 | | -call unless you are using `renderFile()`. |
144 | | - |
145 | | -You'll likely want to use the raw output tag (`<%-`) with your include to avoid |
146 | | -double-escaping the HTML output. |
147 | | - |
148 | | -```ejs |
149 | | -<ul> |
150 | | - <% users.forEach(function(user){ %> |
151 | | - <%- include('user/show', {user: user}) %> |
152 | | - <% }); %> |
153 | | -</ul> |
154 | | -``` |
155 | | - |
156 | | -Includes are inserted at runtime, so you can use variables for the path in the |
157 | | -`include` call (for example `<%- include(somePath) %>`). Variables in your |
158 | | -top-level data object are available to all your includes, but local variables |
159 | | -need to be passed down. |
160 | | - |
161 | | -NOTE: Include preprocessor directives (`<% include user/show %>`) are |
162 | | -not supported in v3.0+. |
163 | | - |
164 | | -## Custom delimiters |
165 | | - |
166 | | -Custom delimiters can be applied on a per-template basis, or globally: |
167 | | - |
168 | | -```javascript |
169 | | -let ejs = require("@photostructure/ejs"), |
170 | | - users = ["geddy", "neil", "alex"]; |
171 | | - |
172 | | -// Just one template |
173 | | -ejs.render( |
174 | | - '<p>[?= users.join(" | "); ?]</p>', |
175 | | - { users: users }, |
176 | | - { delimiter: "?", openDelimiter: "[", closeDelimiter: "]" } |
177 | | -); |
178 | | -// => '<p>geddy | neil | alex</p>' |
179 | | - |
180 | | -// Or globally |
181 | | -ejs.delimiter = "?"; |
182 | | -ejs.openDelimiter = "["; |
183 | | -ejs.closeDelimiter = "]"; |
184 | | -ejs.render('<p>[?= users.join(" | "); ?]</p>', { users: users }); |
185 | | -// => '<p>geddy | neil | alex</p>' |
186 | | -``` |
187 | | - |
188 | | -### Caching |
189 | | - |
190 | | -EJS ships with a basic in-process cache for caching the intermediate JavaScript |
191 | | -functions used to render templates. It's easy to plug in LRU caching using |
192 | | -Node's `lru-cache` library: |
193 | | - |
194 | | -```javascript |
195 | | -let ejs = require("@photostructure/ejs"), |
196 | | - LRU = require("lru-cache"); |
197 | | -ejs.cache = new LRU({ size: 100 }); // LRU cache with 100-item limit |
198 | | -``` |
199 | | - |
200 | | -If you want to clear the EJS cache, call `ejs.clearCache`. If you're using the |
201 | | -LRU cache and need a different limit, simple reset `ejs.cache` to a new instance |
202 | | -of the LRU. |
203 | | - |
204 | | -### Custom file loader |
205 | | - |
206 | | -The default file loader is `fs.readFileSync`, if you want to customize it, you can set ejs.fileLoader. |
207 | | - |
208 | | -```javascript |
209 | | -let ejs = require("@photostructure/ejs"); |
210 | | -let myFileLoad = function (filePath) { |
211 | | - return "myFileLoad: " + fs.readFileSync(filePath); |
212 | | -}; |
213 | | - |
214 | | -ejs.fileLoader = myFileLoad; |
215 | | -``` |
216 | | - |
217 | | -With this feature, you can preprocess the template before reading it. |
218 | | - |
219 | | -### Layouts |
220 | | - |
221 | | -EJS does not specifically support blocks, but layouts can be implemented by |
222 | | -including headers and footers, like so: |
223 | | - |
224 | | -```ejs |
225 | | -<%- include('header') -%> |
226 | | -<h1> |
227 | | - Title |
228 | | -</h1> |
229 | | -<p> |
230 | | - My page |
231 | | -</p> |
232 | | -<%- include('footer') -%> |
| 6 | +npm uninstall @photostructure/ejs |
| 7 | +npm install ejs |
233 | 8 | ``` |
234 | 9 |
|
235 | | -## Client-side support |
| 10 | +For TypeScript users, install [`@types/ejs`](https://www.npmjs.com/package/@types/ejs) as well: |
236 | 11 |
|
237 | | -Go to the [Latest Release](https://github.com/photostructure/ejs/releases/latest), download |
238 | | -`./ejs.js` or `./ejs.min.js`. Alternately, you can compile it yourself by cloning |
239 | | -the repository and running `jake build` (or `$(npm bin)/jake build` if jake is |
240 | | -not installed globally). |
241 | | - |
242 | | -Include one of these files on your page, and `ejs` should be available globally. |
243 | | - |
244 | | -### Example |
245 | | - |
246 | | -```html |
247 | | -<div id="output"></div> |
248 | | -<script src="ejs.min.js"></script> |
249 | | -<script> |
250 | | - let people = ["geddy", "neil", "alex"], |
251 | | - html = ejs.render('<%= people.join(", "); %>', { people: people }); |
252 | | - // With jQuery: |
253 | | - $("#output").html(html); |
254 | | - // Vanilla JS: |
255 | | - document.getElementById("output").innerHTML = html; |
256 | | -</script> |
257 | | -``` |
258 | | - |
259 | | -### Caveats |
260 | | - |
261 | | -Most of EJS will work as expected; however, there are a few things to note: |
262 | | - |
263 | | -1. Obviously, since you do not have access to the filesystem, `ejs.renderFile()` won't work. |
264 | | -2. For the same reason, `include`s do not work unless you use an `include callback`. Here is an example: |
265 | | - |
266 | | -```javascript |
267 | | -let str = "Hello <%= include('file', {person: 'John'}); %>", |
268 | | - fn = ejs.compile(str, { client: true }); |
269 | | - |
270 | | -fn(data, null, function (path, d) { |
271 | | - // include callback |
272 | | - // path -> 'file' |
273 | | - // d -> {person: 'John'} |
274 | | - // Put your code here |
275 | | - // Return the contents of file as a string |
276 | | -}); // returns rendered string |
| 12 | +```bash |
| 13 | +npm install @types/ejs --save-dev |
277 | 14 | ``` |
278 | 15 |
|
279 | | -See the [examples folder](https://github.com/photostructure/ejs/tree/main/examples) for more details. |
280 | | - |
281 | | -## IDE Integration with Syntax Highlighting |
282 | | - |
283 | | -VSCode:Javascript EJS by _DigitalBrainstem_ |
284 | | - |
285 | | -## Related projects |
286 | | - |
287 | | -There are a number of implementations of EJS: |
288 | | - |
289 | | -- TJ's implementation, the v1 of this library: https://github.com/tj/ejs |
290 | | -- EJS Embedded JavaScript Framework on Google Code: https://code.google.com/p/embeddedjavascript/ |
291 | | -- Sam Stephenson's Ruby implementation: https://rubygems.org/gems/ejs |
292 | | -- Erubis, an ERB implementation which also runs JavaScript: http://www.kuwata-lab.com/erubis/users-guide.04.html#lang-javascript |
293 | | -- DigitalBrainstem EJS Language support: https://github.com/Digitalbrainstem/ejs-grammar |
294 | | - |
295 | | -## License |
296 | | - |
297 | | -Licensed under the Apache License, Version 2.0 |
298 | | -(<http://www.apache.org/licenses/LICENSE-2.0>) |
299 | | - |
300 | | ---- |
| 16 | +## Why? |
301 | 17 |
|
302 | | -EJS Embedded JavaScript templates copyright 2112 |
303 | | -mde@fleegix.org. |
| 18 | +This was a temporary fork of [mde/ejs](https://github.com/mde/ejs) created while the upstream project was inactive. The upstream project is now actively maintained again (v5.0.1+ with ESM support), making this fork unnecessary. |
0 commit comments