Skip to content

Commit

Permalink
Merge pull request #208 from geoffp/pattern-engines
Browse files Browse the repository at this point in the history
PatternEngines ongoing work, round 4
  • Loading branch information
Brian Muenzenmeyer authored and bmuenzenmeyer committed Feb 23, 2018
1 parent d2dc6f5 commit e1ae249
Show file tree
Hide file tree
Showing 33 changed files with 765 additions and 224 deletions.
3 changes: 0 additions & 3 deletions packages/patternengine-node-underscore/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{
"env": {
"jasmine": true,
"node": true,
"mocha": true,
"browser": true,
"builtin": true
},
"globals": {},
Expand Down
1 change: 1 addition & 0 deletions packages/patternengine-node-underscore/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ public/index.html
public/styleguide.html
public/styleguide/html/styleguide.html
public/css/*
public/data/*
public/fonts/*
public/js/*
public/images/*
Expand Down
1 change: 1 addition & 0 deletions packages/patternengine-node-underscore/.travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ branches:
only:
- master
- dev
- pattern-engines
15 changes: 15 additions & 0 deletions packages/patternengine-node-underscore/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT.

PL-node-v1.0.0
- FIX: Resolve issue with not hiding underscored patterns.
- THX: Thanks @ivancamilov for reporting this regression.
- FIX: Fix misapplied error input class
- THX: Thanks @johngerome for the pull request!
- ADD: Added a note in the README during installation to run with elevated privileges
- THX: Thanks @RichardBray for the heads up
- ADD: Added a Prerequisites section to the README
- ADD: Added unit tests for pattern states and pseudopatterns
- CHG: Changed pseudopattern generation to use config.patterns.source directory instead of hardcode
- CHG: Explicitly sorting patterns by name prior to building the UI
- ADD: Added ability to specify link.* urls inside data objects
- CHG: Incremented version to 1.0.0. Achieved near-parity with PL PHP 1!
- THX: Thanks to each and every person who cared about Pattern Lab Node! - Brian

PL-node-v0.15.1
- FIX: Resolve issue with styleModifiers not being replaced when the partial has spaces in it.
- ADD: Support multiple styleModifier classes using the | pipe syntax
Expand Down
8 changes: 8 additions & 0 deletions packages/patternengine-node-underscore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@ The Node version of [Pattern Lab](http://patternlab.io/) is, at its core, a stat

This repository contains the vanilla builder logic, grunt and gulp configurations, and some sample template/css/data to illustrate the power and flexibility of the tool.

### Prerequisites

Make sure Node and npm are installed. A great guide can be found here: [https://docs.npmjs.com/getting-started/installing-node](https://docs.npmjs.com/getting-started/installing-node)

### Download

* Download the [latest release of patternlab-node](https://github.com/pattern-lab/patternlab-node/releases/latest) from Github
* Via npm, run `npm install patternlab-node` (Note this will auto install the grunt version currently. see below)
* **NOTE** Node version 4.X and 5.X have tentative support, citing [a lot of Windows issues](https://github.com/nodejs/node-gyp/issues/629), including [mine](https://github.com/pattern-lab/patternlab-node/issues/162). Upgrade node at your own risk until otherwise stated. I've tried to catalog some issues and troubleshooting steps on the [wiki](https://github.com/pattern-lab/patternlab-node/wiki/Windows-Issues).

### Troubleshooting Installs

Make sure you are running your terminal/command line session as administrator. This could mean `sudo`, or opening the window with a right-click option.

### Choose Your Adventure! Now Vanilla, Grunt & Gulp

This repository ships with two `package.json` files, a `Gruntfile.js`, and a `gulpfile.js`. The default is grunt currently. The core builder is not dependent on either.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* patternlab-node - v0.15.1 - 2015
* patternlab-node - v1.0.0 - 2015
*
* Brian Muenzenmeyer, and the web community.
* Licensed under the MIT license.
Expand All @@ -20,9 +20,6 @@
var config = require('../config.json');

//find the {{> template-name }} within patterns
if (config.debug) {
console.log('===\n', pattern, '\n===');
}
var matches = pattern.findPartials();
if(matches !== null){
matches.forEach(function(match, index, matches){
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* patternlab-node - v0.15.1 - 2015
* patternlab-node - v1.0.0 - 2015
*
* Brian Muenzenmeyer, and the web community.
* Licensed under the MIT license.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* patternlab-node - v0.15.1 - 2015
* patternlab-node - v1.0.0 - 2015
*
* Brian Muenzenmeyer, and the web community.
* Licensed under the MIT license.
Expand Down
15 changes: 9 additions & 6 deletions packages/patternengine-node-underscore/builder/object_factory.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* patternlab-node - v0.15.1 - 2015
*
/*
* patternlab-node - v1.0.0 - 2015
*
* Brian Muenzenmeyer, and the web community.
* Licensed under the MIT license.
*
Expand All @@ -20,9 +20,6 @@
// oPattern properties

var oPattern = function(abspath, subdir, filename, data) {
if (config.debug) {
console.log('=== NEW OPATTERN.', '\nabsPath:', abspath, '\nsubdir:', subdir, '\nfilename:', filename, '\ndata:\n', data);
}
this.fileName = filename.substring(0, filename.indexOf('.'));
this.fileExtension = path.extname(abspath);
this.abspath = abspath;
Expand Down Expand Up @@ -61,6 +58,12 @@
return this.engine.renderPattern(this.extendedTemplate, data, partials);
},

registerPartial: function () {
if (typeof this.engine.registerPartial === 'function') {
this.engine.registerPartial(this);
}
},

// the finders all delegate to the PatternEngine, which also encapsulates all
// appropriate regexes
findPartials: function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* patternlab-node - v0.15.1 - 2015
*
/*
* patternlab-node - v1.0.0 - 2015
*
* Brian Muenzenmeyer, 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.
*
*/

Expand Down
83 changes: 54 additions & 29 deletions packages/patternengine-node-underscore/builder/pattern_assembler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* patternlab-node - v0.15.1 - 2015
* patternlab-node - v1.0.0 - 2015
*
* Brian Muenzenmeyer, and the web community.
* Licensed under the MIT license.
Expand All @@ -12,22 +12,24 @@
"use strict";

var pattern_assembler = function(){

var fs = require('fs-extra'),
var path = require('path'),
fs = require('fs-extra'),
of = require('./object_factory'),
plutils = require('./utilities'),
patternEngines = require('./pattern_engines/pattern_engines'),
config = fs.readJSONSync('./config.json');
patternEngines = require('./pattern_engines/pattern_engines');

var config = fs.readJSONSync('./config.json');

function setState(pattern, patternlab){
if(patternlab.config.patternStates[pattern.patternName]){
if(patternlab.config.patternStates && patternlab.config.patternStates[pattern.patternName]){
pattern.patternState = patternlab.config.patternStates[pattern.patternName];
} else{
pattern.patternState = "";
}
}

function addPattern(pattern, patternlab){
//add the link to the global object
patternlab.data.link[pattern.patternGroup + '-' + pattern.patternName] = '/patterns/' + pattern.patternLink;

//only push to array if the array doesn't contain this pattern
Expand All @@ -43,7 +45,10 @@
}
//if the pattern is new, just push to the array
if(isNew){
// do global registration
patternlab.patterns.push(pattern);
// do plugin-specific registration
pattern.registerPartial();
}
}

Expand All @@ -66,44 +71,29 @@
}

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

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

if (config.debug) {
console.log('processPatternIterative:', 'filename:', filename);
console.log('processPatternIterative:', filename);
}

// skip non-pattern files
if (!patternEngines.isPatternFile(filename, patternlab)) { return; }
if (config.debug) {
console.log('processPatternIterative:', 'found pattern', file);
}
if (!patternEngines.isPatternFile(filename, patternlab)) { return null; }

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

//if file is named in the syntax for variants
if(patternEngines.isPseudoPatternJSON(filename)){
//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;
return currentPattern;
}

//can ignore all non-mustache files at this point
if(ext !== '.mustache'){
if (config.debug) {
console.log('==================== FOUND NON-MUSTACHE FILE');
}
return;
//can ignore all non-supported files at this point
if(patternEngines.isFileExtensionSupported(ext) === false){
return currentPattern;
}

//see if this file has a state
Expand All @@ -114,7 +104,7 @@
var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json";
currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2));
if(patternlab.config.debug){
console.log('found pattern-specific data.json for ' + currentPattern.key);
console.log('processPatternIterative: found pattern-specific data.json for ' + currentPattern.key);
}
}
catch(e) {
Expand Down Expand Up @@ -143,6 +133,8 @@

//add currentPattern to patternlab.patterns array
addPattern(currentPattern, patternlab);

return currentPattern;
}


