diff --git a/core/lib/object_factory.js b/core/lib/object_factory.js index c1aa23fe6..74b62f39e 100644 --- a/core/lib/object_factory.js +++ b/core/lib/object_factory.js @@ -9,8 +9,8 @@ var extend = require('util')._extend; var Pattern = function (relPath, data) { // We expect relPath to be the path of the pattern template, relative to the // root of the pattern tree. Parse out the path parts and save the useful ones. - var pathObj = path.parse(relPath); - this.relPath = relPath; // '00-atoms/00-global/00-colors.mustache' + var pathObj = path.parse(path.normalize(relPath)); + this.relPath = path.normalize(relPath); // '00-atoms/00-global/00-colors.mustache' this.fileName = pathObj.name; // '00-colors' this.subdir = pathObj.dir; // '00-atoms/00-global' this.fileExtension = pathObj.ext; // '.mustache' @@ -31,10 +31,10 @@ var Pattern = function (relPath, data) { // calculated path from the root of the public directory to the generated html // file for this pattern - this.patternLink = this.name + '/' + this.name + '.html'; // '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html' + this.patternLink = this.name + path.sep + this.name + '.html'; // '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html' // the top-level pattern group this pattern belongs to. 'atoms' - this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1); + this.patternGroup = this.subdir.split(path.sep)[0].replace(/^\d*-/, ''); // the sub-group this pattern belongs to. this.patternSubGroup = path.basename(this.subdir).replace(/^\d*-/, ''); // 'global' diff --git a/core/lib/parameter_hunter.js b/core/lib/parameter_hunter.js index 0ae1ebf2f..b2b9832e2 100644 --- a/core/lib/parameter_hunter.js +++ b/core/lib/parameter_hunter.js @@ -202,7 +202,7 @@ var parameter_hunter = function () { } //colon delimiter. - paramStringWellFormed += ':'; + values[i]; + paramStringWellFormed += ':'; //values //replace single-quote wrappers with double-quotes diff --git a/core/lib/patternlab.js b/core/lib/patternlab.js index d0518ab77..df1fa47ff 100644 --- a/core/lib/patternlab.js +++ b/core/lib/patternlab.js @@ -1,21 +1,34 @@ -/* - * patternlab-node - v2.2.1 - 2016 - * +/* + * patternlab-node - v2.2.1 - 2016 + * * Brian Muenzenmeyer, Geoff Pursell, and the web community. - * Licensed under the MIT license. - * - * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. + * Licensed under the MIT license. + * + * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. * */ "use strict"; var diveSync = require('diveSync'), + glob = require('glob'), + _ = require('lodash'), path = require('path'); // GTP: these two diveSync pattern processors factored out so they can be reused // from unit tests to reduce code dupe! +function buildPatternData(dataFilesPath, fs) { + var dataFilesPath = dataFilesPath; + var dataFiles = glob.sync(dataFilesPath + '*.json', {"ignore" : [dataFilesPath + 'listitems.json']}); + var mergeObject = {} + dataFiles.forEach(function (filePath) { + var jsonData = fs.readJSONSync(path.resolve(filePath), 'utf8') + mergeObject = _.merge(mergeObject, jsonData) + }) + return mergeObject; +} + function processAllPatternsIterative(pattern_assembler, patterns_dir, patternlab) { diveSync( patterns_dir, @@ -183,7 +196,7 @@ var patternlab_engine = function (config) { function buildPatterns(deletePatternDir) { try { - patternlab.data = fs.readJSONSync(path.resolve(paths.source.data, 'data.json')); + patternlab.data = buildPatternData(paths.source.data, fs); } catch (ex) { plutils.logRed('missing or malformed' + paths.source.data + 'data.json Pattern Lab may not work without this file.'); patternlab.data = {}; @@ -327,7 +340,7 @@ var patternlab_engine = function (config) { patternType: pattern.patternGroup, patternSubtype: pattern.patternSubGroup }, - patternExtension: pattern.fileExtension, + patternExtension: pattern.fileExtension.substr(1), //remove the dot because styleguide asset default adds it for us patternName: pattern.patternName, patternPartial: pattern.patternPartial, patternState: pattern.patternState, @@ -345,15 +358,23 @@ var patternlab_engine = function (config) { patternLabFoot : footerPartial }); + //default the output suffixes if not present + var outputFileSuffixes = { + rendered: '', + rawTemplate: '', + markupOnly: '.markup-only' + } + outputFileSuffixes = _.extend(outputFileSuffixes, patternlab.config.outputFileSuffixes); + //write the compiled template to the public patterns directory var patternPage = headHTML + pattern.patternPartialCode + footerHTML; - fs.outputFileSync(paths.public.patterns + pattern.patternLink, patternPage); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', outputFileSuffixes.rendered + '.html'), patternPage); //write the mustache file too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', pattern.fileExtension), pattern.template); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', outputFileSuffixes.rawTemplate + pattern.fileExtension), pattern.template); //write the encoded version too - fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', '.markup-only.html'), pattern.patternPartialCode); + fs.outputFileSync(paths.public.patterns + pattern.patternLink.replace('.html', outputFileSuffixes.markupOnly + '.html'), pattern.patternPartialCode); return true; }); @@ -392,6 +413,7 @@ var patternlab_engine = function (config) { // export these free functions so they're available without calling the exported // function, for use in reducing code dupe in unit tests. At least, until we // have a better way to do this +patternlab_engine.build_pattern_data = buildPatternData; patternlab_engine.process_all_patterns_iterative = processAllPatternsIterative; patternlab_engine.process_all_patterns_recursive = processAllPatternsRecursive; diff --git a/core/lib/ui_builder.js b/core/lib/ui_builder.js index 6e17fcd35..e8845bc6c 100644 --- a/core/lib/ui_builder.js +++ b/core/lib/ui_builder.js @@ -11,12 +11,11 @@ var eol = require('os').EOL; // PRIVATE FUNCTIONS -function addToPatternPaths(patternlab, patternTypeName, pattern) { - //this is messy, could use a refactor. - if (!patternlab.patternPaths[patternTypeName]) { - patternlab.patternPaths[patternTypeName] = {}; +function addToPatternPaths(patternlab, pattern) { + if (!patternlab.patternPaths[pattern.patternGroup]) { + patternlab.patternPaths[pattern.patternGroup] = {}; } - patternlab.patternPaths[patternTypeName][pattern.patternBaseName] = pattern.subdir.replace(/\\/g, '/') + "/" + pattern.fileName.replace('~', '-'); + patternlab.patternPaths[pattern.patternGroup][pattern.patternBaseName] = pattern.name; } //todo: refactor this as a method on the pattern object itself once we merge dev with pattern-engines branch @@ -91,9 +90,6 @@ function buildNavigation(patternlab) { var pattern = patternlab.patterns[i]; - //todo: check if this is already available - var patternTypeName = pattern.name.replace(/\\/g, '-').split('-')[1]; - //exclude any named defaultPattern from the navigation. //this is meant to be a homepage that is not navigable if (pattern.patternPartial === patternlab.config.defaultPattern) { @@ -102,7 +98,7 @@ function buildNavigation(patternlab) { } //add to patternPaths before continuing - addToPatternPaths(patternlab, patternTypeName, pattern); + addToPatternPaths(patternlab, pattern); continue; } @@ -134,17 +130,17 @@ function buildNavigation(patternlab) { patternSubTypeItem.patternPartial = pattern.patternPartial; //check if the patternType already exists - var patternTypeIndex = patternlab.patternTypeIndex.indexOf(patternTypeName); + var patternTypeIndex = patternlab.patternTypeIndex.indexOf(pattern.patternGroup); if (patternTypeIndex === -1) { //add the patternType - var patternType = new of.oPatternType(patternTypeName); + var patternType = new of.oPatternType(pattern.patternGroup); //add patternPath and viewAllPath - patternlab.patternPaths[patternTypeName] = patternlab.patternPaths[patternTypeName] || {}; - patternlab.viewAllPaths[patternTypeName] = {}; + patternlab.patternPaths[pattern.patternGroup] = patternlab.patternPaths[pattern.patternGroup] || {}; + patternlab.viewAllPaths[pattern.patternGroup] = {}; //test whether the pattern structure is flat or not - usually due to a template or page - flatPatternItem = patternSubTypeName === patternTypeName; + flatPatternItem = patternSubTypeName === pattern.patternGroup; //assume the patternSubType does not exist. patternSubType = new of.oPatternSubType(patternSubTypeName); @@ -160,7 +156,7 @@ function buildNavigation(patternlab) { patternType.patternItems.push(patternSubTypeItem); //add to patternPaths - addToPatternPaths(patternlab, patternTypeName, pattern); + addToPatternPaths(patternlab, pattern); } else { @@ -170,7 +166,7 @@ function buildNavigation(patternlab) { patternSubType.patternSubtypeItemsIndex.push(patternSubTypeItemName); //add to patternPaths - addToPatternPaths(patternlab, patternTypeName, pattern); + addToPatternPaths(patternlab, pattern); //add the view all PatternSubTypeItem viewAllPatternSubTypeItem = new of.oPatternSubTypeItem("View All"); @@ -178,13 +174,13 @@ function buildNavigation(patternlab) { viewAllPatternSubTypeItem.patternPartial = "viewall-" + pattern.patternGroup; patternType.patternItems.push(viewAllPatternSubTypeItem); - patternlab.viewAllPaths[patternTypeName].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length); + patternlab.viewAllPaths[pattern.patternGroup].viewall = pattern.subdir.slice(0, pattern.subdir.indexOf(pattern.patternGroup) + pattern.patternGroup.length); } //add the patternType. patternlab.patternTypes.push(patternType); - patternlab.patternTypeIndex.push(patternTypeName); + patternlab.patternTypeIndex.push(pattern.patternGroup); //done @@ -198,7 +194,7 @@ function buildNavigation(patternlab) { } //test whether the pattern structure is flat or not - usually due to a template or page - flatPatternItem = patternSubTypeName === patternTypeName; + flatPatternItem = patternSubTypeName === pattern.patternGroup; //if it is flat - we should not add the pattern to patternPaths if (flatPatternItem) { @@ -206,7 +202,7 @@ function buildNavigation(patternlab) { patternType.patternItems.push(patternSubTypeItem); //add to patternPaths - addToPatternPaths(patternlab, patternTypeName, pattern); + addToPatternPaths(patternlab, pattern); } else { @@ -242,11 +238,11 @@ function buildNavigation(patternlab) { } // just add to patternPaths - addToPatternPaths(patternlab, patternTypeName, pattern); + addToPatternPaths(patternlab, pattern); } } - patternlab.viewAllPaths[patternTypeName][pattern.patternSubGroup] = pattern.flatPatternPath; + patternlab.viewAllPaths[pattern.patternGroup][pattern.patternSubGroup] = pattern.flatPatternPath; } return patternTypeIndex; } diff --git a/test/files/_data/data.json b/test/files/_data/data.json new file mode 100644 index 000000000..d6d8ef572 --- /dev/null +++ b/test/files/_data/data.json @@ -0,0 +1,2 @@ +{ "data" : "test" } + diff --git a/test/files/_data/foo.json b/test/files/_data/foo.json new file mode 100644 index 000000000..d5da0e19c --- /dev/null +++ b/test/files/_data/foo.json @@ -0,0 +1 @@ +{ "foo" : "bar" } diff --git a/test/files/_data/listitems.json b/test/files/_data/listitems.json new file mode 100644 index 000000000..efcd8b4f1 --- /dev/null +++ b/test/files/_data/listitems.json @@ -0,0 +1,4 @@ +{ + "test_list_item" : "izzn thizzle" +} + diff --git a/test/lineage_hunter_tests.js b/test/lineage_hunter_tests.js index c1e978859..f689d049b 100644 --- a/test/lineage_hunter_tests.js +++ b/test/lineage_hunter_tests.js @@ -145,7 +145,6 @@ exports['lineage hunter '] = { ] }; - lineage_hunter.find_lineage(currentPattern, patternlab); lineage_hunter.find_lineage(currentPattern, patternlab); test.equals(currentPattern.lineageIndex.length, 1); diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 7fe3cea56..2ab591d6f 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -149,24 +149,24 @@ 'process_list_item_partials finds verbose partials and outputs repeated renders' : function(test){ var pattern1 = createFakeListPattern({ - "template": "{{#listItems.one}}{{> 00-atoms/00-test/00-foo.mustache }}{{/listItems.one}}", - "extendedTemplate" : "{{#listItems.one}}{{> 00-atoms/00-test/00-foo.mustache }}{{/listItems.one}}", + "template": "{{#listItems.one}}{{> 00-test/00-foo.mustache }}{{/listItems.one}}", + "extendedTemplate" : "{{#listItems.one}}{{> 00-test/00-foo.mustache }}{{/listItems.one}}", "key": "test-patternName1" }); var pattern2 = createFakeListPattern({ - "template": "{{#listItems.two}}{{> 00-atoms/00-test/00-bar.mustache }}{{/listItems.two}}", - "extendedTemplate" : "{{#listItems.two}}{{> 00-atoms/00-test/00-bar.mustache }}{{/listItems.two}}", + "template": "{{#listItems.two}}{{> 00-test/00-bar.mustache }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{> 00-test/00-bar.mustache }}{{/listItems.two}}", "key": "test-patternName2" }); var patternlab = createFakePatternLab({ "patterns": [ - Pattern.create('00-atoms/00-test/00-foo.mustache', null, { + Pattern.create('00-test/00-foo.mustache', null, { "template": "{{ title }}", "extendedTemplate": "{{ title }}" }), - Pattern.create('00-atoms/00-test/00-bar.mustache', null, { + Pattern.create('00-test/00-bar.mustache', null, { "template": "{{ title }}", "extendedTemplate": "{{ title }}" }) diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js index 685f74fbd..cec3172ae 100644 --- a/test/object_factory_tests.js +++ b/test/object_factory_tests.js @@ -3,19 +3,20 @@ var of = require('../core/lib/object_factory'); var Pattern = require('../core/lib/object_factory').Pattern; + var path = require('path'); exports['Pattern initialization'] = { 'test Pattern initializes correctly' : function (test) { var p = new Pattern('00-atoms/00-global/00-colors.mustache', { d: 123}); - test.equals(p.relPath, '00-atoms/00-global/00-colors.mustache'); + test.equals(p.relPath, '00-atoms' + path.sep + '00-global' + path.sep + '00-colors.mustache'); test.equals(p.name, '00-atoms-00-global-00-colors'); - test.equals(p.subdir, '00-atoms/00-global'); + test.equals(p.subdir, '00-atoms' + path.sep + '00-global'); test.equals(p.fileName, '00-colors'); test.equals(p.fileExtension, '.mustache'); test.equals(p.jsonFileData.d, 123); test.equals(p.patternBaseName, 'colors'); test.equals(p.patternName, 'Colors'); - test.equals(p.patternLink, '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html'); + test.equals(p.patternLink, '00-atoms-00-global-00-colors' + path.sep + '00-atoms-00-global-00-colors.html'); test.equals(p.patternGroup, 'atoms'); test.equals(p.patternSubGroup, 'global'); test.equals(p.flatPatternPath, '00-atoms-00-global'); @@ -31,7 +32,7 @@ }, 'test Pattern with one-directory subdir works as expected' : function (test) { var p = new Pattern('00-atoms/00-colors.mustache', { d: 123}); - test.equals(p.relPath, '00-atoms/00-colors.mustache'); + test.equals(p.relPath, '00-atoms' + path.sep + '00-colors.mustache'); test.equals(p.name, '00-atoms-00-colors'); test.equals(p.subdir, '00-atoms'); test.equals(p.fileName, '00-colors'); @@ -39,7 +40,7 @@ test.equals(p.jsonFileData.d, 123); test.equals(p.patternBaseName, 'colors'); test.equals(p.patternName, 'Colors'); - test.equals(p.patternLink, '00-atoms-00-colors/00-atoms-00-colors.html'); + test.equals(p.patternLink, '00-atoms-00-colors' + path.sep + '00-atoms-00-colors.html'); test.equals(p.patternGroup, 'atoms'); test.equals(p.flatPatternPath, '00-atoms'); test.equals(p.patternPartial, 'atoms-colors'); @@ -50,6 +51,18 @@ test.equals(p.lineageRIndex.length, 0); test.done(); }, + 'test Pattern with no numbers in pattern group works as expected' : function (test) { + var p = new Pattern('atoms/colors.mustache', { d: 123}); + test.equals(p.relPath, 'atoms' + path.sep + 'colors.mustache'); + test.equals(p.name, 'atoms-colors'); + test.equals(p.subdir, 'atoms'); + test.equals(p.fileName, 'colors'); + test.equals(p.patternLink, 'atoms-colors' + path.sep + 'atoms-colors.html'); + test.equals(p.patternGroup, 'atoms'); + test.equals(p.flatPatternPath, 'atoms'); + test.equals(p.patternPartial, 'atoms-colors'); + test.done(); + }, 'test Pattern capitalizes patternDisplayName correctly' : function(test){ var p = new Pattern('00-atoms/00-global/00-colors-alt.mustache', { d: 123}); test.equals(p.patternBaseName, 'colors-alt'); diff --git a/test/pattern_assembler_tests.js b/test/pattern_assembler_tests.js index 002ef35aa..b0fa5e4a0 100644 --- a/test/pattern_assembler_tests.js +++ b/test/pattern_assembler_tests.js @@ -94,7 +94,7 @@ //act - pattern_assembler.process_pattern_recursive('00-test/04-group.mustache', pl, {}); + pattern_assembler.process_pattern_recursive('00-test' + path.sep + '04-group.mustache', pl, {}); //assert var expectedValue = '