Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin opts filter #295

Closed
wants to merge 35 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
3f39a80
move closing tag check to scanLine
Jul 15, 2017
7250566
move old include code to scanLine
Jul 15, 2017
306f962
refactor parser, one full tag per scanline
Jul 20, 2017
0d01573
remove mode LITERAL / no longer needed
Jul 29, 2017
8bc8316
changed literal tags to be standalone (no longer affect the next tag)…
Aug 4, 2017
fdb09af
speed up, run regex for literals only if needed
Aug 4, 2017
01703cd
preview next-open/prev-close tag
Jul 29, 2017
f48ebaa
fix slurping for <%_ _%> with other delim
Jul 29, 2017
e14c2e7
refactor [-_]%> new line slurp
Jul 29, 2017
1877669
combine __append calls
Jul 21, 2017
bd966be
only calculate newLineCount when compileDebug = true
Jul 30, 2017
95d88f4
sample code for mixin
Jul 13, 2017
9a94c4f
improve sample code / rename to snippet
Jul 21, 2017
419a284
tests / fix
Jul 28, 2017
8980ec2
adapt to changes in ejs
Jul 29, 2017
f98a6ec
allow new modes added by plugin
Jul 29, 2017
b23a184
moved modes to exports for easier access in plugins
Jul 29, 2017
8878c38
cache argument names
Jul 29, 2017
cecf459
linting
Jul 30, 2017
d0fdc47
moved snippet to plugin folder
Aug 14, 2017
4d228bc
improve tests / run with/without plugin
Aug 14, 2017
089723d
fix: do not create args when opts.client is set
Aug 14, 2017
4837daa
docs
Aug 14, 2017
fd0b34a
rename key/method names to comply with docs
Aug 14, 2017
ddc1c7e
improve build args
Aug 14, 2017
65e5138
fixing docs markup
Aug 14, 2017
9aaa9ca
amend docs
Aug 14, 2017
565354c
combine open/close pattern
Aug 15, 2017
4fae4d9
add a hook for fs.existsSync, same as already exists for readFileSync
Aug 15, 2017
772c81e
added cache for file exists
Aug 15, 2017
72921a2
plugin locals
Jul 30, 2017
cd0740f
opts-filter
Aug 16, 2017
68d8eb6
copy opts, so data/locals is not modified
Aug 20, 2017
2953a63
move "var" declarations towards top of blocks
Sep 19, 2017
05df465
remove comment
Sep 19, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions docs/plugin-locals.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
EJS Snippet (plug-in) Reference
==============================

The Locals plug-in is based on the functionality of
https://github.com/RandomEtc/ejs-locals

Locals are not available if opts.client is used.

Table of contents
-----------------

- Activating the plug-in
- layout
- block
- script
- stylesheet
- partial


Activating the plug-in
---------------------

The plug-in is activated by requiring it.

`require('ejs/plug-ins/ejs-locals');`

This modifies the global instance of ejs. So any code using `require('ejs');`
will have an ejs with the plug-in activated.

layout
------

A layout is a wrapper around the current template.

Example:

Template "page":
`Hello world <% layout("layout-bold") %>`

Template "layout-bold"
`<b><%- body %></b>`

Rendering the template "page" will:

- Get the rendered result of "page"
- render "layout-bold", passing the result of "page" as the locals value "body"
- return the result of "layout-bold" to the app.


block
-----

`<% block("foo", "data" %>`: stores "data" as "foo".

`<% block("foo", "more data" %>`: appends "more data" to "foo" (with a newline)

`<%- block("foo" %>`: inserts the content of foo


### script

`<% script("SOURCE" %>`: adds a script tag `<script src="SOURCE"></script>`

`<% script("SOURCE", "TYPE" %>`: adds a script tag `<script src="SOURCE" type="TYPE"></script>`

script tags are joined with newlines.