Expand Down Expand Up @@ -277,6 +269,36 @@



//look for pattern links included in data files.
//these will be in the form of link.* WITHOUT {{}}, which would still be there from direct pattern inclusion
function parseDataLinks(patternlab){

//loop through all patterns
for (var i = 0; i < patternlab.patterns.length; i++){
var pattern = patternlab.patterns[i];
//look for link.* such as link.pages-blog as a value
var linkRE = /link.[A-z0-9-_]+/g;
//convert to string for easier searching
var dataObjAsString = JSON.stringify(pattern.jsonFileData);
var linkMatches = dataObjAsString.match(linkRE);

//if no matches found, escape current loop iteration
if(linkMatches === null) { continue; }

for(var i = 0; i < linkMatches.length; i++){
//for each match, find the expanded link within the already constructed patternlab.data.link object
var expandedLink = patternlab.data.link[linkMatches[i].split('.')[1]];
if(patternlab.config.debug){
console.log('expanded data link from ' + linkMatches[i] + ' to ' + expandedLink + ' inside ' + pattern.key);
}
//replace value with expandedLink on the pattern
dataObjAsString = dataObjAsString.replace(linkMatches[i], expandedLink);
}
//write back to data on the pattern
pattern.jsonFileData = JSON.parse(dataObjAsString);
}
}

