diff --git a/packages/engine-twig-php/lib/engine_twig_php.js b/packages/engine-twig-php/lib/engine_twig_php.js index 461a10dbd..86ed25e24 100644 --- a/packages/engine-twig-php/lib/engine_twig_php.js +++ b/packages/engine-twig-php/lib/engine_twig_php.js @@ -26,10 +26,9 @@ const engine_twig_php = { engineName: 'twig-php', engineFileExtension: '.twig', expandPartials: false, - - // @todo Evaluate RegExs - // findPartialsRE: /{%\s*(?:extends|include|embed)\s+('[^']+'|"[^"]+").*?%}/g, - // findPartialKeyRE: /"((?:\\.|[^"\\])*)"/, + findPartialsRE: /{%\s*(?:extends|include|embed)\s+('[^']+'|"[^"]+").*?(with|%}|\s*%})/g, + findPartialKeyRE: /"((?:\\.|[^"\\])*)"|'((?:\\.|[^"\\])*)'/, + namespaces: [], /** * Accept a Pattern Lab config object from the core and put it in @@ -47,6 +46,10 @@ const engine_twig_php = { const { namespaces, alterTwigEnv, relativeFrom } = config.engines.twig; + // Preserve the namespaces from the config so we can use them later to + // evaluate partials. + this.namespaces = namespaces; + // Schema on config object being passed in: // https://github.com/basaltinc/twig-renderer/blob/master/config.schema.json twigRenderer = new TwigRenderer({ @@ -64,7 +67,6 @@ const engine_twig_php = { const patternPath = path.isAbsolute(pattern.relPath) ? path.relative(patternLabConfig.paths.source.root, pattern.relPath) : pattern.relPath; - // console.log(patternPath); let details = ''; if (patternLabConfig.logLevel === 'debug') { @@ -118,8 +120,22 @@ const engine_twig_php = { // @todo Add all functions that get called even if disabled to ease implementing engine further // Currently all of them return `null` as I'm not totally sure there absence will be ok. Additionally, future improvements may be implemented in this functions. - findPartials(pattern) { - return null; + // Find and return any {% extends|include|embed 'template-name' %} within pattern. + // The regex should match the following examples: + // {% + // include '@molecules/teaser-card/teaser-card.twig' with { + // teaser_card: card + // } only + // %} + // OR + // {% include '@molecules/teaser-card/teaser-card.twig' %} + // OR + // {% + // include '@molecules/teaser-card/teaser-card.twig' + // %} + findPartials: function(pattern) { + const matches = pattern.template.match(this.findPartialsRE); + return matches; }, findPartialsWithStyleModifiers(pattern) { @@ -138,8 +154,65 @@ const engine_twig_php = { return null; }, - findPartial(partialString) { - return null; + // Given a pattern, and a partial string, tease out the "pattern key" and + // return it. + findPartial: function(partialString) { + try { + let partial = partialString.match(this.findPartialKeyRE)[0]; + partial = partial.replace(/"/g, ''); + partial = partial.replace(/'/g, ''); + + // Check if namespaces is not empty. + const selectedNamespace = this.namespaces.filter(namespace => { + // Check to see if this partial contains within the namespace id. + return partial.indexOf(`@${namespace.id}`) !== -1; + }); + + let namespaceResolvedPartial = ''; + + if (selectedNamespace.length > 0) { + // Loop through all namespaces and try to resolve the namespace to a file path. + for ( + let index = 0; + index < selectedNamespace[0].paths.length; + index++ + ) { + const path = selectedNamespace[0].paths[index]; + // Replace the name space with the actual path. + // i.e. @atoms -> source/_patterns/00-atoms + const tempPartial = partial.replace( + `@${selectedNamespace[0].id}`, + path + ); + + try { + // Check to see if the file exists. + if (fs.existsSync(tempPartial)) { + // If it does, find the last directory in the namespace path. + // i.e. source/_patterns/00-atoms -> 00-atoms. + const lastDirectory = path.split('/').reverse()[0]; + // Replace the namespace in the path with the directory name. + // i.e. @atoms/04-images/04-avatar.twig -> 00-atoms/04-images/04-avatar.twig + namespaceResolvedPartial = partial.replace( + `@${selectedNamespace[0].id}`, + lastDirectory + ); + // After it matches one time, set the resolved partial and exit the loop. + break; + } + } catch (err) { + console.error(err); + } + } + } + // Return the path with the namespace resolved OR the regex'd partial. + return namespaceResolvedPartial || partial; + } catch (err) { + console.error( + 'Error occured when trying to find partial name in: ' + partialString + ); + return null; + } }, patternMatcher(pattern, regex) {