`<%- script() %>': insert the script tags

### stylesheet

`<% stylesheet("SOURCE" %>`: adds a script tag `<link rel="stylesheet" href="SOURCE" />`

`<% stylesheet("SOURCE", "MEDIA" %>`: adds a script tag `<link rel="stylesheet" href="SOURCE" media="MEDIA" />`

stylesheet tags are joined with newlines.

`<%- stylesheet() %>': insert the stylesheet tags


partial
-------

An extended version of include.

Partials are searched as follows

- relative file names resolve according to the directory of the current template
- absolute file names resolve in opts.root (or / if opts.root is not set)

The following file names are looked up (example `<%- partial("foo/bar") %>`:

- foo/_bar.ejs
- foo/bar.ejs
- foo/bar/index.ejs

Partials can be called as `<%- partial("foo/bar") %>` or `<%- partial("foo/bar", data) %>`

Partials will see the locals, as is at the time they are called.

If data is given, it can be:

- An object (plain object)

The plain object is merged to locals.


- An object (plain object) with a "object" key.
- An object with a custom constructor

This object is passed on a special key in the locals (see collection below)


- An object (plain object) with a "collection" key.
- An array of object (or a collection).

The partial is called for each entry.

The entry is put an a special key in the locals.

The key can be given in the plain object under "as" (unless an array is passed).
Otherwise it derived from the file name of the partial.
(foo/bar_some.ejs will become barSome)

57 changes: 57 additions & 0 deletions docs/plugin-opts-filter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
EJS Snippet (plug-in) Reference
==============================

The OptsFilter plug-in lets you set defaults for all ejs options.

It also offers filters to prevent your app or framework from passing
certain options to ejs.

The filters can also be used if your framework uses an older calling
convention and some keys from your locals data are mistaken as options.



Activating the plug-in
---------------------

The plug-in is activated by requiring it.

`require('ejs/plug-ins/ejs-opts-filter');`

This modifies the global instance of ejs. So any code using `require('ejs');`
will have an ejs with the plug-in activated.


Configuration
-------------

`var filter = require('ejs/plug-ins/ejs-opts-filter');`


`filter.keepOnlyOpts = ['cache', 'root'];`

Only the options cache and root are kept.
All other options are blocked.

Use this with caution. You may block important keys, like filename.
You may also block future options, without knowing the consequences.


`filter.removeOpts = ['client'];`

The client option will be blocked.
All other options will be let through.


```
filter.optsDefaults = {
client: false,
root: '/tmp'
};
```

Will set the client and root option, if they are not specified.
That is, if there key is not present on the opts object.

The defaults are applied after the filters.
So a default can be set to an option that was blocked.
154 changes: 154 additions & 0 deletions docs/plugin-snippet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
EJS Snippet (plug-in) Reference
==============================

The Snippet plug-in lets you define snippets (aka Blocks) and use them
anywhere in your template. This works across include boundaries.

Snippets are not available if opts.client is used.

Table of contents
-----------------

- Activating the plug-in
- Defining Snippets
- Calling Snippets
- Snippets and included templates
- Calling Snippets in included templates
- Defining Snippets in included templates
- Including templates inside a Snippet


Activating the plug-in
---------------------

The plug-in is activated by requiring it.

`require('ejs/plug-ins/ejs-snippet');`

This modifies the global instance of ejs. So any code using `require('ejs');`
will have an ejs with the plug-in activated.

Defining Snippets
-----------------

### Definition

To define a snippet use:

`<%* snippet name %> content <%* /snippet %>`

"content" can be anything, including any ejs code.

If content contains ejs code, then this will not be executed until the snippet
is called.
That is any `<%= val %>` or `<% if(val) { %>` will be kept as they are, and
only be executed when they snippet is called. They therefore see the values
the snippet is called with, not the values at definition time.

### Hoisting

Snippets are hoisted.

A snippet defined anywhere in a template, can be used anywhere in this
template. Even before its definition.

This is useful if snippets call each other in a recursion.

Snippets capture a shallow copy of the "locals". Locals are captured as they
are at the start of the template. That is any changes made to locals by
scriptlets in the template will not be seen by the snippet. (Except where
a shallow copy does not preserve the data).

```
<% foo = 'replacement' %>
<%* snippet name %> <%=foo%> <%* /snippet %>
```

The snippet captures the locals *before* foo gets changed.

### Nesting

Snippets can *not* be nested.

Calling Snippets
----------------

Snippets are called using the `snippet()` function (similar to "include" templates).
The function takes one or two arguments.

```
<%- snippet("name") %>
<%- snippet("name", { foo: 5 }) %>
```

The "snippet" function is available in any javascript part of the ejs template.

Calling the snippet() function is running the snippet, treating the snippet as
a template of its own.
The snippet will see the values for locals captured as described in
"Defining Snippets".
If the 2nd argument is given, the values from the 2nd argument are merged to
the captured locals.

Snippets can call other snippets including them self.

Snippets and included templates
-------------------------------

Defining and calling snippets in templates called by `include()`

### Calling Snippets in included templates

Included templates can access any snippet that is available in the outer
template at the time the `include()` is executed.

A snippet is "available" if:

- it is defined anywhere in the outer template.
- if the outer template is an include itself and the snippet is available to
it, from the outer's outer template.
- if the outer template got the snippet from another `include()` (see below)


### Defining Snippets in included templates

If a template is included, then all snippets defined in this template will
become available in the outer template.

Such snippets become available at the time the `include()` is executed.
Once the `include()` was executed they are available anywhere in the outer
template.

If the template "include-me" defines a snippet called "foo"

```
<% for(a=1; i<9; i++) { %>
<% if(i > 0) { %>
<% snippet('foo') %>
<% } %>
<% include('include-me') %>
<% } %>
```

In the first run of the loop, the snippet "foo" would not be defined. But in
the 2nd run it is defined.

#### Replacing Snippets by included templates

If an included template defines a snippet with the same name as a snippet
available in the outer template, then the snippet from the included template
replaces the snippet from the outer template.

In the included template only the new snippet will be used, as it is hoisted.

In the outer template the snippet will be replaced at the time the `include()`
is executed.


### Including templates inside a Snippet

Snippets can contain `include()` calls. And in the include templates
new snippets can be defined, or existing ones be replaced.
All the rules above apply.

An include can replace the snippet from which it is called.
Loading