Skip to content

Commit 0dee50a

Browse files
committed
Create a Nunjucks loader to resolve Pattern Lab include paths
1 parent bbfc6a3 commit 0dee50a

File tree

1 file changed

+31
-68
lines changed

1 file changed

+31
-68
lines changed

packages/engine-nunjucks/lib/engine_nunjucks.js

Lines changed: 31 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,33 @@
2020

2121
'use strict';
2222

23-
let fs = require('fs-extra'),
24-
path = require('path'),
25-
plPath = process.cwd(),
26-
plConfig = require(path.join(plPath, 'patternlab-config.json')),
27-
nunjucks = require('nunjucks'),
28-
env = nunjucks.configure(plConfig.paths.source.patterns),
29-
partialRegistry = [];
30-
31-
////////////////////////////
32-
// LOAD ANY USER NUNJUCKS CONFIGURATIONS
33-
////////////////////////////
23+
const fs = require('fs-extra');
24+
const path = require('path');
25+
const plPath = process.cwd();
26+
const plConfig = require(path.join(plPath, 'patternlab-config.json'));
27+
const nunjucks = require('nunjucks');
28+
const partialRegistry = [];
29+
30+
// Create Pattern Loader
31+
// Since Pattern Lab includes are not path based we need a custom loader for Nunjucks.
32+
function PatternLoader() {}
33+
34+
PatternLoader.prototype.getSource = function(name) {
35+
const fullPath = path.resolve(
36+
plConfig.paths.source.patterns,
37+
partialRegistry[name]
38+
);
39+
return {
40+
src: fs.readFileSync(fullPath, 'utf-8'),
41+
path: fullPath,
42+
};
43+
};
44+
45+
const env = new nunjucks.Environment(new PatternLoader());
46+
47+
// Load any user Defined configurations
3448
try {
35-
let nunjucksConfig = require(path.join(
49+
const nunjucksConfig = require(path.join(
3650
plPath,
3751
'patternlab-nunjucks-config.js'
3852
));
@@ -41,27 +55,8 @@ try {
4155
}
4256
} catch (err) {}
4357

44-
////////////////////////////
45-
// HELPER FUNCTIONS
46-
// https://stackoverflow.com/questions/2116558/fastest-method-to-replace-all-instances-of-a-character-in-a-string
47-
// Might do some research on the solution.
48-
////////////////////////////
49-
if (!String.prototype.replaceAll) {
50-
String.prototype.replaceAll = function(str1, str2, ignore) {
51-
return this.replace(
52-
new RegExp(
53-
str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g, '\\$&'),
54-
ignore ? 'gi' : 'g'
55-
),
56-
typeof str2 === 'string' ? str2.replace(/\$/g, '$$$$') : str2
57-
);
58-
};
59-
}
60-
61-
////////////////////////////
62-
// NUNJUCKS ENGINE
63-
////////////////////////////
64-
let engine_nunjucks = {
58+
// Nunjucks Engine
59+
const engine_nunjucks = {
6560
engine: nunjucks,
6661
engineName: 'nunjucks',
6762
engineFileExtension: '.njk',
@@ -77,9 +72,7 @@ let engine_nunjucks = {
7772
// render it
7873
renderPattern: function renderPattern(pattern, data) {
7974
try {
80-
// replace pattern names with their full path so Nunjucks can find them.
81-
pattern.extendedTemplate = this.replacePartials(pattern);
82-
let result = nunjucks.renderString(pattern.extendedTemplate, data);
75+
const result = env.renderString(pattern.extendedTemplate, data);
8376
return Promise.resolve(result);
8477
} catch (err) {
8578
console.error('Failed to render pattern: ' + pattern.name);
@@ -88,7 +81,7 @@ let engine_nunjucks = {
8881

8982
// find and return any Nunjucks style includes/imports/extends within pattern
9083
findPartials: function findPartials(pattern) {
91-
let matches = pattern.template.match(this.findPartialsRE);
84+
const matches = pattern.template.match(this.findPartialsRE);
9285
return matches;
9386
},
9487

@@ -116,38 +109,9 @@ let engine_nunjucks = {
116109
}
117110
},
118111

119-
replacePartials: function(pattern) {
120-
try {
121-
let partials = this.findPartials(pattern);
122-
if (partials !== null) {
123-
for (let i = 0; i < partials.length; i++) {
124-
// e.g. {% include "atoms-parent" %}
125-
let partialName = this.findPartial(partials[i]); // e.g. atoms-parent
126-
let partialFullPath = partialRegistry[partialName]; // e.g. 00-atoms/01-parent.njk
127-
let newPartial = partials[i].replaceAll(
128-
partialName,
129-
partialFullPath,
130-
true
131-
); // e.g. {% include "00-atoms/01-parent.njk" %}
132-
pattern.extendedTemplate = pattern.extendedTemplate.replaceAll(
133-
partials[i],
134-
newPartial,
135-
true
136-
);
137-
}
138-
}
139-
return pattern.extendedTemplate;
140-
} catch (err) {
141-
console.error(
142-
'Error occurred in replacing partial names with paths for patern: ' +
143-
pattern.name
144-
);
145-
}
146-
},
147-
148112
// still requires the mustache syntax because of the way PL handles lists
149113
findListItems: function(pattern) {
150-
let matches = pattern.template.match(this.findListItemsRE);
114+
const matches = pattern.template.match(this.findListItemsRE);
151115
return matches;
152116
},
153117

@@ -168,7 +132,6 @@ let engine_nunjucks = {
168132
fs.statSync(metaFilePath);
169133
} catch (err) {
170134
//not a file, so spawn it from the included file
171-
const localMetaFilePath = path.resolve(__dirname, '_meta/', fileName);
172135
const metaFileContent = fs.readFileSync(
173136
path.resolve(__dirname, '..', '_meta/', fileName),
174137
'utf8'

0 commit comments

Comments
 (0)