Skip to content
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

Recursive partial include #157

Merged
merged 10 commits into from
Oct 6, 2015
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
5 changes: 3 additions & 2 deletions builder/object_factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
(function () {
"use strict";

var oPattern = function(subdir, filename, data){
var oPattern = function(abspath, subdir, filename, data){
this.fileName = filename.substring(0, filename.indexOf('.'));
this.abspath = abspath;
this.subdir = subdir;
this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir
this.jsonFileData = data || {};
this.patternName = this.fileName.substring(this.fileName.indexOf('-') + 1); //this is the display name for the ui
this.patternName = this.fileName.replace(/^\d*\-/, ''); //this is the display name for the ui. strip numeric + hyphen prefixes
this.patternLink = this.name + '/' + this.name + '.html';
this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1);
this.patternSubGroup = subdir.substring(subdir.indexOf('/') + 4);
Expand Down
90 changes: 75 additions & 15 deletions builder/pattern_assembler.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,22 @@

function addPattern(pattern, patternlab){
patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink;
patternlab.patterns.push(pattern);

//only push to array if the array doesn't contain this pattern
var isNew = true;
for(var i = 0; i < patternlab.patterns.length; i++){
//so we need the identifier to be unique, which patterns[i].abspath is
if(pattern.abspath === patternlab.patterns[i].abspath){
//if abspath already exists, overwrite that element
patternlab.patterns[i] = pattern;
isNew = false;
break;
}
}
//if the pattern is new, just push to the array
if(isNew){
patternlab.patterns.push(pattern);
}
}

function renderPattern(template, data, partials) {
Expand All @@ -58,23 +73,38 @@
}
}

function processPatternFile(file, patternlab){
function processPatternIterative(file, patternlab){
var fs = require('fs-extra'),
of = require('./object_factory'),
path = require('path');

//extract some information
var abspath = file.substring(2);
var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/');
var filename = path.basename(file);
var ext = path.extname(filename);

//ignore _underscored patterns, json (for now), and dotfiles
if(filename.charAt(0) === '_' || path.extname(filename) === '.json' || filename.charAt(0) === '.'){
//ignore dotfiles and non-variant .json files
if(filename.charAt(0) === '.' || (ext === '.json' && filename.indexOf('~') === -1)){
return;
}

//make a new Pattern Object
var currentPattern = new of.oPattern(subdir, filename);
var currentPattern = new of.oPattern(file, subdir, filename);

//if file is named in the syntax for variants
if(ext === '.json' && filename.indexOf('~') > -1){
//add current pattern to patternlab object with minimal data
//processPatternRecursive() will run find_pseudopatterns() to fill out
//the object in the next diveSync
addPattern(currentPattern, patternlab);
//no need to process further
return;
}

//can ignore all non-mustache files at this point
if(ext !== '.mustache'){
return;
}

//see if this file has a state
setState(currentPattern, patternlab);
Expand All @@ -98,13 +128,13 @@
}

//add the raw template to memory
currentPattern.template = fs.readFileSync(abspath, 'utf8');
currentPattern.template = fs.readFileSync(file, 'utf8');

//our helper function that does a lot of heavy lifting
processPattern(currentPattern, patternlab);
//add currentPattern to patternlab.patterns array
addPattern(currentPattern, patternlab);
}

function processPattern(currentPattern, patternlab, additionalData){
function processPatternRecursive(file, patternlab, additionalData){

var fs = require('fs-extra'),
mustache = require('mustache'),
Expand All @@ -119,6 +149,21 @@
list_item_hunter = new lih(),
pseudopattern_hunter = new pph();

//find current pattern in patternlab object using var file as a key
var currentPattern,
i;

for(i = 0; i < patternlab.patterns.length; i++){
if(patternlab.patterns[i].abspath === file){
currentPattern = patternlab.patterns[i];
}
}

//return if processing an ignored file
if(typeof currentPattern === 'undefined'){
return;
}

currentPattern.extendedTemplate = currentPattern.template;

//find how many partials there may be for the given pattern
Expand All @@ -137,8 +182,23 @@
parameter_hunter.find_parameters(currentPattern, patternlab);

//do something with the regular old partials
for(var i = 0; i < foundPatternPartials.length; i++){
for(i = 0; i < foundPatternPartials.length; i++){
var partialKey = foundPatternPartials[i].replace(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g, '$2');
var partialPath;

//identify which pattern this partial corresponds to
for(var j = 0; j < patternlab.patterns.length; j++){
if(patternlab.patterns[j].key === partialKey ||
patternlab.patterns[j].abspath.indexOf(partialKey) > -1)
{
partialPath = patternlab.patterns[j].abspath;
}
}

//recurse through nested partials to fill out this extended template.
processPatternRecursive(partialPath, patternlab);

//complete assembly of extended template
var partialPattern = getpatternbykey(partialKey, patternlab);
currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
}
Expand Down Expand Up @@ -248,11 +308,11 @@
renderPattern: function(template, data, partials){
return renderPattern(template, data, partials);
},
process_pattern_file: function(file, patternlab){
processPatternFile(file, patternlab);
process_pattern_iterative: function(file, patternlab){
processPatternIterative(file, patternlab);
},
process_pattern: function(pattern, patternlab, additionalData){
processPattern(pattern, patternlab, additionalData);
process_pattern_recursive: function(file, patternlab, additionalData){
processPatternRecursive(file, patternlab, additionalData);
},
get_pattern_by_key: function(key, patternlab){
return getpatternbykey(key, patternlab);
Expand Down
40 changes: 38 additions & 2 deletions builder/patternlab.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ var patternlab_engine = function () {

pattern_assembler.combine_listItems(patternlab);

//diveSync once to perform iterative populating of patternlab object
diveSync(patterns_dir, {
filter: function(path, dir) {
if(dir){
Expand All @@ -87,7 +88,29 @@ var patternlab_engine = function () {
return;
}

pattern_assembler.process_pattern_file(file, patternlab);
pattern_assembler.process_pattern_iterative(file.substring(2), patternlab);
});

//diveSync again to recursively include partials, filling out the
//extendedTemplate property of the patternlab.patterns elements
diveSync(patterns_dir, {
filter: function(path, dir) {
if(dir){
var remainingPath = path.replace(patterns_dir, '');
var isValidPath = remainingPath.indexOf('/_') === -1;
return isValidPath;
}
return true;
}
},
function(err, file){
//log any errors
if(err){
console.log(err);
return;
}

pattern_assembler.process_pattern_recursive(file.substring(2), patternlab);
});

//delete the contents of config.patterns.public before writing
Expand Down Expand Up @@ -142,6 +165,11 @@ var patternlab_engine = function () {
i;

for (i = 0; i < patternlab.patterns.length; i++) {
// skip underscore-prefixed files
if (path.basename(patternlab.patterns[i].abspath).charAt(0) === '_') {
continue;
}

var pattern = patternlab.patterns[i];

// check if the current sub section is different from the previous one
Expand Down Expand Up @@ -170,6 +198,11 @@ var patternlab_engine = function () {
//loop through all patterns.to build the navigation
//todo: refactor this someday
for(var i = 0; i < patternlab.patterns.length; i++){
// skip underscore-prefixed files
if (path.basename(patternlab.patterns[i].abspath).charAt(0) === '_') {
continue;
}

var pattern = patternlab.patterns[i];
var bucketName = pattern.name.replace(/\\/g, '-').split('-')[1];

Expand Down Expand Up @@ -239,7 +272,10 @@ var patternlab_engine = function () {
var bucket = patternlab.buckets[bucketIndex];

//get the navItem
var navItemName = pattern.subdir.split('-').pop();
//if there is one or more slashes in the subdir, get everything after
//the last slash. if no slash, get the whole subdir string and strip
//any numeric + hyphen prefix
var navItemName = pattern.subdir.split('/').pop().replace(/^\d*\-/, '');

//get the navSubItem
var navSubItemName = pattern.patternName.replace(/-/g, ' ');
Expand Down
4 changes: 3 additions & 1 deletion builder/pseudopattern_hunter.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
variantFileData = pattern_assembler.merge_data(currentPattern.jsonFileData, variantFileData);

var variantName = pseudoPatterns[i].substring(pseudoPatterns[i].indexOf('~') + 1).split('.')[0];
var patternVariant = new of.oPattern(currentPattern.subdir, currentPattern.fileName + '-' + variantName + '.mustache', variantFileData);
var variantFilePath = 'source/_patterns/' + currentPattern.subdir + '/' + currentPattern.fileName + '~' + variantName + '.json';
var variantFileName = currentPattern.fileName + '-' + variantName + '.';
var patternVariant = new of.oPattern(variantFilePath, currentPattern.subdir, variantFileName, variantFileData);

//see if this file has a state
pattern_assembler.setPatternState(patternVariant, patternlab);
Expand Down
1 change: 1 addition & 0 deletions test/files/_patterns/00-test/00-foo.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{> test-bar }}
1 change: 1 addition & 0 deletions test/files/_patterns/00-test/01-bar.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bar
5 changes: 3 additions & 2 deletions test/object_factory_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

exports['oPattern initialization'] = {
'test oPattern initializes correctly' : function(test){
var p = new of.oPattern('00-atoms/00-global', '00-colors.mustache', { d: 123});
var p = new of.oPattern('source/_patterns/00-atoms/00-global/00-colors.mustache', '00-atoms/00-global', '00-colors.mustache', { d: 123});
test.equals(p.name, '00-atoms-00-global-00-colors');
test.equals(p.abspath, 'source/_patterns/00-atoms/00-global/00-colors.mustache');
test.equals(p.subdir, '00-atoms/00-global');
test.equals(p.fileName, '00-colors');
test.equals(p.jsonFileData.d, 123);
Expand Down Expand Up @@ -59,4 +60,4 @@
}
};

}());
}());
91 changes: 89 additions & 2 deletions test/pattern_assembler_tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,95 @@
test.equals(results[1], '{{> 01-molecules/06-components/02-single-comment(description: \'A life is like a garden. Perfect moments can be had, but not preserved, except in memory.\') }}');

test.done();
}
},

};
'process_pattern_recursive recursively includes partials' : function(test){

//tests inclusion of partial that will be discovered by diveSync later in iteration than parent
//prepare to diveSync
var diveSync = require('diveSync');
var fs = require('fs-extra');
var pa = require('../builder/pattern_assembler');
var pattern_assembler = new pa();
var patterns_dir = './test/files/_patterns';
var patternlab = {};
patternlab.config = fs.readJSONSync('./config.json');
patternlab.config.patterns = {source: patterns_dir};
patternlab.data = fs.readJSONSync('./source/_data/data.json');
patternlab.listitems = fs.readJSONSync('./source/_data/listitems.json');
patternlab.header = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/header.html', 'utf8');
patternlab.footer = fs.readFileSync('./source/_patternlab-files/pattern-header-footer/footer.html', 'utf8');
patternlab.patterns = [];
patternlab.data.link = {};
patternlab.partials = {};

//diveSync once to perform iterative populating of patternlab object
diveSync(patterns_dir,
{
filter: function(path, dir){
if(dir){
var remainingPath = path.replace(patterns_dir, '');
var isValidPath = remainingPath.indexOf('/_') === -1;
return isValidPath;
}
return true;
}
},
function(err, file){
//log any errors
if(err){
console.log(err);
return;
}

pattern_assembler.process_pattern_iterative(file.substring(2), patternlab);
}
);

//diveSync again to recursively include partials, filling out the
//extendedTemplate property of the patternlab.patterns elements
diveSync(patterns_dir,
{
filter: function(path, dir){
if(dir){
var remainingPath = path.replace(patterns_dir, '');
var isValidPath = remainingPath.indexOf('/_') === -1;
return isValidPath;
}
return true;
}
},
function(err, file){
//log any errors
if(err){
console.log(err);
return;
}

pattern_assembler.process_pattern_recursive(file.substring(2), patternlab);
}
);

//get test output for comparison
var foo = fs.readFileSync(patterns_dir + '/00-test/00-foo.mustache', 'utf8').trim();
var bar = fs.readFileSync(patterns_dir + '/00-test/01-bar.mustache', 'utf8').trim();
var fooExtended;

//get extended pattern
for(var i = 0; i < patternlab.patterns.length; i++){
if(patternlab.patterns[i].fileName === '00-foo'){
fooExtended = patternlab.patterns[i].extendedTemplate.trim();
break;
}
}

//check initial values
test.equals(foo, '{{> test-bar }}');
test.equals(bar, 'bar');
//test that 00-foo.mustache included partial 01-bar.mustache
test.equals(fooExtended, 'bar');

test.done();
}
};
}());