From d977b18b97299de77625d686d8c7ee3302458d6c Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Wed, 12 Aug 2015 23:42:50 -0500 Subject: [PATCH 1/9] Support for ignoring _directories Resolves #128 --- CHANGELOG | 4 ++++ README.md | 6 ++++++ builder/patternlab.js | 30 ++++++++++++++++++++---------- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 47e84b680..643571c5b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,8 @@ THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT. + +PL-node-v0.11.0 + - ADD: Ignore pattern directories that start with an underscore. + PL-node-v0.10.1 - ADD: Added more unit tests for recently more-modular code - FIX: Lineage was not working for patterns with pattern parameters diff --git a/README.md b/README.md index f2eb63b62..294871070 100644 --- a/README.md +++ b/README.md @@ -177,6 +177,12 @@ If your instance of Pattern Lab lives in a subdirectory of your server, for inst Default: blank +##### excluding patterns + +If you'd like to exclude an individual pattern you can do so by prepending the filename with an underscore, like: `_filename.mustache` + +You can also exclude complete directories by prepending the directory name with an underscore, like: `/_experiment/...` + ##### Verbose Mode `patternlab.json` is a file created for debugging purposes. Set `debug` to true in `.config.json` to see all the secrets. diff --git a/builder/patternlab.js b/builder/patternlab.js index 74e4c186f..914e9fdf6 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -65,17 +65,27 @@ var patternlab_engine = function () { var pattern_assembler = new pa(), entity_encoder = new he(), - pattern_exporter = new pe(); - - diveSync('./source/_patterns', function(err, file){ - //log any errors - if(err){ - console.log(err); - return; - } - - pattern_assembler.process_pattern_file(file, patternlab); + pattern_exporter = new pe(), + patterns_dir = './source/_patterns'; + + diveSync(patterns_dir, { + filter: function(path, dir) { + if(dir){ + var remainingPath = path.replace(patterns_dir, ''); + var isValidPath = remainingPath.indexOf('/_') === -1; + return isValidPath; + } + return true; + } + }, + function(err, file){ + //log any errors + if(err){ + console.log(err); + return; + } + pattern_assembler.process_pattern_file(file, patternlab); }); //render all patterns last, so lineageR works patternlab.patterns.forEach(function(pattern, index, patterns){ From c7d0399c4b1d6e138dadf0072031bf851d4eb923 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Thu, 20 Aug 2015 23:35:11 -0500 Subject: [PATCH 2/9] first half of list item support - constructing the list --- builder/pattern_assembler.js | 31 +++++++++++++++++++++++++++++++ builder/patternlab.js | 2 ++ 2 files changed, 33 insertions(+) diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index a024a7dac..5fb1b3444 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -156,6 +156,34 @@ return obj1; } + function buildListItems(patternlab){ + //combine all list items into one structure + var list = []; + for (var item in patternlab.listitems) { + if( patternlab.listitems.hasOwnProperty(item)) { + list.push(patternlab.listitems[item]); + } + } + patternlab.listItemArray = shuffle(list); + + for(var i = 1; i <= 12; i++){ + var top = i; + var c = 1; + var tempItems = []; + while(c <= top){ + tempItems.push(patternlab.listItemArray[c]); + c++; + } + patternlab.listitems['' + i ] = tempItems; + } + } + + //http://stackoverflow.com/questions/6274339/how-can-i-shuffle-an-array-in-javascript + function shuffle(o){ + for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x); + return o; + } + return { find_pattern_partials: function(pattern){ return findPartials(pattern); @@ -180,6 +208,9 @@ }, merge_data: function(existingData, newData){ return mergeData(existingData, newData); + }, + combine_listItems: function(patternlab){ + buildListItems(patternlab); } }; diff --git a/builder/patternlab.js b/builder/patternlab.js index 914e9fdf6..fe62fe5cf 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -68,6 +68,8 @@ var patternlab_engine = function () { pattern_exporter = new pe(), patterns_dir = './source/_patterns'; + pattern_assembler.combine_listItems(patternlab); + diveSync(patterns_dir, { filter: function(path, dir) { if(dir){ From 14c970592462e24d95b3fa2549c4ed3f64d28332 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Thu, 20 Aug 2015 23:58:46 -0500 Subject: [PATCH 3/9] Found pattern parameter data bleeding into global data object Closes #139 --- CHANGELOG | 1 + builder/parameter_hunter.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 643571c5b..750812b9d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT. PL-node-v0.11.0 - ADD: Ignore pattern directories that start with an underscore. + - FIX: Resolved issue where pattern parameter data bled into global data object PL-node-v0.10.1 - ADD: Added more unit tests for recently more-modular code diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index 0541b211f..d1a6b4fb9 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -41,13 +41,13 @@ //compile this partial immeadiately, essentially consuming it. var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); - var existingData = pattern.data || patternlab.data; + var existingData = pattern.data ? JSON.parse(JSON.stringify(pattern.data)) : JSON.parse(JSON.stringify(patternlab.data)); //merge paramData with any other data that exists. for (var prop in paramData) { if (existingData.hasOwnProperty(prop)) { existingData[prop] = paramData[prop]; - } + } } //extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally From 97b3e25ec98014084afa6ce4635beccac6aed7dc Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Fri, 21 Aug 2015 00:27:07 -0500 Subject: [PATCH 4/9] Support a fluid viewport closes #122 based on https://github.com/pattern-lab/edition-php-development/issues/9 && https://github.com/pattern-lab/styleguidekit-assets-default/commit/eb69fc700cfcb17c6672789b53e2eb7d879b6a6f --- CHANGELOG | 1 + public/styleguide/js/styleguide.js | 173 ++++++++++++++++------------- 2 files changed, 94 insertions(+), 80 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 750812b9d..e9891025c 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT. PL-node-v0.11.0 - ADD: Ignore pattern directories that start with an underscore. - FIX: Resolved issue where pattern parameter data bled into global data object + - ADD: Support a fluid viewport PL-node-v0.10.1 - ADD: Added more unit tests for recently more-modular code diff --git a/public/styleguide/js/styleguide.js b/public/styleguide/js/styleguide.js index 8c9616255..05d7cb276 100644 --- a/public/styleguide/js/styleguide.js +++ b/public/styleguide/js/styleguide.js @@ -1,5 +1,5 @@ (function(w){ - + var sw = document.body.clientWidth, //Viewport Width sh = $(document).height(), //Viewport Height minViewportWidth = 240, //Minimum Size for Viewport @@ -12,14 +12,19 @@ $headerHeight = $('.sg-header').height(), discoID = false, discoMode = false, + fullMode = true, hayMode = false; - - + $(w).resize(function(){ //Update dimensions on resize sw = document.body.clientWidth; sh = $(document).height(); setAccordionHeight(); + + if(fullMode === true) { + sizeiframe(sw, false); + }; + }); /* Pattern Lab accordion dropdown */ @@ -43,12 +48,12 @@ setAccordionHeight(); }); - //Accordion Height + //Accordion Height function setAccordionHeight() { var $activeAccordion = $('.sg-acc-panel.active').first(), accordionHeight = $activeAccordion.height(), availableHeight = sh-$headerHeight; //Screen height minus the height of the header - + $activeAccordion.height(availableHeight); //Set height of accordion to the available height } @@ -56,7 +61,7 @@ e.preventDefault(); $('.sg-nav-container').toggleClass('active'); }); - + //"View (containing clean, code, raw, etc options) Trigger $('#sg-t-toggle').on("click", function(e){ e.preventDefault(); @@ -68,84 +73,89 @@ e.preventDefault(); $(this).parents('ul').toggleClass('active'); }); - + //Phase View Events $('.sg-size[data-size]').on("click", function(e){ e.preventDefault(); killDisco(); killHay(); - + fullMode = false; + var val = $(this).attr('data-size'); - + if (val.indexOf('px') > -1) { $bodySize = 1; } - - val = val.replace(/[^\d.-]/g,'') + + val = val.replace(/[^\d.-]/g,'') sizeiframe(Math.floor(val*$bodySize)); }); - + //Size View Events // handle small button function goSmall() { killDisco(); killHay(); + fullMode = false; sizeiframe(getRandom(minViewportWidth,500)); } - + $('#sg-size-s').on("click", function(e){ e.preventDefault(); goSmall(); }); - + jwerty.key('ctrl+shift+s', function(e) { goSmall(); return false; }); - + // handle medium button function goMedium() { killDisco(); killHay(); + fullMode = false; sizeiframe(getRandom(500,800)); } - + $('#sg-size-m').on("click", function(e){ e.preventDefault(); goMedium(); }); - + jwerty.key('ctrl+shift+m', function(e) { goMedium(); return false; }); - + // handle large button function goLarge() { killDisco(); killHay(); + fullMode = false; sizeiframe(getRandom(800,1200)); } - + $('#sg-size-l').on("click", function(e){ e.preventDefault(); goLarge(); }); - + jwerty.key('ctrl+shift+l', function(e) { goLarge(); return false; }); //Click Full Width Button - $('#sg-size-full').on("click", function(e){ //Resets + $('#sg-size-full').on("click", function(e){ //Resets e.preventDefault(); killDisco(); killHay(); + fullMode = true; sizeiframe(sw); }); - + //Click Random Size Button $('#sg-size-random').on("click", function(e){ e.preventDefault(); @@ -153,11 +163,12 @@ killHay(); sizeiframe(getRandom(minViewportWidth,sw)); }); - + //Click for Disco Mode, which resizes the viewport randomly $('#sg-size-disco').on("click", function(e){ e.preventDefault(); killHay(); + fullMode = false; if (discoMode) { killDisco(); @@ -171,19 +182,19 @@ function disco() { sizeiframe(getRandom(minViewportWidth,sw)); } - + function killDisco() { discoMode = false; clearInterval(discoID); discoID = false; } - + function startDisco() { killHay(); discoMode = true; discoID = setInterval(disco, 800); } - + jwerty.key('ctrl+shift+d', function(e) { if (!discoMode) { startDisco(); @@ -212,22 +223,22 @@ $('#sg-gen-container').removeClass('hay-mode'); sizeiframe(Math.floor(currentWidth)); } - + // start Hay! mode function startHay() { killDisco(); hayMode = true; $('#sg-gen-container').removeClass("vp-animate").width(minViewportWidth+viewportResizeHandleWidth); $sgViewport.removeClass("vp-animate").width(minViewportWidth); - + var timeoutID = window.setTimeout(function(){ $('#sg-gen-container').addClass('hay-mode').width(maxViewportWidth+viewportResizeHandleWidth); $sgViewport.addClass('hay-mode').width(maxViewportWidth); - + setInterval(function(){ var vpSize = $sgViewport.width(); updateSizeReading(vpSize); },100); }, 200); } - + // start hay from a keyboard shortcut jwerty.key('ctrl+shift+h', function(e) { if (hayMode) { @@ -280,20 +291,20 @@ var val = parseFloat($(this).val()); updateSizeReading(val,'em','updatePxInput'); }); - + // set 0 to 320px as a default jwerty.key('ctrl+shift+0', function(e) { e.preventDefault(); sizeiframe(320,true); return false; }); - + // handle the MQ click var mqs = []; $('#sg-mq a').each(function(i) { - + mqs.push($(this).html()); - + // bind the click $(this).on("click", function(i,k) { return function(e) { @@ -305,7 +316,7 @@ sizeiframe(width,true); } }(i,this)); - + // bind the keyboard shortcut. can't use cmd on a mac because 3 & 4 are for screenshots jwerty.key('ctrl+shift+'+(i+1), function (k) { return function(e) { @@ -317,9 +328,9 @@ return false; } }(this)); - + }); - + //Resize the viewport //'size' is the target size of the viewport //'animate' is a boolean for switching the CSS animation on or off. 'animate' is true by default, but can be set to false for things like nudging and dragging @@ -335,7 +346,7 @@ } //Conditionally remove CSS animation class from viewport - if(animate==false) { + if(animate==false) { $('#sg-gen-container,#sg-viewport').removeClass("vp-animate"); //If aninate is set to false, remove animate class from viewport } else { $('#sg-gen-container,#sg-viewport').addClass("vp-animate"); @@ -347,7 +358,7 @@ updateSizeReading(theSize); //Update values in toolbar saveSize(theSize); //Save current viewport to cookie } - + function saveSize(size) { if (!DataSaver.findValue('vpWidth')) { DataSaver.addValue("vpWidth",size); @@ -355,8 +366,8 @@ DataSaver.updateValue("vpWidth",size); } } - - + + //Update Pixel and Em inputs //'size' is the input number //'unit' is the type of unit: either px or em. Default is px. Accepted values are 'px' and 'em' @@ -369,7 +380,7 @@ pxSize = size; emSize = size/$bodySize; } - + if (target == 'updatePxInput') { $sizePx.val(pxSize); } else if (target == 'updateEmInput') { @@ -377,19 +388,19 @@ } else { $sizeEms.val(emSize.toFixed(2)); $sizePx.val(pxSize); - } + } } - + /* Returns a random number between min and max */ function getRandom (min, max) { return Math.random() * (max - min) + min; } - + function updateViewportWidth(size) { - + $("#sg-viewport").width(size); $("#sg-gen-container").width(size*1 + 14); - + updateSizeReading(size); } @@ -398,27 +409,29 @@ // 2. make a hidden div visible so that it can track mouse movements and make sure the pointer doesn't get lost in the iframe // 3. on "mousemove" calculate the math, save the results to a cookie, and update the viewport $('#sg-rightpull').mousedown(function(event) { - + // capture default data var origClientX = event.clientX; var origViewportWidth = $sgViewport.width(); - + + fullMode = false; + // show the cover $("#sg-cover").css("display","block"); - + // add the mouse move event and capture data. also update the viewport width $('#sg-cover').mousemove(function(event) { - + viewportWidth = (origClientX > event.clientX) ? origViewportWidth - ((origClientX - event.clientX)*2) : origViewportWidth + ((event.clientX - origClientX)*2); - + if (viewportWidth > minViewportWidth) { - + if (!DataSaver.findValue('vpWidth')) { DataSaver.addValue("vpWidth",viewportWidth); } else { DataSaver.updateValue("vpWidth",viewportWidth); } - + sizeiframe(viewportWidth,false); } }); @@ -438,7 +451,7 @@ // get the request vars var oGetVars = urlHandler.getRequestVars(); - + // pre-load the viewport width var vpWidth = 0; var trackViewportWidth = true; // can toggle this feature on & off @@ -454,7 +467,7 @@ } else if (trackViewportWidth && (vpWidth = DataSaver.findValue("vpWidth"))) { updateViewportWidth(vpWidth); } - + // load the iframe source var patternName = "all"; var patternPath = ""; @@ -464,36 +477,36 @@ patternPath = urlHandler.getFileName(patternName); iFramePath = (patternPath != "") ? window.location.protocol+"//"+window.location.host+window.location.pathname.replace("index.html","")+patternPath : iFramePath; } - + if (patternName != "all") { document.getElementById("title").innerHTML = "Pattern Lab - "+patternName; history.replaceState({ "pattern": patternName }, null, null); } - + document.getElementById("sg-raw").setAttribute("href",urlHandler.getFileName(patternName)); - + urlHandler.skipBack = true; document.getElementById("sg-viewport").contentWindow.location.replace(iFramePath); - + //IFrame functionality - + // update the iframe with the source from clicked element in pull down menu. also close the menu // having it outside fixes an auto-close bug i ran into $('.sg-nav a').not('.sg-acc-handle').on("click", function(e){ - + e.preventDefault(); - + // update the iframe via the history api handler document.getElementById("sg-viewport").contentWindow.postMessage( { "path": urlHandler.getFileName($(this).attr("data-patternpartial")) }, urlHandler.targetOrigin); - + // close up the menu $(this).parents('.sg-acc-panel').toggleClass('active'); $(this).parents('.sg-acc-panel').siblings('.sg-acc-handle').toggleClass('active'); - + return false; - + }); // handle when someone clicks on the grey area of the viewport so it auto-closes the nav @@ -504,7 +517,7 @@ function closePanels() { $(this).toggleClass('active'); } }); - + $('.sg-acc-handle').each(function() { if ($(this).hasClass('active')) { $(this).toggleClass('active'); @@ -513,43 +526,43 @@ function closePanels() { } $('#sg-vp-wrap').click(function(e) { - + closePanels(); - + }); // watch the iframe source so that it can be sent back to everyone else. // based on the great MDN docs at https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage function receiveIframeMessage(event) { - + var data = (typeof event.data !== "string") ? event.data : JSON.parse(event.data); - + // does the origin sending the message match the current host? if not dev/null the request if ((window.location.protocol !== "file:") && (event.origin !== window.location.protocol+"//"+window.location.host)) { return; } - + if (data.bodyclick !== undefined) { - + closePanels(); - + } else if (data.patternpartial !== undefined) { - + if (!urlHandler.skipBack) { - + if ((history.state === undefined) || (history.state === null) || (history.state.pattern !== data.patternpartial)) { urlHandler.pushPattern(data.patternpartial, data.path); } - + if (wsnConnected) { var iFramePath = urlHandler.getFileName(data.patternpartial); wsn.send( '{"url": "'+iFramePath+'", "patternpartial": "'+event.data.patternpartial+'" }' ); } } - + // reset the defaults urlHandler.skipBack = false; - + } else if (data.keyPress !== undefined) { if (data.keyPress == 'ctrl+shift+s') { goSmall(); @@ -571,7 +584,7 @@ function receiveIframeMessage(event) { } } else if (data.keyPress == 'ctrl+shift+0') { sizeiframe(320,true); - } else if (found = data.keyPress.match(/ctrl\+shift\+([1-9])/)) { + } else if (found == data.keyPress.match(/ctrl\+shift\+([1-9])/)) { var val = mqs[(found[1]-1)]; var type = (val.indexOf("px") !== -1) ? "px" : "em"; val = val.replace(type,""); From 6f5ede8f0a619684a57a2d25112e843737ba4c0d Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Tue, 25 Aug 2015 01:19:24 -0500 Subject: [PATCH 5/9] initial list item support closes #92 --- Gruntfile.js | 4 + builder/list_item_hunter.js | 109 ++++++++++++++++++ builder/object_factory.js | 3 +- builder/parameter_hunter.js | 20 ++-- builder/pattern_assembler.js | 43 +++++-- builder/patternlab.js | 1 - .../02-comments/00-comment-thread.mustache | 4 +- 7 files changed, 161 insertions(+), 23 deletions(-) create mode 100644 builder/list_item_hunter.js diff --git a/Gruntfile.js b/Gruntfile.js index cd9112eb3..f0708fab1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -47,6 +47,10 @@ module.exports = function(grunt) { pseudopattern_hunter: { src: './builder/pseudopattern_hunter.js', dest: './builder/pseudopattern_hunter.js' + }, + list_item_hunter: { + src: './builder/list_item_hunter.js', + dest: './builder/list_item_hunter.js' } }, copy: { diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js new file mode 100644 index 000000000..999e81255 --- /dev/null +++ b/builder/list_item_hunter.js @@ -0,0 +1,109 @@ +/* + * patternlab-node - v0.10.1 - 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. + * + */ + +(function () { + "use strict"; + + var list_item_hunter = function(){ + + var extend = require('util')._extend, + pa = require('./pattern_assembler'), + mustache = require('mustache'), + pattern_assembler = new pa(), + items = [ 'zero','one','two','three','four','five','six','seven','eight','nine','ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen','twenty']; + + function processListItemPartials(pattern, patternlab){ + //find any listitem blocks + var matches = pattern_assembler.find_list_items(pattern, patternlab); + if(matches !== null){ + matches.forEach(function(liMatch, index, matches){ + + if(patternlab.config.debug){ + console.log('found listItem of size ' + liMatch + ' inside ' + pattern.key); + } + + //find the boundaries of the block + var loopNumberString = liMatch.split('.')[1].split('}')[0].trim(); + + //find the boundaries of the block + var end = liMatch.replace('#', '/'); + var patternBlock = pattern.template.substring(pattern.template.indexOf(liMatch) + liMatch.length, pattern.template.indexOf(end)).trim(); + + //build arrays that repeat the block, however large we need to + var repeatedBlockTemplate = []; + var repeatedBlockHtml = ''; + for(var i = 0; i < items.indexOf(loopNumberString); i++){ + repeatedBlockTemplate.push(patternBlock); + } + + //iterate over each copied block, rendering its contents along with pattenlab.listitems[i] + for(var i = 0; i < repeatedBlockTemplate.length; i++){ + + var thisBlockTemplate = repeatedBlockTemplate[i]; + var thisBlockHTML = ""; + + //combine listItem data with pattern data with global data + var itemData = patternlab.listitems['' + items.indexOf(loopNumberString)]; //this is a propety + var globalData = JSON.parse(JSON.stringify(patternlab.data)); + var localData = JSON.parse(JSON.stringify(pattern.jsonFileData)); + + var allData = pattern_assembler.merge_data(globalData, localData); + allData = pattern_assembler.merge_data(allData, itemData[i]); + allData.link = extend({}, patternlab.data.link); + + //check for partials within the repeated block + var foundPartials = pattern_assembler.find_pattern_partials({ 'template' : thisBlockTemplate }); + + if(foundPartials.length > 0){ + + for(var j = 0; j < foundPartials.length; j++){ + //add the lineage once for the parent pattern + //TODO + + //get the partial + var partialName = foundPartials[j].match(/([a-z-]+)/ig)[0]; + var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); + + //replace its reference within the block with the extended template + thisBlockTemplate = thisBlockTemplate.replace(foundPartials[j], partialPattern.extendedTemplate); + + } + + //render with data + thisBlockHTML = pattern_assembler.renderPattern(thisBlockTemplate, allData, patternlab.partials); + + } else{ + //just render with mergedData + thisBlockHTML = pattern_assembler.renderPattern(thisBlockTemplate, allData, patternlab.partials); + } + + //add the rendered HTML to our string + repeatedBlockHtml = repeatedBlockHtml + thisBlockHTML; + } + + //replace the block with our generated HTML + var repeatingBlock = pattern.extendedTemplate.substring(pattern.extendedTemplate.indexOf(liMatch), pattern.extendedTemplate.indexOf(end) + end.length); + pattern.extendedTemplate = pattern.extendedTemplate.replace(repeatingBlock, repeatedBlockHtml); + + }); + } + } + + return { + process_list_item_partials: function(pattern, patternlab){ + processListItemPartials(pattern, patternlab); + } + }; + + }; + + module.exports = list_item_hunter; + +}()); diff --git a/builder/object_factory.js b/builder/object_factory.js index f1809b16e..1e632d17b 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -15,8 +15,7 @@ this.fileName = filename.substring(0, filename.indexOf('.')); this.subdir = subdir; this.name = subdir.replace(/[\/\\]/g, '-') + '-' + this.fileName; //this is the unique name with the subDir - this.data = data || null; - this.jsonFileData = {}; + this.jsonFileData = data || {}; this.patternName = this.fileName.substring(this.fileName.indexOf('-') + 1); //this is the display name for the ui this.patternLink = this.name + '/' + this.name + '.html'; this.patternGroup = this.name.substring(this.name.indexOf('-') + 1, this.name.indexOf('-', 4) + 1 - this.name.indexOf('-') + 1); diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index d1a6b4fb9..5b7c0d3b4 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -23,9 +23,10 @@ //find the {{> template-name(*) }} within patterns var matches = pattern.template.match(/{{>([ ]+)?([A-Za-z0-9-]+)(\()(.+)(\))([ ]+)?}}/g); if(matches !== null){ + //compile this partial immeadiately, essentially consuming it. matches.forEach(function(pMatch, index, matches){ //find the partial's name - var partialName = pMatch.match(/([a-z-]+)/ig)[0] + var partialName = pMatch.match(/([a-z-]+)/ig)[0]; if(patternlab.config.debug){ console.log('found patternParameters for ' + partialName); @@ -39,20 +40,17 @@ //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 var paramData = eval(paramString); - //compile this partial immeadiately, essentially consuming it. var partialPattern = pattern_assembler.get_pattern_by_key(partialName, patternlab); - var existingData = pattern.data ? JSON.parse(JSON.stringify(pattern.data)) : JSON.parse(JSON.stringify(patternlab.data)); + var globalData = JSON.parse(JSON.stringify(patternlab.data)); + var localData = JSON.parse(JSON.stringify(pattern.jsonFileData)); - //merge paramData with any other data that exists. - for (var prop in paramData) { - if (existingData.hasOwnProperty(prop)) { - existingData[prop] = paramData[prop]; - } - } + var allData = pattern_assembler.merge_data(globalData, localData); + allData = pattern_assembler.merge_data(allData, paramData); //extend pattern data links into link for pattern link shortcuts to work. we do this locally and globally - existingData.link = extend({}, patternlab.data.link); - var renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, existingData, patternlab.partials); + allData.link = extend({}, patternlab.data.link); + + var renderedPartial = pattern_assembler.renderPattern(partialPattern.extendedTemplate, allData, patternlab.partials); //remove the parameter from the partial and replace it with the rendered partial + paramData pattern.extendedTemplate = pattern.extendedTemplate.replace(pMatch, renderedPartial); diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 5fb1b3444..674b42b18 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -13,12 +13,27 @@ var pattern_assembler = function(){ + function isObjectEmpty(obj) { + for(var prop in obj) { + if(obj.hasOwnProperty(prop)) + return false; + } + + return true; + } + + //find and return any {{> template-name }} within pattern function findPartials(pattern){ var matches = pattern.template.match(/{{>([ ])?([A-Za-z0-9-]+)(?:\:[A-Za-z0-9-]+)?(?:(| )\(.*)?([ ])?}}/g); return matches; } + function findListItems(pattern){ + var matches = pattern.template.match(/({{#( )?)(listItems.)(one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|nineteen|twenty)( )?}}/g); + return matches; + } + function setState(pattern, patternlab){ if(patternlab.config.patternStates[pattern.patternName]){ pattern.patternState = patternlab.config.patternStates[pattern.patternName]; @@ -86,10 +101,12 @@ lh = require('./lineage_hunter'), ph = require('./parameter_hunter'), pph = require('./pseudopattern_hunter'), + lih = require('./list_item_hunter'), path = require('path'); var parameter_hunter = new ph(), lineage_hunter = new lh(), + list_item_hunter = new lih(), pseudopattern_hunter = new pph(); currentPattern.extendedTemplate = currentPattern.template; @@ -102,6 +119,10 @@ if(patternlab.config.debug){ console.log('found partials for ' + currentPattern.key); } + + //find any listItem partials + list_item_hunter.process_list_item_partials(currentPattern, patternlab); + //determine if the template contains any pattern parameters. if so they must be immediately consumed parameter_hunter.find_parameters(currentPattern, patternlab); @@ -166,15 +187,17 @@ } patternlab.listItemArray = shuffle(list); - for(var i = 1; i <= 12; i++){ - var top = i; - var c = 1; + for(var i = 1; i <= patternlab.listItemArray.length; i++){ var tempItems = []; - while(c <= top){ - tempItems.push(patternlab.listItemArray[c]); - c++; + if( i === 1){ + tempItems.push(patternlab.listItemArray[0]); + patternlab.listitems['' + i ] = tempItems; + } else{ + for(var c = 1; c <= i; c++){ + tempItems.push(patternlab.listItemArray[c - 1]); + patternlab.listitems['' + i ] = tempItems; + } } - patternlab.listitems['' + i ] = tempItems; } } @@ -188,6 +211,9 @@ find_pattern_partials: function(pattern){ return findPartials(pattern); }, + find_list_items: function(pattern){ + return findListItems(pattern) + }, setPatternState: function(pattern, patternlab){ setState(pattern, patternlab); }, @@ -211,6 +237,9 @@ }, combine_listItems: function(patternlab){ buildListItems(patternlab); + }, + is_object_empty: function(obj){ + return isObjectEmpty(obj); } }; diff --git a/builder/patternlab.js b/builder/patternlab.js index fe62fe5cf..ff409887a 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -94,7 +94,6 @@ var patternlab_engine = function () { //render the pattern, but first consolidate any data we may have var allData = JSON.parse(JSON.stringify(patternlab.data)); allData = pattern_assembler.merge_data(allData, pattern.jsonFileData); - allData = pattern_assembler.merge_data(allData, pattern.data); pattern.patternPartial = pattern_assembler.renderPattern(pattern.extendedTemplate, allData); diff --git a/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache b/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache index a6a48dc66..6e150a137 100644 --- a/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache +++ b/source/_patterns/02-organisms/02-comments/00-comment-thread.mustache @@ -3,9 +3,9 @@

