Skip to content

Commit 4b037ec

Browse files
committed
StyleModifier support. Unit test coverage. Tested basic, listitem, and pattern param support with style modifiers. added to readme. Closes #95
1 parent c15d488 commit 4b037ec

9 files changed

+199
-132
lines changed

Gruntfile.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ module.exports = function(grunt) {
5151
list_item_hunter: {
5252
src: './builder/list_item_hunter.js',
5353
dest: './builder/list_item_hunter.js'
54+
},
55+
style_modifier_hunter: {
56+
src: './builder/style_modifier_hunter.js',
57+
dest: './builder/style_modifier_hunter.js'
5458
}
5559
},
5660
copy: {

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,32 @@ Pattern parameters **do not** currently support the following:
179179

180180
You can read the full documentation on pattern parameters here: [Using Pattern Parameters](http://patternlab.io/docs/pattern-parameters.html)
181181

182+
##### Pattern Style Modifiers
183+
Style Modifiers allow you to create a base pattern that you can easily modify by adding a class name to the pattern partial. Read more about them [here](http://patternlab.io/docs/pattern-stylemodifier.html), including support with pattern parameters. Below is the gist.
184+
185+
The basic syntax is this:
186+
187+
```
188+
{{> atoms-message:error }}
189+
```
190+
191+
This works by using a reserved mustache variable of sorts called {{ styleModifier }} applied to the atoms-message mustache file itself:
192+
193+
```
194+
<div class="message {{ styleModifier }}">{{ message }}</div>
195+
```
196+
197+
Once rendered, it looks like this:
198+
199+
```
200+
<div>
201+
<div class="message error"></div>
202+
</div>
203+
```
204+
205+
206+
207+
182208
##### Pseudo-Patterns
183209
Pseudo-patterns are meant to give developers the ability to build multiple and unique **rendered** patterns off of one base pattern and its mark-up while giving them control over the data that is injected into the base pattern. This feature is especially useful when developing template- and page-style patterns.
184210

builder/list_item_hunter.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
/*
2-
* patternlab-node - v0.14.0 - 2015
3-
*
1+
/*
2+
* patternlab-node - v0.14.0 - 2015
3+
*
44
* Brian Muenzenmeyer, and the web community.
5-
* Licensed under the MIT license.
6-
*
7-
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
5+
* Licensed under the MIT license.
6+
*
7+
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
88
*
99
*/
1010

@@ -15,8 +15,10 @@
1515

1616
var extend = require('util')._extend,
1717
pa = require('./pattern_assembler'),
18+
smh = require('./style_modifier_hunter'),
1819
mustache = require('mustache'),
1920
pattern_assembler = new pa(),
21+
style_modifier_hunter = new smh(),
2022
items = [ 'zero','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen','twenty'];
2123

2224
function processListItemPartials(pattern, patternlab){
@@ -71,6 +73,11 @@
7173
var partialName = foundPartials[j].match(/([\w\-\.\/~]+)/g)[0];
7274
var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab);
7375

76+
//if partial has style modifier data, replace the styleModifier value
77+
if(pattern.stylePartials && pattern.stylePartials.length > 0){
78+
style_modifier_hunter.consume_style_modifier(partialPattern, foundPartials[j], patternlab);
79+
}
80+
7481
//replace its reference within the block with the extended template
7582
thisBlockTemplate = thisBlockTemplate.replace(foundPartials[j], partialPattern.extendedTemplate);
7683
}
@@ -87,7 +94,7 @@
8794
repeatedBlockHtml = repeatedBlockHtml + thisBlockHTML;
8895
}
8996

90-
//replace the block with our generated HTML
97+
//replace the block with our generated HTML
9198
var repeatingBlock = pattern.extendedTemplate.substring(pattern.extendedTemplate.indexOf(liMatch), pattern.extendedTemplate.indexOf(end) + end.length);
9299
pattern.extendedTemplate = pattern.extendedTemplate.replace(repeatingBlock, repeatedBlockHtml);
93100

builder/parameter_hunter.js

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
/*
2-
* patternlab-node - v0.14.0 - 2015
3-
*
1+
/*
2+
* patternlab-node - v0.14.0 - 2015
3+
*
44
* Brian Muenzenmeyer, and the web community.
5-
* Licensed under the MIT license.
6-
*
7-
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
5+
* Licensed under the MIT license.
6+
*
7+
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
88
*
99
*/
1010

@@ -16,17 +16,18 @@
1616
var extend = require('util')._extend,
1717
pa = require('./pattern_assembler'),
1818
mustache = require('mustache'),
19+
smh = require('./style_modifier_hunter'),
20+
style_modifier_hunter = new smh(),
1921
pattern_assembler = new pa();
2022

2123
function findparameters(pattern, patternlab){
2224

23-
//find the {{> template-name(*) }} within patterns
24-
var matches = pattern.template.match(/{{>([ ]+)?([\w\-\.\/~]+)(\()(.+)(\))([ ]+)?}}/g);
25-
if(matches !== null){
25+
if(pattern.parameteredPartials && pattern.parameteredPartials.length > 0){
2626
//compile this partial immeadiately, essentially consuming it.
27-
matches.forEach(function(pMatch, index, matches){
28-
//find the partial's name
27+
pattern.parameteredPartials.forEach(function(pMatch, index, matches){
28+
//find the partial's name and retrieve it
2929
var partialName = pMatch.match(/([\w\-\.\/~]+)/g)[0];
30+
var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab);
3031

3132
if(patternlab.config.debug){
3233
console.log('found patternParameters for ' + partialName);
@@ -40,13 +41,17 @@
4041
//do no evil. there is no good way to do this that I can think of without using a split, which then makes commas and colons special characters and unusable within the pattern params
4142
var paramData = eval(paramString);
4243

43-
var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab);
4444
var globalData = JSON.parse(JSON.stringify(patternlab.data));
45-
var localData = JSON.parse(JSON.stringify(pattern.jsonFileData));
45+
var localData = JSON.parse(JSON.stringify(pattern.jsonFileData || {}));
4646

4747
var allData = pattern_assembler.merge_data(globalData, localData);
4848
allData = pattern_assembler.merge_data(allData, paramData);
4949

50+
//if partial has style modifier data, replace the styleModifier value
51+
if(pattern.stylePartials && pattern.stylePartials.length > 0){
52+
style_modifier_hunter.consume_style_modifier(partialPattern, pMatch, patternlab);
53+
}
54+
5055
//extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally
5156
allData.link = extend({}, patternlab.data.link);
5257

builder/pattern_assembler.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
/*
2-
* patternlab-node - v0.14.0 - 2015
3-
*
1+
/*
2+
* patternlab-node - v0.14.0 - 2015
3+
*
44
* Brian Muenzenmeyer, and the web community.
5-
* Licensed under the MIT license.
6-
*
7-
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
5+
* Licensed under the MIT license.
6+
*
7+
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
88
*
99
*/
1010

@@ -24,19 +24,19 @@
2424

2525
// returns any patterns that match {{> value:mod }} or {{> value:mod(foo:"bar") }} within the pattern
2626
function findPartialsWithStyleModifiers(pattern){
27-
var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-]+)+(?:(| )\(.*)?([ ])?}}/g);
27+
var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_]+)+(?:(| )\(.*)?([ ])?}}/g);
2828
return matches;
2929
}
3030

