Skip to content
This repository was archived by the owner on Dec 10, 2019. It is now read-only.

Commit 7243967

Browse files
committed
Handlebars (and possibly other engines) need to be excluded from
"partial expansion", the process of recursively "manually" rendering partials into the extendedTemplate property of the oPattern, in order to have access to the calling pattern's correct JSON environment. Each engine must indicate if it supports partial expansion (probably no by default). Also, factor out the partial expansion process from the main processPatternRecursively function for clarity and easy conditionalizing, and add a unit test to verify that this works okay.
1 parent 7a6d9c6 commit 7243967

File tree

4 files changed

+94
-57
lines changed

4 files changed

+94
-57
lines changed

builder/pattern_assembler.js

Lines changed: 55 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -139,22 +139,61 @@
139139

140140

141141

142+
function expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern) {
143+
var smh = require('./style_modifier_hunter'),
144+
ph = require('./parameter_hunter');
145+
146+
var style_modifier_hunter = new smh(),
147+
parameter_hunter = new ph();
148+
149+
if(patternlab.config.debug){
150+
console.log('found partials for ' + currentPattern.key);
151+
}
152+
153+
// determine if the template contains any pattern parameters. if so they
154+
// must be immediately consumed
155+
parameter_hunter.find_parameters(currentPattern, patternlab);
156+
157+
//do something with the regular old partials
158+
for(var i = 0; i < foundPatternPartials.length; i++){
159+
var partialKey = currentPattern.getPartialKey(foundPatternPartials[i]);
160+
var partialPath;
161+
162+
//identify which pattern this partial corresponds to
163+
for(var j = 0; j < patternlab.patterns.length; j++){
164+
if(patternlab.patterns[j].key === partialKey ||
165+
patternlab.patterns[j].abspath.indexOf(partialKey) > -1)
166+
{
167+
partialPath = patternlab.patterns[j].abspath;
168+
}
169+
}
170+
171+
//recurse through nested partials to fill out this extended template.
172+
processPatternRecursive(partialPath, patternlab);
173+
174+
//complete assembly of extended template
175+
var partialPattern = getpatternbykey(partialKey, patternlab);
176+
177+
//if partial has style modifier data, replace the styleModifier value
178+
if(currentPattern.stylePartials && currentPattern.stylePartials.length > 0){
179+
style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab);
180+
}
181+
182+
currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
183+
}
184+
}
185+
142186
function processPatternRecursive(file, patternlab, additionalData){
143187
var lh = require('./lineage_hunter'),
144-
ph = require('./parameter_hunter'),
145188
pph = require('./pseudopattern_hunter'),
146-
lih = require('./list_item_hunter'),
147-
smh = require('./style_modifier_hunter');
189+
lih = require('./list_item_hunter');
148190

149-
var parameter_hunter = new ph(),
150-
lineage_hunter = new lh(),
151-
list_item_hunter = new lih(),
152-
style_modifier_hunter = new smh(),
153-
pseudopattern_hunter = new pph();
191+
var lineage_hunter = new lh(),
192+
list_item_hunter = new lih(),
193+
pseudopattern_hunter = new pph();
154194

155195
//find current pattern in patternlab object using var file as a key
156-
var currentPattern,
157-
i;
196+
var currentPattern, i;
158197

159198
for(i = 0; i < patternlab.patterns.length; i++){
160199
if(patternlab.patterns[i].abspath === file){
@@ -163,60 +202,19 @@
163202
}
164203

165204
//return if processing an ignored file
166-
if(typeof currentPattern === 'undefined'){
167-
return;
168-
}
205+
if (typeof currentPattern === 'undefined') { return; }
169206

170207
currentPattern.extendedTemplate = currentPattern.template;
171208

172209
//find how many partials there may be for the given pattern
173210
var foundPatternPartials = currentPattern.findPartials(currentPattern);
174211

175-
if(foundPatternPartials !== null && foundPatternPartials.length > 0){
176-
177-
if(patternlab.config.debug){
178-
console.log('found partials for ' + currentPattern.key);
179-
}
180-
181-
//find any listItem blocks
182-
list_item_hunter.process_list_item_partials(currentPattern, patternlab);
183-
184-
//determine if the template contains any pattern parameters. if so they must be immediately consumed
185-
parameter_hunter.find_parameters(currentPattern, patternlab);
186-
187-
//do something with the regular old partials
188-
for(i = 0; i < foundPatternPartials.length; i++){
189-
var partialKey = currentPattern.getPartialKey(foundPatternPartials[i]);
190-
191-
var partialPath;
192-
193-
//identify which pattern this partial corresponds to
194-
for(var j = 0; j < patternlab.patterns.length; j++){
195-
if(patternlab.patterns[j].key === partialKey ||
196-
patternlab.patterns[j].abspath.indexOf(partialKey) > -1)
197-
{
198-
partialPath = patternlab.patterns[j].abspath;
199-
}
200-
}
212+
//find any listItem blocks that within the pattern, even if there are no partials
213+
list_item_hunter.process_list_item_partials(currentPattern, patternlab);
201214

202-
//recurse through nested partials to fill out this extended template.
203-
processPatternRecursive(partialPath, patternlab);
204-
205-
//complete assembly of extended template
206-
var partialPattern = getpatternbykey(partialKey, patternlab);
207-
208-
//if partial has style modifier data, replace the styleModifier value
209-
if(currentPattern.stylePartials && currentPattern.stylePartials.length > 0){
210-
style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab);
211-
}
212-
213-
currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
214-
215-
}
216-
217-
} else{
218-
//find any listItem blocks that within the pattern, even if there are no partials
219-
list_item_hunter.process_list_item_partials(currentPattern, patternlab);
215+
// expand any partials present in this pattern; that is, drill down into the template and replace their calls in this template with rendered results
216+
if (currentPattern.engine.expandPartials && (foundPatternPartials !== null && foundPatternPartials.length > 0)) {
217+
expandPartials(foundPatternPartials, list_item_hunter, patternlab, currentPattern);
220218
}
221219

222220
//find pattern lineage

builder/pattern_engines/engine_handlebars.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
engineName: 'handlebars',
1919
engineFileExtension: '.hbs',
2020

21+
// partial expansion is only necessary for Mustache templates that have
22+
// style modifiers or pattern parameters (I think)
23+
expandPartials: false,
24+
2125
// regexes, stored here so they're only compiled once
2226
// GTP warning: unchanged copypasta from mustache engine
2327
// findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g,

builder/pattern_engines/engine_mustache.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
engineName: 'mustache',
1919
engineFileExtension: '.mustache',
2020

21+
// partial expansion is only necessary for Mustache templates that have
22+
// style modifiers or pattern parameters (I think)
23+
expandPartials: true,
24+
2125
// regexes, stored here so they're only compiled once
2226
findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g,
2327
findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g,

test/engine_handlebars_tests.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,37 @@
135135
test.equals(helloWorldWithData.render(), 'Hello world!\nYeah, we got the subtitle from the JSON.\n');
136136
test.done();
137137
},
138+
'handlebars partials use the JSON environment from the calling pattern and can accept passed parameters': function (test) {
139+
test.expect(1);
140+
141+
// pattern paths
142+
var atomPath = path.resolve(
143+
testPatternsPath,
144+
'00-atoms',
145+
'00-global',
146+
'00-helloworld-withdata.hbs'
147+
);
148+
var molPath = path.resolve(
149+
testPatternsPath,
150+
'00-molecules',
151+
'00-global',
152+
'00-call-atom-with-molecule-data.hbs'
153+
);
154+
155+
// set up environment
156+
var patternlab = new fakePatternLab(); // environment
157+
var assembler = new pa();
158+
159+
// do all the normal processing of the pattern
160+
var atom = assembler.process_pattern_iterative(atomPath, patternlab);
161+
var mol = assembler.process_pattern_iterative(molPath, patternlab);
162+
assembler.process_pattern_recursive(atomPath, patternlab);
163+
assembler.process_pattern_recursive(molPath, patternlab);
164+
165+
// test
166+
test.equals(mol.render(), '<h2>Call with default JSON environment:</h2>\nThis is Hello world!\nfrom the default JSON.\n\n\n<h2>Call with passed parameter:</h2>\nHowever, this is Hello world!\nfrom a totally different blob.\n\n');
167+
test.done();
168+
},
138169
'find_pattern_partials finds partials': function(test){
139170
testFindPartials(test, [
140171
"{{> molecules-comment-header}}",

0 commit comments

Comments
 (0)