Skip to content

Commit aefb32a

Browse files
committed
Merge branch 'features/plugins' into dev
Conflicts: core/lib/patternlab.js core/scripts/postinstall.js
2 parents 33889f2 + 2d3af26 commit aefb32a

File tree

9 files changed

+156
-15
lines changed

9 files changed

+156
-15
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"no-with": 2,
6868
"quotes": [0, "single"],
6969
"radix": 2,
70-
"semi": [0, "never"],
70+
"semi": [1, "always"],
7171
"strict": 0,
7272
"space-before-blocks": 1,
7373
"space-before-function-paren": [1, {

core/lib/annotation_exporter.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,11 @@ var annotations_exporter = function (pl) {
5959
//take the annotation snippets and split them on our custom delimiter
6060
var annotationsYAML = annotationsMD.split('~*~');
6161
for (var i = 0; i < annotationsYAML.length; i++) {
62-
var annotation = buildAnnotationMD(annotationsYAML[i], markdown_parser)
62+
var annotation = buildAnnotationMD(annotationsYAML[i], markdown_parser);
6363
annotations.push(annotation);
6464
}
6565
return false;
66-
}
66+
};
6767
}
6868

6969
/*
@@ -72,7 +72,7 @@ var annotations_exporter = function (pl) {
7272
function parseAnnotationsMD() {
7373
var markdown_parser = new mp();
7474
var annotations = [];
75-
var mdFiles = glob.sync(paths.source.annotations + '/*.md')
75+
var mdFiles = glob.sync(paths.source.annotations + '/*.md');
7676

7777
mdFiles.forEach(parseMDFile(annotations, markdown_parser));
7878
return annotations;

core/lib/object_factory.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,14 +87,19 @@ Pattern.prototype = {
8787
// calculated path from the root of the public directory to the generated html
8888
// file for this pattern.
8989
// Should look something like '00-atoms-00-global-00-colors/00-atoms-00-global-00-colors.html'
90-
getPatternLink: function (patternlab, suffixType) {
90+
getPatternLink: function (patternlab, suffixType, customfileExtension) {
9191
// if no suffixType is provided, we default to rendered
9292
var suffixConfig = patternlab.config.outputFileSuffixes;
9393
var suffix = suffixType ? suffixConfig[suffixType] : suffixConfig.rendered;
9494

9595
if (suffixType === 'rawTemplate') {
9696
return this.name + path.sep + this.name + suffix + this.fileExtension;
9797
}
98+
99+
if (suffixType === 'custom') {
100+
return this.name + path.sep + this.name + customfileExtension;
101+
}
102+
98103
return this.name + path.sep + this.name + suffix + '.html';
99104
},
100105

core/lib/pattern_assembler.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ var pattern_assembler = function () {
551551
parseDataLinks(patternlab);
552552
},
553553
parse_data_links_specific: function (patternlab, data, label) {
554-
return parseDataLinksHelper(patternlab, data, label)
554+
return parseDataLinksHelper(patternlab, data, label);
555555
},
556556
parse_pattern_markdown: function (pattern, patternlab) {
557557
parsePatternMarkdown(pattern, patternlab);

core/lib/patternlab.js

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ var diveSync = require('diveSync'),
1414
glob = require('glob'),
1515
_ = require('lodash'),
1616
path = require('path'),
17-
plutils = require('./utilities'),
18-
cleanHtml = require('js-beautify').html;
17+
cleanHtml = require('js-beautify').html,
18+
inherits = require('util').inherits,
19+
pm = require('./plugin_manager'),
20+
plutils = require('./utilities');
21+
22+
var EventEmitter = require('events').EventEmitter;
1923

2024
function buildPatternData(dataFilesPath, fs) {
2125
var dataFiles = glob.sync(dataFilesPath + '*.json', {"ignore" : [dataFilesPath + 'listitems.json']});
@@ -74,6 +78,28 @@ function checkConfiguration(patternlab) {
7478
patternlab.config.outputFileSuffixes = _.extend(outputFileSuffixes, patternlab.config.outputFileSuffixes);
7579
}
7680

81+
/**
82+
* Finds and calls the main method of any found plugins.
83+
* @param patternlab - global data store
84+
*/
85+
function initializePlugins(patternlab) {
86+
var plugin_manager = new pm(patternlab.config, path.resolve(__dirname, '../../patternlab-config.json'));
87+
var foundPlugins = plugin_manager.detect_plugins();
88+
89+
if (foundPlugins && foundPlugins.length > 0) {
90+
91+
for (var i = 0; i < foundPlugins.length; i++) {
92+
var plugin = plugin_manager.load_plugin(foundPlugins[i]);
93+
plugin(patternlab);
94+
}
95+
}
96+
}
97+
98+
function PatternLabEventEmitter() {
99+
EventEmitter.call(this);
100+
}
101+
inherits(PatternLabEventEmitter, EventEmitter);
102+
77103
var patternlab_engine = function (config) {
78104
'use strict';
79105

@@ -93,9 +119,13 @@ var patternlab_engine = function (config) {
93119

94120
patternlab.package = fs.readJSONSync(path.resolve(__dirname, '../../package.json'));
95121
patternlab.config = config || fs.readJSONSync(path.resolve(__dirname, '../../patternlab-config.json'));
122+
patternlab.events = new PatternLabEventEmitter();
96123

97124
checkConfiguration(patternlab);
98125

126+
//todo: determine if this is the best place to wire up plugins
127+
initializePlugins(patternlab);
128+
99129
var paths = patternlab.config.paths;
100130

101131
function getVersion() {
@@ -237,6 +267,9 @@ var patternlab_engine = function (config) {
237267
}
238268

239269
function buildPatterns(deletePatternDir) {
270+
271+
patternlab.events.emit('patternlab-build-pattern-start', patternlab);
272+
240273
try {
241274
patternlab.data = buildPatternData(paths.source.data, fs);
242275
} catch (ex) {
@@ -269,9 +302,13 @@ var patternlab_engine = function (config) {
269302

270303
pattern_assembler.combine_listItems(patternlab);
271304

305+
patternlab.events.emit('patternlab-build-global-data-end', patternlab);
306+
272307
// diveSync once to perform iterative populating of patternlab object
273308
processAllPatternsIterative(pattern_assembler, paths.source.patterns, patternlab);
274309

310+
patternlab.events.emit('patternlab-pattern-iteration-end', patternlab);
311+
275312
//diveSync again to recursively include partials, filling out the
276313
//extendedTemplate property of the patternlab.patterns elements
277314
processAllPatternsRecursive(pattern_assembler, paths.source.patterns, patternlab);
@@ -385,6 +422,9 @@ var patternlab_engine = function (config) {
385422

386423
var footerHTML = pattern_assembler.renderPattern(patternlab.userFoot, allFooterData);
387424

425+
patternlab.events.emit('patternlab-pattern-write-begin', patternlab, pattern);
426+
427+
//write the compiled template to the public patterns directory
388428
var patternPage = headHTML + pattern.patternPartialCode + footerHTML;
389429

390430
//beautify the output if configured to do so
@@ -401,6 +441,8 @@ var patternlab_engine = function (config) {
401441
//write the encoded version too
402442
fs.outputFileSync(paths.public.patterns + pattern.getPatternLink(patternlab, 'markupOnly'), cleanedPatternPartialCode);
403443

444+
patternlab.events.emit('patternlab-pattern-write-end', patternlab, pattern);
445+
404446
return true;
405447
});
406448

core/lib/plugin_manager.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"use strict";
2+
3+
var plugin_manager = function (config, configPath) {
4+
var path = require('path'),
5+
fs = require('fs-extra'),
6+
util = require('./utilities');
7+
8+
function loadPlugin(pluginName) {
9+
return require(path.join(process.cwd(), 'node_modules', pluginName));
10+
}
11+
12+
function installPlugin(pluginName) {
13+
try {
14+
var pluginPath = path.resolve(
15+
path.join(process.cwd(), 'node_modules', pluginName)
16+
);
17+
console.log('Attempting to load plugin from', pluginPath);
18+
try {
19+
var pluginDirStats = fs.statSync(pluginPath);
20+
} catch (ex) {
21+
util.logRed(pluginName + ' not found, please use npm to install it first.');
22+
util.logRed(pluginName + ' not loaded.');
23+
return;
24+
}
25+
var pluginPathDirExists = pluginDirStats.isDirectory();
26+
if (pluginPathDirExists) {
27+
28+
//write config entry back
29+
var diskConfig = fs.readJSONSync(path.resolve(configPath), 'utf8');
30+
diskConfig[pluginName] = false;
31+
fs.outputFileSync(path.resolve(configPath), JSON.stringify(diskConfig, null, 2));
32+
33+
util.logGreen('Plugin ' + pluginName + ' installed.');
34+
35+
//todo, tell them how to uninstall or disable
36+
37+
}
38+
} catch (ex) {
39+
console.log(ex);
40+
}
41+
}
42+
43+
function detectPlugins() {
44+
var node_modules_path = path.join(process.cwd(), 'node_modules');
45+
return fs.readdirSync(node_modules_path).filter(function (dir) {
46+
var module_path = path.join(process.cwd(), 'node_modules', dir);
47+
return fs.statSync(module_path).isDirectory() && dir.indexOf('plugin-node-') === 0;
48+
});
49+
}
50+
51+
function disablePlugin(pluginName) {
52+
console.log('disablePlugin not implemented yet. No change made to state of plugin', pluginName);
53+
}
54+
55+
function enablePlugin(pluginName) {
56+
console.log('enablePlugin not implemented yet. No change made to state of plugin', pluginName);
57+
}
58+
59+
return {
60+
install_plugin: function (pluginName) {
61+
installPlugin(pluginName);
62+
},
63+
load_plugin: function (pluginName) {
64+
return loadPlugin(pluginName);
65+
},
66+
detect_plugins: function () {
67+
return detectPlugins();
68+
},
69+
disable_plugin: function (pluginName) {
70+
disablePlugin(pluginName);
71+
},
72+
enable_plugin: function (pluginName) {
73+
enablePlugin(pluginName);
74+
}
75+
};
76+
77+
};
78+
79+
module.exports = plugin_manager;

core/lib/starterkit_manager.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,14 @@ var starterkit_manager = function (config) {
5858
if (contentType && contentType.indexOf('application/json') === -1) {
5959
throw new TypeError("StarterkitManager->listStarterkits: Not valid JSON");
6060
}
61-
return res.json()
61+
return res.json();
6262
}).then(function (json) {
6363
if (!json.items || !Array.isArray(json.items)) {
6464
return false;
6565
}
6666
return json.items
6767
.map(function (repo) {
68-
return {name: repo.name, url: repo.html_url}
68+
return {name: repo.name, url: repo.html_url};
6969
});
7070
}).catch(function (err) {
7171
console.error(err);

core/lib/ui_builder.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ var ui_builder = function () {
246246
patternState: pattern.patternState,
247247
patternSrcPath: encodeURI(pattern.subdir + '/' + pattern.fileName),
248248
patternPath: patternPath
249-
}
249+
};
250250
}
251251

252252
/**
@@ -553,8 +553,8 @@ var ui_builder = function () {
553553
//viewAllPaths
554554
output += 'var viewAllPaths = ' + JSON.stringify(patternlab.viewAllPaths) + ';' + eol;
555555

556-
//plugins someday
557-
output += 'var plugins = [];' + eol;
556+
//plugins
557+
output += 'var plugins = ' + JSON.stringify(patternlab.plugins) + ';' + eol;
558558

559559
//smaller config elements
560560
output += 'var defaultShowPatternInfo = ' + (patternlab.config.defaultShowPatternInfo ? patternlab.config.defaultShowPatternInfo : 'false') + ';' + eol;
@@ -645,7 +645,7 @@ var ui_builder = function () {
645645

646646
return {
647647
buildFrontend: function (patternlab) {
648-
buildFrontend(patternlab)
648+
buildFrontend(patternlab);
649649
},
650650
isPatternExcluded: function (pattern, patternlab) {
651651
return isPatternExcluded(pattern, patternlab);

core/scripts/postinstall.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ try {
55
var path = require('path');
66
var fs = require('fs-extra');
77
var smPath = path.resolve(__dirname, '..', 'lib/starterkit_manager.js');
8+
var pmPath = path.resolve(__dirname, '..', 'lib/plugin_manager.js');
89
var uPath = path.resolve(__dirname, '..', 'lib/utilities.js');
910
var sm = require(smPath);
11+
var pm = require(pmPath);
1012
var u = require(uPath);
1113

1214
//get the config
@@ -21,8 +23,21 @@ try {
2123
if (foundStarterkits && foundStarterkits.length > 0) {
2224
starterkit_manager.load_starterkit(foundStarterkits[0], true);
2325
} else {
24-
console.log('No starterkits found to automatically load.')
26+
console.log('No starterkits found to automatically load.');
2527
}
28+
29+
//determine if any plugins are already installed
30+
var plugin_manager = new pm(config, configPath);
31+
var foundPlugins = plugin_manager.detect_plugins();
32+
33+
if (foundPlugins && foundPlugins.length > 0) {
34+
35+
for (var i = 0; i < foundPlugins.length; i++) {
36+
console.log('Found plugin', foundPlugins[i]);
37+
plugin_manager.install_plugin(foundPlugins[i]);
38+
}
39+
}
40+
2641
u.logGreen('Pattern Lab postinstall complete.');
2742

2843
} catch (ex) {

0 commit comments

Comments
 (0)