Skip to content

Commit

Permalink
feat: add partial blocks (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmjuanes authored Dec 25, 2024
1 parent e0292a2 commit 3af1861
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,28 @@ const result = m("User: {{>user userName=name userEmail=email }}", data, {partia

Please note that providing keyword arguments and a custom context to a partial is not supported. On this situation, the partial will be evaluated only with the custom context.

#### Partial blocks

> This feature was added in `v0.16.0`.
You can pass a block to a partial using a greather than symbol `>>` followed by the partial name to start the partial block, and a slash followed by the partial name to end the partial block. The provided block content will be available in the `@content` variable.

Example:

```javascript
const options = {
partials: {
foo: "Hello {{@content}}!",
},
};

const result = m("{{>>foo}}Bob{{/foo}}", {}, options);
// Output: 'Hello Bob!'
```

### Inline partials

> Added in `v0.16.0`.
> This feature was added in `v0.16.0`.
Inline partials allows you to define partials directly in your template. Use the plus symbol `+` followed by the partial name to start the partial definition, and end the partial definition with a slash `/` followed by the partial name. For example, `{{<foo}}` begins a partial definition called `foo`, and `{{/foo}}` ends it.

Expand Down
9 changes: 7 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,15 @@ const create = (template = "", options = {}) => {
i = i + lastIndex + 1;
}
else if (tokens[i].startsWith(">")) {
const [t, args, opt] = parseArgs(tokens[i].slice(1), context, vars);
const [t, args, opt] = parseArgs(tokens[i].replace(/^>{1,2}/, ""), context, vars);
const blockContent = []; // to store partial block content
if (tokens[i].startsWith(">>")) {
i = compile(tokens, blockContent, context, vars, i + 1, t);
}
if (typeof partials[t] === "string") {
const newCtx = args.length > 0 ? args[0] : (Object.keys(opt).length > 0 ? opt : context);
compile(tokenize(partials[t]), output, newCtx, vars, 0, "");
const newVars = {...vars, content: blockContent.join("")};
compile(tokenize(partials[t]), output, newCtx, newVars, 0, "");
}
}
else if (tokens[i].startsWith("=")) {
Expand Down
10 changes: 10 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ describe("templating", () => {
});
});

describe("{{>> xyz}}", () => {
it("should allow providing a block to the partial", () => {
const partials = {
foo: "Hello {{@content}}!",
};

assert.equal(m("{{>>foo}}Bob{{/foo}}", {}, {partials}), "Hello Bob!");
});
});

describe("{{#each }}", () => {
it("should do nothing if value is not an array or object", () => {
assert.equal(m("x{{#each values}}{{.}}{{/each}}x", {values: null}), "xx");
Expand Down

0 comments on commit 3af1861

Please sign in to comment.