3131
// returns any patterns that match {{> value(foo:"bar") }} or {{> value:mod(foo:"bar") }} within the pattern
3232
function findPartialsWithPatternParameters(pattern){
33-
var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)+([ ])?}}/g);
33+
var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)+([ ])?}}/g);
3434
return matches;
3535
}
3636

37-
//find and return any {{> template-name }} within pattern
37+
//find and return any {{> template-name* }} within pattern
3838
function findPartials(pattern){
39-
var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g);
39+
var matches = pattern.template.match(/{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_]+)?(?:(| )\(.*)?([ ])?}}/g);
4040
return matches;
4141
}
4242

@@ -145,6 +145,12 @@
145145
//add the raw template to memory
146146
currentPattern.template = fs.readFileSync(file, 'utf8');
147147

148+
//find any stylemodifiers that may be in the current pattern
149+
currentPattern.stylePartials = findPartialsWithStyleModifiers(currentPattern);
150+
151+
//find any pattern parameters that may be in the current pattern
152+
currentPattern.parameteredPartials = findPartialsWithPatternParameters(currentPattern);
153+
148154
//add currentPattern to patternlab.patterns array
149155
addPattern(currentPattern, patternlab);
150156
}
@@ -157,11 +163,13 @@
157163
ph = require('./parameter_hunter'),
158164
pph = require('./pseudopattern_hunter'),
159165
lih = require('./list_item_hunter'),
166+
smh = require('./style_modifier_hunter'),
160167
path = require('path');
161168

