Skip to content

Commit 8a4d4c6

Browse files
author
Brian Muenzenmeyer
committed
Merge pull request #161 from pattern-lab/dev
Dev push for v0.13.0
2 parents 12a40e1 + e6fc96a commit 8a4d4c6

26 files changed

+478
-85
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ public/fonts/*
88
public/js/*
99
public/images/*
1010
public/patterns/*
11-
config.ini
1211
latest-change.txt
1312
patternlab.json
1413
.sass-cache/*

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
language: node_js
22

33
node_js:
4+
- 4.1
5+
- 4.0
6+
- 0.12
47
- 0.11
5-
- 0.10
68

79
before_install:
810
- phantomjs --version

CHANGELOG

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT.
22

3+
PL-node-v0.13.0
4+
- FIX: Cleanup an old file and an incorrect entry in the .gitignore file
5+
- CHG: Change order of pattern addition and ~variant pattern addition so they build naturally in the menu.
6+
- THX: Thanks @e2tha-e for the flurry of pull requests!
7+
- CHG: Update data merge function to prioritize handle pattern~variant.json files
8+
- THX: Thanks @e2tha-e for finding, fixing, and unit testing the data merge issue.
9+
- ADD: Support for recursive partial inclusion
10+
- THX: Thanks @e2tha-e for making pattern inclusion a lot more robust. Great work!!!
11+
- FIX: Improvements to style guide menu generation and capitalization.
12+
313
PL-node-v0.12.0
414
- ADD: Gulp support arrives with an optional configuration
515
- ADD: Instructions how to install and run with Gulp

Gruntfile.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ module.exports = function(grunt) {
2828
src: './builder/patternlab_grunt.js',
2929
dest: './builder/patternlab_grunt.js'
3030
},
31+
patternlab_gulp: {
32+
src: './builder/patternlab_gulp.js',
33+
dest: './builder/patternlab_gulp.js'
34+
},
3135
parameter_hunter: {
3236
src: './builder/parameter_hunter.js',
3337
dest: './builder/parameter_hunter.js'

builder/lineage_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/list_item_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/media_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/object_factory.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.
@@ -11,12 +11,16 @@
1111
(function () {
1212
"use strict";
1313

14-
var oPattern = function(subdir, filename, data){
14+
var oPattern = function(abspath, subdir, filename, data){
1515
this.fileName = filename.substring(0, filename.indexOf('.'));
16+
this.abspath = abspath;
1617
this.subdir = subdir;
1718
this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir
1819
this.jsonFileData = data || {};
19-
this.patternName = this.fileName.substring(this.fileName.indexOf('-') + 1); //this is the display name for the ui
20+
this.patternName = this.fileName.replace(/^\d*\-/, '');
21+
this.patternDisplayName = this.patternName.split('-').reduce(function(val, working){
22+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
23+
}, '').trim(); //this is the display name for the ui. strip numeric + hyphen prefixes
2024
this.patternLink = this.name + '/' + this.name + '.html';
2125
this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1);
2226
this.patternSubGroup = subdir.substring(subdir.indexOf('/') + 4);
@@ -32,7 +36,9 @@
3236

3337
var oBucket = function(name){
3438
this.bucketNameLC = name;
35-
this.bucketNameUC = name.charAt(0).toUpperCase() + name.slice(1);
39+
this.bucketNameUC = name.split('-').reduce(function(val, working){
40+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
41+
}, '').trim();
3642
this.navItems = [];
3743
this.navItemsIndex = [];
3844
this.patternItems = [];
@@ -41,15 +47,19 @@
4147

4248
var oNavItem = function(name){
4349
this.sectionNameLC = name;
44-
this.sectionNameUC = name.charAt(0).toUpperCase() + name.slice(1);
50+
this.sectionNameUC = name.split('-').reduce(function(val, working){
51+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
52+
}, '').trim();
4553
this.navSubItems = [];
4654
this.navSubItemsIndex = [];
4755
};
4856

4957
var oNavSubItem = function(name){
5058
this.patternPath = '';
5159
this.patternPartial = '';
52-
this.patternName = name.charAt(0).toUpperCase() + name.slice(1);
60+
this.patternName = name.split(' ').reduce(function(val, working){
61+
return val.charAt(0).toUpperCase() + val.slice(1) + ' ' + working.charAt(0).toUpperCase() + working.slice(1);
62+
}, '').trim();
5363
};
5464

5565
module.exports = {

builder/parameter_hunter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.

builder/pattern_assembler.js

Lines changed: 113 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* patternlab-node - v0.12.0 - 2015
2+
* patternlab-node - v0.13.0 - 2015
33
*
44
* Brian Muenzenmeyer, and the web community.
55
* Licensed under the MIT license.
@@ -44,7 +44,22 @@
4444

4545
function addPattern(pattern, patternlab){
4646
patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink;
47-
patternlab.patterns.push(pattern);
47+
48+
//only push to array if the array doesn't contain this pattern
49+
var isNew = true;
50+
for(var i = 0; i < patternlab.patterns.length; i++){
51+
//so we need the identifier to be unique, which patterns[i].abspath is
52+
if(pattern.abspath === patternlab.patterns[i].abspath){
53+
//if abspath already exists, overwrite that element
54+
patternlab.patterns[i] = pattern;
55+
isNew = false;
56+
break;
57+
}
58+
}
59+
//if the pattern is new, just push to the array
60+
if(isNew){
61+
patternlab.patterns.push(pattern);
62+
}
4863
}
4964

5065
function renderPattern(template, data, partials) {
@@ -58,23 +73,38 @@
5873
}
5974
}
6075

61-
function processPatternFile(file, patternlab){
76+
function processPatternIterative(file, patternlab){
6277
var fs = require('fs-extra'),
6378
of = require('./object_factory'),
6479
path = require('path');
6580

6681
//extract some information
67-
var abspath = file.substring(2);
6882
var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/');
6983
var filename = path.basename(file);
84+
var ext = path.extname(filename);
7085

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

7691
//make a new Pattern Object
77-
var currentPattern = new of.oPattern(subdir, filename);
92+
var currentPattern = new of.oPattern(file, subdir, filename);
93+
94+
//if file is named in the syntax for variants
95+
if(ext === '.json' && filename.indexOf('~') > -1){
96+
//add current pattern to patternlab object with minimal data
97+
//processPatternRecursive() will run find_pseudopatterns() to fill out
98+
//the object in the next diveSync
99+
addPattern(currentPattern, patternlab);
100+
//no need to process further
101+
return;
102+
}
103+
104+
//can ignore all non-mustache files at this point
105+
if(ext !== '.mustache'){
106+
return;
107+
}
78108

79109
//see if this file has a state
80110
setState(currentPattern, patternlab);
@@ -83,7 +113,9 @@
83113
try {
84114
var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json";
85115
currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2));
86-
console.log('found pattern-specific data.json for ' + currentPattern.key);
116+
if(patternlab.config.debug){
117+
console.log('found pattern-specific data.json for ' + currentPattern.key);
118+
}
87119
}
88120
catch(e) {
89121
}
@@ -92,19 +124,21 @@
92124
try {
93125
var listJsonFileName = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".listitems.json";
94126
currentPattern.patternSpecificListJson = fs.readJSONSync(listJsonFileName.substring(2));
95-
console.log('found pattern-specific listitems.json for ' + currentPattern.key);
127+
if(patternlab.config.debug){
128+
console.log('found pattern-specific listitems.json for ' + currentPattern.key);
129+
}
96130
}
97131
catch(e) {
98-
}
132+
}
99133

100134
//add the raw template to memory
101-
currentPattern.template = fs.readFileSync(abspath, 'utf8');
135+
currentPattern.template = fs.readFileSync(file, 'utf8');
102136

103-
//our helper function that does a lot of heavy lifting
104-
processPattern(currentPattern, patternlab);
137+
//add currentPattern to patternlab.patterns array
138+
addPattern(currentPattern, patternlab);
105139
}
106140

107-
function processPattern(currentPattern, patternlab, additionalData){
141+
function processPatternRecursive(file, patternlab, additionalData){
108142

109143
var fs = require('fs-extra'),
110144
mustache = require('mustache'),
@@ -119,6 +153,21 @@
119153
list_item_hunter = new lih(),
120154
pseudopattern_hunter = new pph();
121155

156+
//find current pattern in patternlab object using var file as a key
157+
var currentPattern,
158+
i;
159+
160+
for(i = 0; i < patternlab.patterns.length; i++){
161+
if(patternlab.patterns[i].abspath === file){
162+
currentPattern = patternlab.patterns[i];
163+
}
164+
}
165+
166+
//return if processing an ignored file
167+
if(typeof currentPattern === 'undefined'){
168+
return;
169+
}
170+
122171
currentPattern.extendedTemplate = currentPattern.template;
123172

124173
//find how many partials there may be for the given pattern
@@ -137,8 +186,23 @@
137186
parameter_hunter.find_parameters(currentPattern, patternlab);
138187

139188
//do something with the regular old partials
140-
for(var i = 0; i < foundPatternPartials.length; i++){
189+
for(i = 0; i < foundPatternPartials.length; i++){
141190
var partialKey = foundPatternPartials[i].replace(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g, '$2');
191+
var partialPath;
192+
193+
//identify which pattern this partial corresponds to
194+
for(var j = 0; j < patternlab.patterns.length; j++){
195+
if(patternlab.patterns[j].key === partialKey ||
196+
patternlab.patterns[j].abspath.indexOf(partialKey) > -1)
197+
{
198+
partialPath = patternlab.patterns[j].abspath;
199+
}
200+
}
201+
202+
//recurse through nested partials to fill out this extended template.
203+
processPatternRecursive(partialPath, patternlab);
204+
205+
//complete assembly of extended template
142206
var partialPattern = getpatternbykey(partialKey, patternlab);
143207
currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
144208
}
@@ -148,11 +212,11 @@
148212
//find pattern lineage
149213
lineage_hunter.find_lineage(currentPattern, patternlab);
150214

151-
//look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json
152-
pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab);
153-
154215
//add to patternlab object so we can look these up later.
155216
addPattern(currentPattern, patternlab);
217+
218+
//look for a pseudo pattern by checking if there is a file containing same name, with ~ in it, ending in .json
219+
pseudopattern_hunter.find_pseudopatterns(currentPattern, patternlab);
156220
}
157221

158222
function getpatternbykey(key, patternlab){
@@ -167,24 +231,39 @@
167231
throw 'Could not find pattern with key ' + key;
168232
}
169233

170-
171-
var self = this;
172-
function mergeData(obj1, obj2) {
173-
for (var p in obj2) {
234+
/**
235+
* Recursively merge properties of two objects.
236+
*
237+
* @param {Object} obj1 If obj1 has properties obj2 doesn't, add to obj2.
238+
* @param {Object} obj2 This object's properties have priority over obj1.
239+
* @returns {Object} obj2
240+
*/
241+
function mergeData(obj1, obj2){
242+
if(typeof obj2 === 'undefined'){
243+
obj2 = {};
244+
}
245+
for(var p in obj1){
174246
try {
175-
// Property in destination object set; update its value.
176-
if ( obj2[p].constructor == Object ) {
177-
obj1[p] = self.merge_data(obj1[p], obj2[p]);
178-
179-
} else {
180-
obj1[p] = obj2[p];
247+
// Only recurse if obj1[p] is an object.
248+
if(obj1[p].constructor === Object){
249+
// Requires 2 objects as params; create obj2[p] if undefined.
250+
if(typeof obj2[p] === 'undefined'){
251+
obj2[p] = {};
252+
}
253+
obj2[p] = mergeData(obj1[p], obj2[p]);
254+
// Pop when recursion meets a non-object. If obj1[p] is a non-object,
255+
// only copy to undefined obj2[p]. This way, obj2 maintains priority.
256+
} else if(typeof obj2[p] === 'undefined'){
257+
obj2[p] = obj1[p];
181258
}
182259
} catch(e) {
183260
// Property in destination object not set; create it and set its value.
184-
obj1[p] = obj2[p];
261+
if(typeof obj2[p] === 'undefined'){
262+
obj2[p] = obj1[p];
263+
}
185264
}
186265
}
187-
return obj1;
266+
return obj2;
188267
}
189268

190269
function buildListItems(patternlab){
@@ -233,11 +312,11 @@
233312
renderPattern: function(template, data, partials){
234313
return renderPattern(template, data, partials);
235314
},
236-
process_pattern_file: function(file, patternlab){
237-
processPatternFile(file, patternlab);
315+
process_pattern_iterative: function(file, patternlab){
316+
processPatternIterative(file, patternlab);
238317
},
239-
process_pattern: function(pattern, patternlab, additionalData){
240-
processPattern(pattern, patternlab, additionalData);
318+
process_pattern_recursive: function(file, patternlab, additionalData){
319+
processPatternRecursive(file, patternlab, additionalData);
241320
},
242321
get_pattern_by_key: function(key, patternlab){
243322
return getpatternbykey(key, patternlab);

0 commit comments

Comments
 (0)