Skip to content

fix(engine_twig_php): Twig incremental rebuilds #1036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions packages/cli/bin/inquiries/starterkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,28 +20,28 @@ const starterkitSetup = [
{
name: 'starterkit-twig-demo (Recommended)',
value: '@pattern-lab/starterkit-twig-demo',
},
},
{
name: 'starterkit-mustache-bootstrap',
value: 'starterkit-mustache-bootstrap',
},
},
{
name: 'starterkit-mustache-demo',
value: '@pattern-lab/starterkit-mustache-demo',
},
},
{
name: 'starterkit-mustache-foundation',
value: 'starterkit-mustache-foundation',
},
},
{
name: 'starterkit-mustache-materialdesign',
value: 'starterkit-mustache-materialdesign',
},
},
{
name: 'starterkit-mustache-base',
value: '@pattern-lab/starterkit-mustache-base',
},

new inquirer.Separator(),
{
name: 'Custom starterkit',
Expand Down
119 changes: 109 additions & 10 deletions packages/engine-twig-php/lib/engine_twig_php.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -57,6 +56,9 @@ const engine_twig_php = {
relativeFrom,
alterTwigEnv,
});

// Preserve the namespaces (after recursively adding nested folders) from the config so we can use them later to evaluate partials.
this.namespaces = twigRenderer.config.src.namespaces;
},

renderPattern(pattern, data) {
Expand All @@ -72,8 +74,6 @@ const engine_twig_php = {
const patternPath = path.isAbsolute(relPath)
? path.relative(patternLabConfig.paths.source.root, relPath)
: relPath;
// console.log(patternPath);

let details = '';
if (patternLabConfig.logLevel === 'debug') {
details = `<details><pre><code>${JSON.stringify(
Expand Down Expand Up @@ -126,8 +126,29 @@ 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);
const filteredMatches =
matches &&
matches.filter(match => {
// Filter out programmatically created includes.
// i.e. {% include '@namespace/icons/assets/' ~ name ~ '.svg' %}
return match.indexOf('~') === -1;
});
return filteredMatches;
},

findPartialsWithStyleModifiers(pattern) {
Expand All @@ -146,8 +167,86 @@ 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 patternPath = path.isAbsolute(selectedNamespace[0].paths[index])
? path.relative(
patternLabConfig.paths.source.root,
selectedNamespace[0].paths[index]
)
: selectedNamespace[0].paths[index];

// Replace the name space with the actual path.
// i.e. @atoms -> source/_patterns/00-atoms
const tempPartial = path.join(
process.cwd(),
partial.replace(`@${selectedNamespace[0].id}`, patternPath)
);

try {
// Check to see if the file actually exists.
if (fs.existsSync(tempPartial)) {
// get the path to the top-level folder of this pattern
// ex. /Users/bradfrost/sites/pattern-lab/packages/edition-twig/source/_patterns/00-atoms
const fullFolderPath = `${
tempPartial.split(selectedNamespace[0].id)[0]
}${selectedNamespace[0].id}`;

// then tease out the folder name itself (including the # prefix)
// ex. 00-atoms
const folderName = fullFolderPath.substring(
fullFolderPath.lastIndexOf('/') + 1,
fullFolderPath.length
);

// finally, return the Twig path we created from the full file path
// ex. 00-atoms/05-buttons/button.twig
const fullIncludePath = tempPartial.replace(
tempPartial.split(
`${folderName}${tempPartial.split(folderName)[1]}`
)[0],
''
);

namespaceResolvedPartial = fullIncludePath;

// 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) {
Expand Down