return {
find_pattern_partials: function(pattern){
return pattern.findPartials();
Expand All @@ -300,7 +322,7 @@
return renderPattern(template, data, partials);
},
process_pattern_iterative: function(file, patternlab){
processPatternIterative(file, patternlab);
return processPatternIterative(file, patternlab);
},
process_pattern_recursive: function(file, patternlab, additionalData){
processPatternRecursive(file, patternlab, additionalData);
Expand All @@ -310,6 +332,9 @@
},
combine_listItems: function(patternlab){
buildListItems(patternlab);
},
parse_data_links: function(patternlab){
parseDataLinks(patternlab);
}
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* handlebars pattern engine for patternlab-node - v0.15.1 - 2015
*
* Geoffrey Pursell, Brian Muenzenmeyer, and the web community.
* Licensed under the MIT license.
*
* Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice.
*
*/

(function () {
"use strict";

var Handlebars = require('handlebars');

var engine_handlebars = {
engine: Handlebars,
engineName: 'handlebars',
engineFileExtension: '.hbs',

// regexes, stored here so they're only compiled once
// GTP warning: unchanged copypasta from mustache engine
// findPartialsRE: /{{>\s*((?:\d+-[\w-]+\/)+(\d+-[\w-]+(\.\w+)?)|[A-Za-z0-9-]+)(\:[\w-]+)?(\(\s*\w+\s*:\s*(?:'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")\))?\s*}}/g,
findPartialsRE: /{{#?>\s*([\w-\/.]+)(?:.|\s+)*?}}/g,
findPartialsWithStyleModifiersRE: /{{>([ ])?([\w\-\.\/~]+)(?!\()(\:[A-Za-z0-9-_|]+)+(?:(| )\(.*)?([ ])?}}/g,
findPartialsWithPatternParametersRE: /{{>([ ])?([\w\-\.\/~]+)(?:\:[A-Za-z0-9-_|]+)?(?:(| )\(.*)+([ ])?}}/g,
findListItemsRE: /({{#( )?)(list(I|i)tems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g,

// render it
renderPattern: function renderPattern(template, data, partials) {
if (partials) {
Handlebars.registerPartial(partials);
}
var compiled = Handlebars.compile(template);
return compiled(data);
},

registerPartial: function (oPattern) {
Handlebars.registerPartial(oPattern.key, oPattern.template);
},

// find and return any {{> template-name }} within pattern
findPartials: function findPartials(pattern) {
var matches = pattern.template.match(this.findPartialsRE);
return matches;
},
findPartialsWithStyleModifiers: function(pattern) {
var matches = pattern.template.match(this.findPartialsWithStyleModifiersRE);
return matches;
},
// returns any patterns that match {{> value(foo:"bar") }} or {{>
// value:mod(foo:"bar") }} within the pattern
findPartialsWithPatternParameters: function(pattern) {
var matches = pattern.template.match(this.findPartialsWithPatternParametersRE);
return matches;
},
findListItems: function(pattern) {
var matches = pattern.template.match(this.findListItemsRE);
return matches;
},
// given a pattern, and a partial string, tease out the "pattern key" and
// return it.
getPartialKey: function(pattern, partialString) {
var partialKey = partialString.replace(this.findPartialsRE, '$1');
return partialKey;
}
};

module.exports = engine_handlebars;
})();
Loading

0 comments on commit e1ae249

Please sign in to comment.