|
22 | 22 |
|
23 | 23 | const fs = require('fs-extra'); |
24 | 24 | const path = require('path'); |
25 | | -const process = require('process'); |
26 | | -const Twig = require('node-twig'); |
27 | | -const twig = Twig.renderFile; |
| 25 | +const { |
| 26 | + TwingEnvironment, |
| 27 | + TwingLoaderFilesystem, |
| 28 | + TwingLoaderChain, |
| 29 | + TwingSource, |
| 30 | +} = require('twing'); |
| 31 | + |
| 32 | +class TwingLoaderPatternLab { |
| 33 | + patterns = new Map(); |
| 34 | + |
| 35 | + constuctor() {} |
| 36 | + |
| 37 | + registerPartial(pattern) { |
| 38 | + if (pattern.patternPartial) { |
| 39 | + this.patterns.set(pattern.patternPartial, pattern); |
| 40 | + } |
| 41 | + } |
| 42 | + |
| 43 | + /** |
| 44 | + * Returns the source context for a given template logical name. |
| 45 | + * |
| 46 | + * @param {string} name The template logical name |
| 47 | + * @param {TwingSource} from The source that initiated the template loading |
| 48 | + * |
| 49 | + * @returns {Promise<TwingSource>} |
| 50 | + * |
| 51 | + * @throws TwingErrorLoader When name is not found |
| 52 | + */ |
| 53 | + getSourceContext(name, from) { |
| 54 | + var pattern = this.patterns.get(name); |
| 55 | + return Promise.resolve( |
| 56 | + new TwingSource(pattern.extendedTemplate, name, pattern.relPath) |
| 57 | + ); |
| 58 | + } |
| 59 | + |
| 60 | + /** |
| 61 | + * Gets the cache key to use for the cache for a given template name. |
| 62 | + * |
| 63 | + * @param {string} name The name of the template to load |
| 64 | + * @param {TwingSource} from The source that initiated the template loading |
| 65 | + * |
| 66 | + * @returns {Promise<string>} The cache key |
| 67 | + * |
| 68 | + * @throws TwingErrorLoader When name is not found |
| 69 | + */ |
| 70 | + getCacheKey(name, from) { |
| 71 | + return Promise.resolve(name); |
| 72 | + } |
| 73 | + |
| 74 | + /** |
| 75 | + * Returns true if the template is still fresh. |
| 76 | + *l |
| 77 | + * @param {string} name The template name |
| 78 | + * @param {number} time Timestamp of the last modification time of the cached template |
| 79 | + * @param {TwingSource} from The source that initiated the template loading |
| 80 | + * |
| 81 | + * @returns {Promise<boolean>} true if the template is fresh, false otherwise |
| 82 | + * |
| 83 | + * @throws TwingErrorLoader When name is not found |
| 84 | + */ |
| 85 | + isFresh(name, time, from) { |
| 86 | + return Promise.resolve(this.patterns.has(name) ? true : false); |
| 87 | + } |
| 88 | + |
| 89 | + /** |
| 90 | + * Check if we have the source code of a template, given its name. |
| 91 | + * |
| 92 | + * @param {string} name The name of the template to check if we can load |
| 93 | + * @param {TwingSource} from The source that initiated the template loading |
| 94 | + * |
| 95 | + * @returns {Promise<boolean>} If the template source code is handled by this loader or not |
| 96 | + */ |
| 97 | + exists(name, from) { |
| 98 | + return Promise.resolve(this.patterns.has(name) ? true : false); |
| 99 | + } |
| 100 | + |
| 101 | + /** |
| 102 | + * Resolve the path of a template, given its name, whatever it means in the context of the loader. |
| 103 | + * |
| 104 | + * @param {string} name The name of the template to resolve |
| 105 | + * @param {TwingSource} from The source that initiated the template loading |
| 106 | + * |
| 107 | + * @returns {Promise<string>} The resolved path of the template |
| 108 | + */ |
| 109 | + resolve(name, from) { |
| 110 | + pattern = this.patterns.get(name); |
| 111 | + return null; |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +const fileSystemLoader = new TwingLoaderFilesystem(); |
| 116 | +const patternLabLoader = new TwingLoaderPatternLab(); |
| 117 | +const chainLoader = new TwingLoaderChain([fileSystemLoader, patternLabLoader]); |
| 118 | +const twing = new TwingEnvironment(chainLoader); |
| 119 | +var metaPath; |
28 | 120 |
|
29 | 121 | var engine_twig = { |
30 | | - engine: Twig, |
| 122 | + engine: twing, |
31 | 123 | engineName: 'twig', |
32 | 124 | engineFileExtension: '.twig', |
33 | 125 |
|
34 | | - //Important! Needed for Twig compilation. Can't resolve paths otherwise. |
35 | | - expandPartials: true, |
36 | | - |
37 | 126 | // regexes, stored here so they're only compiled once |
38 | 127 | findPartialsRE: /{%\s*(?:extends|include|embed)\s+('[^']+'|"[^"]+").*?%}/g, |
39 | 128 | findPartialKeyRE: /"((?:\\.|[^"\\])*)"/, |
40 | 129 | findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g, // TODO |
41 | 130 |
|
42 | 131 | // render it |
43 | | - renderPattern: function renderPattern(pattern, data) { |
44 | | - return Promise.resolve( |
45 | | - twig( |
46 | | - pattern.relPath, |
47 | | - { |
48 | | - root: path.relative( |
49 | | - __dirname, |
50 | | - path.resolve(process.cwd(), 'source', '_patterns') |
51 | | - ), |
52 | | - context: data, |
53 | | - }, |
54 | | - (error, template) => { |
55 | | - if (error) { |
56 | | - console.log(error); |
57 | | - } |
58 | | - console.log(template); |
59 | | - return template; |
60 | | - } |
61 | | - ) |
| 132 | + renderPattern: function renderPattern(pattern, data, partials) { |
| 133 | + var patternPath = pattern.relPath; |
| 134 | + if (patternPath.lastIndexOf(metaPath) === 0) { |
| 135 | + patternPath = patternPath.substring(metaPath.length + 1); |
| 136 | + } |
| 137 | + return Promise.resolve(twing.render(patternPath, data)); |
| 138 | + }, |
| 139 | + |
| 140 | + registerPartial: function registerPartial(pattern) { |
| 141 | + console.log( |
| 142 | + `registerPartial(${pattern.name} - ${pattern.patternPartial} - ${pattern.patternPath} - ${pattern.relPath})` |
62 | 143 | ); |
| 144 | + patternLabLoader.registerPartial(pattern); |
63 | 145 | }, |
64 | 146 |
|
65 | 147 | // find and return any {% include 'template-name' %} within pattern |
@@ -88,7 +170,6 @@ var engine_twig = { |
88 | 170 | // given a pattern, and a partial string, tease out the "pattern key" and |
89 | 171 | // return it. |
90 | 172 | findPartial: function(partialString) { |
91 | | - //var partialKey = partialString.replace(this.findPartialsRE, '$1'); |
92 | 173 | var partial = partialString.match(this.findPartialKeyRE)[0]; |
93 | 174 | partial = partial.replace(/"/g, ''); |
94 | 175 |
|
@@ -121,6 +202,30 @@ var engine_twig = { |
121 | 202 | this.spawnFile(config, '_00-head.twig'); |
122 | 203 | this.spawnFile(config, '_01-foot.twig'); |
123 | 204 | }, |
| 205 | + |
| 206 | + /** |
| 207 | + * Accept a Pattern Lab config object from the core and use the settings to |
| 208 | + * load helpers. |
| 209 | + * |
| 210 | + * @param {object} config - the global config object from core |
| 211 | + */ |
| 212 | + usePatternLabConfig: function(config) { |
| 213 | + metaPath = path.resolve(config.paths.source.meta); |
| 214 | + // Global paths |
| 215 | + fileSystemLoader.addPath(config.paths.source.meta); |
| 216 | + fileSystemLoader.addPath(config.paths.source.patterns); |
| 217 | + // Namespaced paths |
| 218 | + if ( |
| 219 | + config['engines'] && |
| 220 | + config['engines']['twig'] && |
| 221 | + config['engines']['twig']['namespaces'] |
| 222 | + ) { |
| 223 | + var namespaces = config['engines']['twig']['namespaces']; |
| 224 | + Object.keys(namespaces).forEach(function(key, index) { |
| 225 | + fileSystemLoader.addPath(namespaces[key], key); |
| 226 | + }); |
| 227 | + } |
| 228 | + }, |
124 | 229 | }; |
125 | 230 |
|
126 | 231 | module.exports = engine_twig; |
0 commit comments