59 Comments

{{> molecules-comment-form }}
    - {{#listItems.twelve}} + {{#listItems.five}} {{> molecules-single-comment }} - {{/listItems.twelve}} + {{/listItems.five}}
{{> molecules-pagination }} From b3f596970fe85090cd8f2bafc11f24af962ce270 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Tue, 25 Aug 2015 21:34:19 -0500 Subject: [PATCH 6/9] fixed a unit test --- test/object_factory_tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/object_factory_tests.js b/test/object_factory_tests.js index 9bffad0ab..63ca0cc7f 100644 --- a/test/object_factory_tests.js +++ b/test/object_factory_tests.js @@ -9,7 +9,7 @@ test.equals(p.name, '00-atoms-00-global-00-colors'); test.equals(p.subdir, '00-atoms/00-global'); test.equals(p.fileName, '00-colors'); - test.equals(p.data.d, 123); + test.equals(p.jsonFileData.d, 123); 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.patternGroup, 'atoms'); From 54369c117da8b4e12e4c6217b446013e5b42b3e3 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Tue, 25 Aug 2015 22:20:50 -0500 Subject: [PATCH 7/9] basic unit test coverage for list_item_hunter --- builder/list_item_hunter.js | 16 ++-- builder/pattern_assembler.js | 2 +- test/list_item_hunter_tests.js | 150 +++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 6 deletions(-) create mode 100644 test/list_item_hunter_tests.js diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js index 999e81255..a15e1ef26 100644 --- a/builder/list_item_hunter.js +++ b/builder/list_item_hunter.js @@ -49,8 +49,17 @@ var thisBlockTemplate = repeatedBlockTemplate[i]; var thisBlockHTML = ""; + //check for a local listitems.json file + // var patternSpecificListJson = {}; + // try { + // patternSpecificListJson = abspath.substr(0, abspath.lastIndexOf(".")) + "listitems.json"; + // currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); + // } + // catch(e) { + // } + //combine listItem data with pattern data with global data - var itemData = patternlab.listitems['' + items.indexOf(loopNumberString)]; //this is a propety + var itemData = patternlab.listitems['' + items.indexOf(loopNumberString)]; //this is a property var globalData = JSON.parse(JSON.stringify(patternlab.data)); var localData = JSON.parse(JSON.stringify(pattern.jsonFileData)); @@ -61,11 +70,9 @@ //check for partials within the repeated block var foundPartials = pattern_assembler.find_pattern_partials({ 'template' : thisBlockTemplate }); - if(foundPartials.length > 0){ + if(foundPartials && foundPartials.length > 0){ for(var j = 0; j < foundPartials.length; j++){ - //add the lineage once for the parent pattern - //TODO //get the partial var partialName = foundPartials[j].match(/([a-z-]+)/ig)[0]; @@ -73,7 +80,6 @@ //replace its reference within the block with the extended template thisBlockTemplate = thisBlockTemplate.replace(foundPartials[j], partialPattern.extendedTemplate); - } //render with data diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index 674b42b18..c6ffb3d98 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -65,7 +65,7 @@ //extract some information var abspath = file.substring(2); - var subdir = path.dirname(path.relative('./source/_patterns', file)).replace('\\', '/'); + var subdir = path.dirname(path.relative(patternlab.config.patterns.source, file)).replace('\\', '/'); var filename = path.basename(file); //ignore _underscored patterns, json (for now), and dotfiles diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js new file mode 100644 index 000000000..501a22a44 --- /dev/null +++ b/test/list_item_hunter_tests.js @@ -0,0 +1,150 @@ +(function () { + "use strict"; + + var lih = require('../builder/list_item_hunter'); + + exports['list_item_hunter'] = { + 'process_list_item_partials finds and outputs basic repeating blocks' : function(test){ + //arrange + //setup current pattern from what we would have during execution + var currentPattern = { + "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "key": "test-patternName", + "jsonFileData" : {} + }; + + var patternlab = { + "listitems": { + "1": [ + { + "title": "Foo" + } + ], + "2": [ + { + "title": "Foo" + }, + { + "title": "Bar" + } + ] + }, + "data": { + "link": {}, + "partials": [] + }, + "config": {"debug": false} + }; + + var list_item_hunter = new lih(); + + //act + list_item_hunter.process_list_item_partials(currentPattern, patternlab); + + //assert + test.equals(currentPattern.extendedTemplate, "FooBar" ); + + test.done(); + }, + + 'process_list_item_partials finds partials and outputs repeated renders' : function(test){ + //arrange + //setup current pattern from what we would have during execution + var currentPattern = { + "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", + "key": "test-patternName", + "jsonFileData" : {} + }; + + var patternlab = { + "listitems": { + "1": [ + { + "title": "Foo" + } + ], + "2": [ + { + "title": "Foo" + }, + { + "title": "Bar" + } + ] + }, + "data": { + "link": {}, + "partials": [] + }, + "config": {"debug": false}, + "patterns": [ + { + "template": "{{ title }}", + "extendedTemplate" : "{{ title }}", + "key": "test-simple", + "jsonFileData" : {} + } + ] + }; + + var list_item_hunter = new lih(); + + //act + list_item_hunter.process_list_item_partials(currentPattern, patternlab); + + //assert + test.equals(currentPattern.extendedTemplate, "FooBar" ); + + test.done(); + }, + + //TODO + //'process_list_item_partials overwrites listItem data if local .listitem.json is found' : function(test){ + // //arrange + // //setup current pattern from what we would have during execution + // var currentPattern = { + // "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + // "extendedTemplate" : "{{#listItems.two}}{{ title }}{{/listItems.two}}", + // "key": "test-patternName", + // "jsonFileData" : {} + // }; + + // var patternlab = { + // "listitems": { + // "1": [ + // { + // "title": "Foo" + // } + // ], + // "2": [ + // { + // "title": "Foo" + // }, + // { + // "title": "Bar" + // } + // ] + // }, + // "data": { + // "link": {}, + // "partials": [] + // }, + // "config": {"debug": true} + // }; + + // var list_item_hunter = new lih(); + + // //act + // list_item_hunter.process_list_item_partials(currentPattern, patternlab); + + // //assert + // test.equals(currentPattern.extendedTemplate, "FooBar" ); + + // test.done(); + //}, + + }; + +}()); From 192b87f2e84afbf589770e1594461dfa9187c351 Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Tue, 25 Aug 2015 23:31:26 -0500 Subject: [PATCH 8/9] patterspecific.listitems.json support unit tests for list_item_hunter.js CHANGELOG and package for v0.11.0 --- CHANGELOG | 1 + builder/lineage_hunter.js | 2 +- builder/list_item_hunter.js | 19 ++---- builder/media_hunter.js | 2 +- builder/object_factory.js | 2 +- builder/parameter_hunter.js | 2 +- builder/pattern_assembler.js | 16 ++++- builder/pattern_exporter.js | 2 +- builder/patternlab.js | 2 +- builder/patternlab_grunt.js | 2 +- builder/pseudopattern_hunter.js | 2 +- package.json | 2 +- test/list_item_hunter_tests.js | 101 +++++++++++++++++++------------- 13 files changed, 88 insertions(+), 67 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e9891025c..85124e76e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,7 @@ THIS CHANGELOG IS AN ATTEMPT TO DOCUMENT CHANGES TO THIS PROJECT. PL-node-v0.11.0 - ADD: Ignore pattern directories that start with an underscore. + - ADD: Support for lists with the listItems variable - FIX: Resolved issue where pattern parameter data bled into global data object - ADD: Support a fluid viewport diff --git a/builder/lineage_hunter.js b/builder/lineage_hunter.js index bb072bf74..47bc9c473 100644 --- a/builder/lineage_hunter.js +++ b/builder/lineage_hunter.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/list_item_hunter.js b/builder/list_item_hunter.js index a15e1ef26..dd251bda3 100644 --- a/builder/list_item_hunter.js +++ b/builder/list_item_hunter.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. @@ -31,8 +31,6 @@ //find the boundaries of the block var loopNumberString = liMatch.split('.')[1].split('}')[0].trim(); - - //find the boundaries of the block var end = liMatch.replace('#', '/'); var patternBlock = pattern.template.substring(pattern.template.indexOf(liMatch) + liMatch.length, pattern.template.indexOf(end)).trim(); @@ -43,23 +41,18 @@ repeatedBlockTemplate.push(patternBlock); } + //check for a local listitems.json file + var listData = JSON.parse(JSON.stringify(patternlab.listitems)); + listData = pattern_assembler.merge_data(listData, pattern.patternSpecificListJson); + //iterate over each copied block, rendering its contents along with pattenlab.listitems[i] for(var i = 0; i < repeatedBlockTemplate.length; i++){ var thisBlockTemplate = repeatedBlockTemplate[i]; var thisBlockHTML = ""; - //check for a local listitems.json file - // var patternSpecificListJson = {}; - // try { - // patternSpecificListJson = abspath.substr(0, abspath.lastIndexOf(".")) + "listitems.json"; - // currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); - // } - // catch(e) { - // } - //combine listItem data with pattern data with global data - var itemData = patternlab.listitems['' + items.indexOf(loopNumberString)]; //this is a property + var itemData = listData['' + items.indexOf(loopNumberString)]; //this is a property like "2" var globalData = JSON.parse(JSON.stringify(patternlab.data)); var localData = JSON.parse(JSON.stringify(pattern.jsonFileData)); diff --git a/builder/media_hunter.js b/builder/media_hunter.js index 3900d81ed..289a78bb9 100644 --- a/builder/media_hunter.js +++ b/builder/media_hunter.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/object_factory.js b/builder/object_factory.js index 1e632d17b..6725abe75 100644 --- a/builder/object_factory.js +++ b/builder/object_factory.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/parameter_hunter.js b/builder/parameter_hunter.js index 5b7c0d3b4..089b80055 100644 --- a/builder/parameter_hunter.js +++ b/builder/parameter_hunter.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/pattern_assembler.js b/builder/pattern_assembler.js index c6ffb3d98..98b661783 100644 --- a/builder/pattern_assembler.js +++ b/builder/pattern_assembler.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. @@ -81,12 +81,22 @@ //look for a json file for this template try { - var jsonFilename = abspath.substr(0, abspath.lastIndexOf(".")) + ".json"; - currentPattern.jsonFileData = fs.readJSONSync(jsonFilename); + var jsonFilename = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".json"; + currentPattern.jsonFileData = fs.readJSONSync(jsonFilename.substring(2)); + console.log('found pattern-specific data.json for ' + currentPattern.key); } catch(e) { } + //look for a listitems.json file for this template + try { + var listJsonFileName = patternlab.config.patterns.source + currentPattern.subdir + '/' + currentPattern.fileName + ".listitems.json"; + currentPattern.patternSpecificListJson = fs.readJSONSync(listJsonFileName.substring(2)); + console.log('found pattern-specific listitems.json for ' + currentPattern.key); + } + catch(e) { + } + //add the raw template to memory currentPattern.template = fs.readFileSync(abspath, 'utf8'); diff --git a/builder/pattern_exporter.js b/builder/pattern_exporter.js index 61f62cccf..78560b631 100644 --- a/builder/pattern_exporter.js +++ b/builder/pattern_exporter.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/patternlab.js b/builder/patternlab.js index ff409887a..d819cff43 100644 --- a/builder/patternlab.js +++ b/builder/patternlab.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/patternlab_grunt.js b/builder/patternlab_grunt.js index a79854e6f..72fccc8ff 100644 --- a/builder/patternlab_grunt.js +++ b/builder/patternlab_grunt.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/builder/pseudopattern_hunter.js b/builder/pseudopattern_hunter.js index b2b74a125..b5513e458 100644 --- a/builder/pseudopattern_hunter.js +++ b/builder/pseudopattern_hunter.js @@ -1,5 +1,5 @@ /* - * patternlab-node - v0.10.1 - 2015 + * patternlab-node - v0.11.0 - 2015 * * Brian Muenzenmeyer, and the web community. * Licensed under the MIT license. diff --git a/package.json b/package.json index 91df44efb..8e0a247ad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "patternlab-node", "description": "Pattern Lab is a collection of tools to help you create atomic design systems. This is the node command line interface (CLI).", - "version": "0.10.1", + "version": "0.11.0", "devDependencies": { "grunt": "~0.4.0", "grunt-contrib-watch": "^0.6.1", diff --git a/test/list_item_hunter_tests.js b/test/list_item_hunter_tests.js index 501a22a44..0da3c9288 100644 --- a/test/list_item_hunter_tests.js +++ b/test/list_item_hunter_tests.js @@ -100,50 +100,67 @@ test.done(); }, - //TODO - //'process_list_item_partials overwrites listItem data if local .listitem.json is found' : function(test){ - // //arrange - // //setup current pattern from what we would have during execution - // var currentPattern = { - // "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", - // "extendedTemplate" : "{{#listItems.two}}{{ title }}{{/listItems.two}}", - // "key": "test-patternName", - // "jsonFileData" : {} - // }; - - // var patternlab = { - // "listitems": { - // "1": [ - // { - // "title": "Foo" - // } - // ], - // "2": [ - // { - // "title": "Foo" - // }, - // { - // "title": "Bar" - // } - // ] - // }, - // "data": { - // "link": {}, - // "partials": [] - // }, - // "config": {"debug": true} - // }; - - // var list_item_hunter = new lih(); - - // //act - // list_item_hunter.process_list_item_partials(currentPattern, patternlab); + 'process_list_item_partials overwrites listItem data if local .listitem.json is found' : function(test){ + //arrange + //setup current pattern from what we would have during execution + var currentPattern = { + "template": "{{#listItems.two}}{{ title }}{{/listItems.two}}", + "extendedTemplate" : "{{#listItems.two}}{{> test-simple }}{{/listItems.two}}", + "key": "test-patternName", + "jsonFileData" : {}, + "patternSpecificListJson" : { + "2": [ + { + "title": "One" + }, + { + "title": "Two" + }, + ] + } + }; + + var patternlab = { + "listitems": { + "1": [ + { + "title": "Foo" + } + ], + "2": [ + { + "title": "Foo" + }, + { + "title": "Bar" + } + ] + }, + "data": { + "link": {}, + "partials": [] + }, + "config": {"debug": false}, + "patterns": [ + { + "template": "{{ title }}", + "extendedTemplate" : "{{ title }}", + "key": "test-simple", + "jsonFileData" : {} + } + ] + }; + + var list_item_hunter = new lih(); + + //act + list_item_hunter.process_list_item_partials(currentPattern, patternlab); - // //assert - // test.equals(currentPattern.extendedTemplate, "FooBar" ); + //assert + test.equals(currentPattern.extendedTemplate, "OneTwo" ); - // test.done(); - //}, + test.done(); + } }; From 31b4dfc9dfe85bedef3b3f1fb432217cd24b0c6c Mon Sep 17 00:00:00 2001 From: BRIAN MUENZENMEYER Date: Tue, 25 Aug 2015 23:43:34 -0500 Subject: [PATCH 9/9] readme reorg - mention the roadmap --- README.md | 72 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 294871070..c72b197a6 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,40 @@ Pattern states should be lowercase and use hyphens where spaces are present. } ``` +##### Pattern Export +`config.json` also has two properties that work together to export completed patterns for use in a production environment. Provide an array of keys and an output directory. Pattern Lab doesn't ship with any pattern export keys, but the default directory is `"./pattern_exports/"` created inside the install directory. + +``` +"patternExportKeys": ["molecules-primary-nav", "organisms-header", "organisms-header"], +"patternExportDirectory": "./pattern_exports/" +``` + +Coupled with exported css (much easier to extract with existing tools like [grunt-contrib-copy](https://github.com/gruntjs/grunt-contrib-copy)), pattern export can help to maintain the relevancy of the design system by directly placing partials in a directory of your choosing. + +##### baseurl + +If your instance of Pattern Lab lives in a subdirectory of your server, for instance on github pages (ex: yourusername.github.io/patterns-demo/), then add the baseurl here. The baseurl is everything after the hostname - ie: `patterns-demo` + +``` +"baseurl" : "/patterns-demo" +``` + +Default: blank + +##### excluding patterns + +If you'd like to exclude an individual pattern you can do so by prepending the filename with an underscore, like: `_filename.mustache` + +You can also exclude complete directories by prepending the directory name with an underscore, like: `/_experiment/...` + +##### Verbose Mode +`patternlab.json` is a file created for debugging purposes. Set `debug` to true in `.config.json` to see all the secrets. + +##### Server +Running `grunt serve` will compile the patternlab front end and host it on http://localhost:9001 by default. Page will reload on any saved source code change. + +### Advanced Pattern Library Features + ##### Pattern Parameters Pattern parameters are a simple mechanism for replacing Mustache variables via attributes on a pattern partial tag rather than having to use a pattern-specific json file. They are especially useful when you want to supply distinct values for Mustache variables in a specific pattern partial instance that may be included multiple times in a molecule, template, or page. @@ -157,38 +191,6 @@ This would compile to: As you can see, it's a much easier way of linking patterns to one another. -##### Pattern Export -`config.json` also has two properties that work together to export completed patterns for use in a production environment. Provide an array of keys and an output directory. Pattern Lab doesn't ship with any pattern export keys, but the default directory is `"./pattern_exports/"` created inside the install directory. - -``` -"patternExportKeys": ["molecules-primary-nav", "organisms-header", "organisms-header"], -"patternExportDirectory": "./pattern_exports/" -``` - -Coupled with exported css (much easier to extract with existing tools like [grunt-contrib-copy](https://github.com/gruntjs/grunt-contrib-copy)), pattern export can help to maintain the relevancy of the design system by directly placing partials in a directory of your choosing. - -##### baseurl - -If your instance of Pattern Lab lives in a subdirectory of your server, for instance on github pages (ex: yourusername.github.io/patterns-demo/), then add the baseurl here. The baseurl is everything after the hostname - ie: `patterns-demo` - -``` -"baseurl" : "/patterns-demo" -``` - -Default: blank - -##### excluding patterns - -If you'd like to exclude an individual pattern you can do so by prepending the filename with an underscore, like: `_filename.mustache` - -You can also exclude complete directories by prepending the directory name with an underscore, like: `/_experiment/...` - -##### Verbose Mode -`patternlab.json` is a file created for debugging purposes. Set `debug` to true in `.config.json` to see all the secrets. - -##### Server -Running `grunt serve` will compile the patternlab front end and host it on http://localhost:9001 by default. Page will reload on any saved source code change. - === The Node version of Pattern Lab is maintained by [@bmuenzenmeyer](https://twitter.com/bmuenzenmeyer) and contributors. Pull requests welcome, but please take a moment to read the [guidelines](https://github.com/pattern-lab/patternlab-node/blob/master/CONTRIBUTING.md). @@ -197,9 +199,11 @@ The Node version of Pattern Lab is maintained by [@bmuenzenmeyer](https://twitte You can find some simple upgrade documenation in it's current home here (unreleased but confirmed to work): [https://github.com/pattern-lab/website/blob/dev/patternlabsite/docs/node/upgrading.md](https://github.com/pattern-lab/website/blob/dev/patternlabsite/docs/node/upgrading.md) -### Forward, To the Specification! +### ROADMAP + +A roadmap exists for Pattern Lab Node. Check it out [here](https://github.com/pattern-lab/patternlab-node/issues/134) -Dave Olsen has published the [specification](https://github.com/pattern-lab/the-spec/blob/draft/SPEC.md) for Pattern Lab ports. Development will be oriented toward compliance with this as the spec and the port mature together. +Dave Olsen has also published the [specification](https://github.com/pattern-lab/the-spec/blob/draft/SPEC.md) for Pattern Lab ports. Development will be oriented toward compliance with this as the spec and the port mature together. ### Is Pattern Lab a Platform or a Build Tool?