162169
var parameter_hunter = new ph(),
163170
lineage_hunter = new lh(),
164171
list_item_hunter = new lih(),
172+
style_modifier_hunter = new smh(),
165173
pseudopattern_hunter = new pph();
166174

167175
//find current pattern in patternlab object using var file as a key
@@ -198,7 +206,8 @@
198206

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

204213
//identify which pattern this partial corresponds to
@@ -215,7 +224,14 @@
215224

216225
//complete assembly of extended template
217226
var partialPattern = getpatternbykey(partialKey, patternlab);
227+
228+
//if partial has style modifier data, replace the styleModifier value
229+
if(currentPattern.stylePartials && currentPattern.stylePartials.length > 0){
230+
style_modifier_hunter.consume_style_modifier(partialPattern, foundPatternPartials[i], patternlab);
231+
}
232+
218233
currentPattern.extendedTemplate = currentPattern.extendedTemplate.replace(foundPatternPartials[i], partialPattern.extendedTemplate);
234+
219235
}
220236

221237
}

builder/style_modifier_hunter.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* patternlab-node - v0.14.0 - 2015
3+
*
4+
* Brian Muenzenmeyer, and the web community.
5+
* Licensed under the MIT license.
6+
*
7+
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
8+
*
9+
*/
10+
11+
(function () {
12+
"use strict";
13+
14+
var style_modifier_hunter = function(){
15+
16+
function consumestylemodifier(pattern, partial, patternlab){
17+
18+
//extract the classname from the stylemodifier which comes in the format of :className
19+
var styleModifier = partial.match(/:([\w\-_])+/g) ? partial.match(/:([\w\-_])+/g)[0].slice(1) : null;
20+
if(styleModifier){
21+
22+
if(patternlab.config.debug){
23+
console.log('found partial styleModifier within pattern ' + pattern.key);
24+
}
25+
26+
//replace the stylemodifier placeholder with the class name
27+
pattern.extendedTemplate = pattern.extendedTemplate.replace('{{styleModifier}}', styleModifier);
28+
}
29+
}
30+
31+
return {
32+
consume_style_modifier: function(pattern, partial, patternlab){
33+
consumestylemodifier(pattern, partial, patternlab);
34+
}
35+
};
36+
37+
};
38+
39+
module.exports = style_modifier_hunter;
40+
41+
}());

gulpfile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ gulp.task('banner', function(){
4242
'./builder/pattern_exporter.js',
4343
'./builder/pattern_assembler.js',
4444
'./builder/pseudopattern_hunter.js',
45-
'./builder/list_item_hunter.js'
45+
'./builder/list_item_hunter.js',
46+
'./builder/style_modifier_hunter.js'
4647
])
4748
.pipe(strip_banner())
4849
.pipe(header( banner, {

0 commit comments

Comments
 (0)