Bladeren bron

Merge 675ca3b1de into 972fd2b27a

pull/828/merge
Luke Blaney GitHub 1 jaar geleden
bovenliggende
commit
53e429ba62
Geen bekende sleutel gevonden voor deze handtekening in de database GPG sleutel-ID: B5690EEEBB952194
6 gewijzigde bestanden met toevoegingen van 102 en 3 verwijderingen
  1. +23
    -0
      README.md
  2. +29
    -2
      mustache.js
  3. +31
    -0
      test/mustache-spec-test.js
  4. +4
    -0
      test/parse-test.js
  5. +14
    -0
      test/partial-test.js
  6. +1
    -1
      test/spec

+ 23
- 0
README.md Bestand weergeven

@@ -419,6 +419,29 @@ Mustache.render(template, view, {
});
```

Partials can have dynamic names, which begin with `*`. In this case, a value is read from the context and the partial with that value is used.

For example, this template and partial:

base.mustache:
<h2>Message of the Day</h2>
{{> *dayOfWeek}}

thursday.mustache:
<span>This must be Thursday. I never could get the hang of Thursdays.</span>

When loaded with the context:
```json
{
"dayOfWeek": "thursday"
}
```
will be expanded to:
```html
<h2>Message of the Day</h2>
<span>This must be Thursday. I never could get the hang of Thursdays.</span>
```

### Custom Delimiters

Custom delimiters can be used in place of `{{` and `}}` by setting the new values in JavaScript or in templates.


+ 29
- 2
mustache.js Bestand weergeven

@@ -79,6 +79,7 @@ var spaceRe = /\s+/;
var equalsRe = /\s*=/;
var curlyRe = /\s*\}/;
var tagRe = /#|\^|\/|>|\{|&|=|!/;
var dynamicRe = /\*/;

/**
* Breaks up the given `template` string into a tree of tokens. If the `tags`
@@ -202,6 +203,14 @@ function parseTemplate (template, tags) {
scanner.scan(curlyRe);
scanner.scanUntil(closingTagRe);
type = '&';
} else if (type === '>') {
if (scanner.scan(dynamicRe) === '') {
value = scanner.scanUntil(closingTagRe);
} else {
scanner.scan(whiteRe);
type = '>*';
value = scanner.scanUntil(closingTagRe);
}
} else {
value = scanner.scanUntil(closingTagRe);
}
@@ -210,7 +219,7 @@ function parseTemplate (template, tags) {
if (!scanner.scan(closingTagRe))
throw new Error('Unclosed tag at ' + scanner.pos);

if (type == '>') {
if (type == '>' || type == '>*') {
token = [ type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace ];
} else {
token = [ type, value, start, scanner.pos ];
@@ -571,6 +580,7 @@ Writer.prototype.renderTokens = function renderTokens (tokens, context, partials
if (symbol === '#') value = this.renderSection(token, context, partials, originalTemplate, config);
else if (symbol === '^') value = this.renderInverted(token, context, partials, originalTemplate, config);
else if (symbol === '>') value = this.renderPartial(token, context, partials, config);
else if (symbol === '>*') value = this.renderDynamicPartial(token, context, partials, config);
else if (symbol === '&') value = this.unescapedValue(token, context);
else if (symbol === 'name') value = this.escapedValue(token, context, config);
else if (symbol === 'text') value = this.rawValue(token);
@@ -636,10 +646,27 @@ Writer.prototype.indentPartial = function indentPartial (partial, indentation, l
return partialByNl.join('\n');
};

Writer.prototype.renderPartial = function renderPartial (token, context, partials, config) {
Writer.prototype.renderDynamicPartial = function renderPartial (token, context, partials, config) {
if (!partials) return;
var tags = this.getConfigTags(config);
var name = context.lookup(token[1].trim());
var value = isFunction(partials) ? partials(name) : partials[name];
if (value != null) {
var lineHasNonSpace = token[6];
var tagIndex = token[5];
var indentation = token[4];
var indentedValue = value;
if (tagIndex == 0 && indentation) {
indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);
}
var tokens = this.parse(indentedValue, tags);
return this.renderTokens(tokens, context, partials, indentedValue, config);
}
};

Writer.prototype.renderPartial = function renderPartial (token, context, partials, config) {
if (!partials) return;
var tags = this.getConfigTags(config);
var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
if (value != null) {
var lineHasNonSpace = token[6];


+ 31
- 0
test/mustache-spec-test.js Bestand weergeven

@@ -14,6 +14,9 @@ var skipTests = {
inverted: [
'Standalone Without Newline'
],
interpolation: [
'Dotted Names - Context Precedence'
],
partials: [
'Standalone Without Previous Line',
'Standalone Without Newline'
@@ -21,6 +24,34 @@ var skipTests = {
sections: [
'Standalone Without Newline'
],
'~inheritance': [
'Default',
'Variable',
'Triple Mustache',
'Sections',
'Negative Sections',
'Mustache Injection',
'Inherit',
'Overridden content',
'Data does not override block',
'Data does not override block default',
'Overridden parent',
'Two overridden parents',
'Override parent with newlines',
'Inherit indentation',
'Only one override',
'Parent template',
'Recursion',
'Multi-level inheritance',
'Multi-level inheritance, no sub child',
'Text inside parent',
'Block scope',
'Standalone parent',
'Standalone block',
'Block reindentation',
'Intrinsic indentation',
'Nested block reindentation'
],
'~lambdas': [
'Interpolation',
'Interpolation - Expansion',


+ 4
- 0
test/parse-test.js Bestand weergeven

@@ -46,6 +46,10 @@ var expectations = {
' {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0, false ] ],
' {{> abc }} {{> abc }}\n' : [ [ '>', 'abc', 2, 12, ' ', 0, false ], [ '>', 'abc', 13, 23, ' ', 1, false ] ],
'{{ > abc }}' : [ [ '>', 'abc', 0, 11, '', 0, false ] ],
'{{>*abc}}' : [ [ '>*', 'abc', 0, 9, '', 0, false ] ],
'{{> *abc}}' : [ [ '>*', 'abc', 0, 10, '', 0, false ] ],
'{{>* abc}}' : [ [ '>*', 'abc', 0, 10, '', 0, false ] ],
'{{ > * abc }}' : [ [ '>*', 'abc', 0, 13, '', 0, false ] ],
'{{=<% %>=}}' : [ [ '=', '<% %>', 0, 11 ] ],
'{{= <% %> =}}' : [ [ '=', '<% %>', 0, 13 ] ],
'{{=<% %>=}}<%={{ }}=%>' : [ [ '=', '<% %>', 0, 11 ], [ '=', '{{ }}', 11, 22 ] ],


+ 14
- 0
test/partial-test.js Bestand weergeven

@@ -172,4 +172,18 @@ describe('Partials spec', function () {
var renderResult = Mustache.render(template, {}, partials, tags);
assert.equal(renderResult, expected);
});

describe('when rendering a dynamically named partial after already having rendered that partial with a different name value', function () {
it('returns different output for the latter render', function () {
var template = 'Place: {{>*place}}';
var partials = {
first: '1st',
second: '2nd',
};
var renderedFirst = Mustache.render(template, {place:'first'}, partials);
var renderedSecond = Mustache.render(template, {place:'second'}, partials);

assert.notEqual(renderedFirst, renderedSecond);
});
});
});

+ 1
- 1
test/spec

@@ -1 +1 @@
Subproject commit 72233f3ffda9e33915fd3022d0a9ebbcce265acd
Subproject commit 7138576e12ff0f05511de77807c2fb3959bb22e3

Laden…
Annuleren
Opslaan