Blog

Working with data in Pattern Lab using Handlebars templates

We often use the node version of Pattern Lab over at Wirestream to scaffold out sites before integrating front-end assets into a CMS. It’s a great static site builder that allows our interactive development team to build out separate components, combine them into full templates/pages and work out all the bugs before they get integrated into a CMS.

Working data files into the components allows us to think about how the components will be used and  work out any edge cases. This causes a bit of a learning curve for UI developers that aren’t accustomed to working with JSON data and thinking in customizability for a CMS. So, here are some of the basics of working with JSON data in Pattern Lab, using handlebars templating.

The Set Up

Just a note that the file structure I’ll be referring to isn’t the traditional atoms, molecules, organisms etc. I’ve using a more stripped down elements-components-templates structure. You can restructure your patterns and call them whatever you choose based on your project requirements and pattern lab doesn’t care.

Data Location

Data can be pulled from multiple locations for each component (or element, atom, molecule, whatever your naming convention may be). The data will only show on the level you’ve placed the JSON file. I prefer component or template level data as opposed to one giant global data file. This may require some duplication but feels easier to maintain.

Taking a bootstrap ‘Jumbotron’ component as an example, if the component and data file are placed here:

Folder Screenshot

The data will pull into the jumbotron component only when viewed on the components page in patternlab, here:

Screen Shot 2017-05-29 at 6.03.41 PM

If we create a template and include the jumbotron, it will not contain the data.

Screen Shot 2017-05-29 at 6.07.33 PMScreen Shot 2017-05-29 at 6.10.25 PMThe home template needs it’s own data file (home.json) in the same folder in order to populate the jumbotron data.

Adding the data

So what’s hardcoded and what’s data? Anything customizable in the CMS this markup eventually lands in, should be pulled from a json file.

Taking the jumbotron as an example, let’s say the title, paragraph, and link are all customizable. We’ll replace all those with handlebars expressions. So this:

<div class="jumbotron">
 <h1>Heading</h1>
 <p>Jumbotron Text</p>
 <p><a class="btn btn-primary btn-lg" href="/buy-it" role="button">CTA Button</a></p>
</div>

becomes this:

<div class="jumbotron">
 <h1>{{heading}}</h1>
 <p>{{content}}</p>
 <p><a class="btn btn-primary btn-lg" href="{{href}}" role="button">{{ctaText}}</a></p>
</div>

and the home.json file would look like this:

Screen Shot 2017-05-29 at 6.31.41 PM

{
 "heading": "Jumbotron Heading",
 "content": "This is a Jumbotron!",
 "href": "www.google.com",
 "ctaText": "Click me or else."
}

Screen Shot 2017-05-29 at 6.32.44 PM

Getting Loopy

What if there is a requirement that there can be multiple CTA buttons? In order to mock that up, it’s as easy as using a handlebars {{#each}}{{/each}} expression and an array in the JSON data.

jumbotron.hbs:

<div class="jumbotron">
 <h1>{{heading}}</h1>
 <p>{{content}}</p>
 {{#each ctas}}
 <p><a class="btn btn-primary btn-lg" href="{{href}}" role="button">{{ctaText}}</a></p>
 {{/each}}
</div>

home.json:

{
 "heading": "Jumbotron Heading",
 "content": "This is a Jumbotron!",
 "ctas": [
 {
 "ctaText": "Click me or else.",
 "href": "www.google.com"
 },
 {
 "ctaText": "No, click me!",
 "href": "www.yahoo.com"
 },
 {
 "ctaText": "Don't click me.",
 "href": "www.bing.com"
 }
 ]
}

Screen Shot 2017-05-29 at 6.43.39 PM

I’ve added a “ctas” array to the data, which is an array of objects. Each object includes the ctaText and href.  I then loop over the array in the jumbotron.hbs file with a handlebars each expression.

Conditions – if this show this

What if the content, currently set to “This is a Jumbotron”, is optional? This is where the handlebars {{#if}} {{/if}} expression becomes useful. We don’t want to output the paragraph tag if there’s no content, so we can simply wrap it in an if condition.

jumbotron.hbs:

<div class="jumbotron">
 <h1>{{heading}}</h1>
 {{#if content}}
 <p>{{content}}</p>
 {{/if}}
 {{#each ctas}}
 <p><a class="btn btn-primary btn-lg" href="{{href}}" role="button">{{ctaText}}</a></p>
 {{/each}}
</div>

home.json:

{
 "heading": "Jumbotron Heading",
 "ctas": [
 {
 "ctaText": "Click me or else.",
 "href": "www.google.com"
 },
 {
 "ctaText": "No, click me!",
 "href": "www.google.com"
 },
 {
 "ctaText": "Don't click me.",
 "href": "www.google.com"
 }
 ]
}

Screen Shot 2017-05-29 at 6.56.32 PM

But, what if I don’t want to keep deleting and adding properties to test different variations of one component?

Variations

Pattern Lab includes something called Pseudo-Patterns in order to create variations of patterns.

All we have to do is duplicate the data file, home.json and add the variation name after the template name, separated by a tilde.

Screen Shot 2017-05-29 at 7.02.42 PM

And now Pattern Lab will be updated to include the new variation:

Screen Shot 2017-05-29 at 7.04.21 PM

Conclusion

As you can see, Pattern Lab is very powerful, but also very complex. Using Pattern Lab allows us to work more efficiently and avoid a lot of duplicated markup. It also allows us to quickly update templates or components with data in order to test UI bugs and edge cases, often quicker than working with code already integrated into a CMS.

This astronaut just wants a friend! A Ludum Dare Post-mortem

Another Ludum Dare came and went and I managed to (mostly) complete a little HTML5 minigame. I didn’t really hit crunch time until the last few hours of the jam, and wasted far too much time during the compo not programming.  I’ve gotten to the point that I’m pretty comfortable with Phaser.js, and am able to spend more time figuring out game mechanics.

In ‘With Kindness’, you play a lonely astronaut, stranded on a far away planet. All he wants is to make some new friends. There are many aliens on the planet, that constantly spit acid at you, but maybe, just maybe, if you give them a good hug they will become your friend!

With Kindness Screenshot

I was initially uninspired by the theme, ‘An Unconventional Weapon’, but managed to come up with a decent idea. Though, while rating other games during the judging phase I came across a few other games also using hugging as a weapon.

I’ve been wanting to play around with making some kind of a beat-em-up style game, and used this Ludum Dare to explore and learn some of the challenges I’d run into. Probably the most difficult involved splitting one sprite into multiple sprites in order to layer them, and provide better collision detection.

With Kindness Sprites
A small selection of sprites from With Kindness

I attempted to keep the astronaut and the alien sprites separate, so I’d be able to separate both their animation, but ultimately ended up having to attach the alien to the astronaut sprite when they’re hugging. Time is always the enemy during Ludum Dare and I spent most of the time creating the astronaut sprite frames and trying to figure out how to position and layer them correctly.

I used the gulp config to build a texture atlas I’ve written about previously, which saved a massive amount of time (at least it felt like it) compared to having to manually create and update the atlas.

I only wish I’d saved some time to add some sound effects and music.  I think a super happy pop melody would really complete the experience, but I don’t see much of a future beyond that for the game.

Check out the Ludum Dare entry or Play the game directly. Feel free to check out the With Kindness Source Code, but as is standard for a 48 hour game jam, things got a little sloppy towards the end.

And since I forgot in-game instructions:

WASD or Arrow keys to move around, F key to initiate hug, continue pressing F to hug even harder!

Exploding sprites with Phaser.js and Shatter.js

I’ve been working on increasing Crash Landing‘s juiciness and one of my first tasks was to make the ground beneath the player explode into pieces. It’s been a great opportunity to  get some use out of Shatter.js.

It wasn’t completely straightforward to figure out how to access the raw image data in order to feed it to Shatter.js, and how to best provide the shattered image back to Phaser. Since I’m loading the sprites from a sprite atlas I need to extract the individual sprite I want to shatter to it’s own image. I could also just load the images individually, but I really wanted to keep the sprite atlas and not load duplicate images.

Next I created a sprite group to contain all the shattered pieces, with each shattered piece placed in it’s correct spot so that when the group is rendered it still visually appears as one object. Then we can interact with the group as a whole and also each sprite individually. To make them explode I just loop through all of them and a random x and y velocity.

Most of the magic is all in ShatterSprite.js which I’ve heavily commented below:


CrashLanding.Util.ShatterSprite = function ShatterSprite(game, key, frame) {
    var numberOfSprites = 12; // make 12 sprites from frame
    var offCanvas = -1000; // constant to create sprites outside of game canvas

    function getImageFromSprite(game, key, frame) {
       // temp sprite used for extraction
       var sprite = game.add.sprite(offCanvas, offCanvas, key, frame);
       // create a canvas to draw the sprite to with Phaser's bitmapData method
       var bmd = game.add.bitmapData(sprite.width, sprite.height);
       // create an image and set the image data, and clean up
       var image = new Image();
       bmd.draw(sprite, 0, 0, sprite.width, sprite.height);
       bmd.update();
       sprite.destroy();
       image.src = bmd.canvas.toDataURL();
       return image;
    }
    
    // Create a phaser group out of a Shatter object
    function createShatteredGroup(game, shatteredImage) {
       var shatteredGroup = game.add.group();
       // Shatter.js returns the new images in an array at Shatter.images, here we loop through all of them
       shatteredImage.images.forEach(function(image, ind, arr) {
          // create a key for the using the same name as the frame of the original sprite + its position in the array of shattered images
          var key = frame + ind;
          // add it to the game cache, so we can add it to the new sprite group
          game.cache.addImage(key, null, image.image);
          var sprite = shatteredGroup.create(offCanvas, offCanvas, key);
          // save the sprites offset so we can place it properly when drawing the groupp
          sprite.originX = image.x;
          sprite.originY = image.y;
          game.physics.arcade.enable(sprite);
          // for the shattered ground objects I only check down collision. Need to move this out and pass in.
          sprite.body.checkCollision.left = false;
          sprite.body.checkCollision.right = false;
          sprite.body.checkCollision.up = false;
       });
       return shatteredGroup;
    }

    return createShatteredGroup(game,
       new Shatter(getImageFromSprite(game, key, frame), numberOfSprites));
}

Once I’ve created my sprite group I can use it to replace sprites/tiles on the screen.  The ground exploding awesomeness takes place in the appropriately named Ground.js. Below, ‘exploder’ is the shattered sprite group and oldTile is the tile I’ve decided to remove from the game world.


oldTile = game.level1map.removeTileWorldXY(removeX, groundLevel, tileWidth, tileHeight);
       // I'm randomly removing tiles, so I make sure there was a tile removed
       if (typeof oldTile != 'undefined') {
          // set shattered group to the previous location of the tile
          exploder.x = oldTile.worldX;
          exploder.y = oldTile.worldY;
          // add each piece at it's proper location within the group and give it some velocity
          exploder.children.forEach(function(sprite) {
             sprite.x = sprite.originX;
             sprite.y = sprite.originY;
             sprite.body.velocity.x = game.rnd.integerInRange(xVelocityMin, xVelocityMax);
             sprite.body.velocity.y = game.rnd.integerInRange(yVelocityMin, yVelocityMax);
          });

There are plenty of improvements we could make, but I think this provides a decent example of how to use Shatter.js with Phaser.js.

Using gulp to automate texture atlas and sprite sheet creation for Phaser

I’ve always used TexturePacker to create texture atlases for Phaser. It’s an awesome visual tool that’s really easy to use to create atlases and sprite sheets, but I’m a command line guy and always looking to save time and be more efficient.

While I’ve been working on Crash Landing, I hesitate to update or add new sprites because of the pain of having to go through all the steps to update or add a sprite. It may sound a bit silly, but it really is time consuming having to open up the program, load the old atlas, add or update it and save it back out. I’d rather spend this time coding, or creating new sprites. My dislike for this process makes me not want to create new sprites and iterate quickly.

I first looked into automating TexturePacker, which does have a command line interface, but at the same time being a standalone program I’d have to write a bash script to automate the process, or find a gulp package to interact with the command line (seems a little messy). I plan on building a full workflow for automating more tasks using Gulp, so I did a little research and found a working implementation using existing Node.js packages.

gulp.spritesmith and spritesmith-texturepacker

gulp.spritesmith is a gulp plugin for spritesmith, a node utility to create spritesheets, and spritesmith-texturepacker is an export template for spritesmith to create a .json file compatible with TexturePacker, and thus Phaser.

So let’s get to it. If you’re familiar with gulp already it’s pretty simple to set up. I’m assuming you’ve got npm and are familiar with installing packages. You’ll need gulp in your project, both spritesmith packages above, and I’m also using imagemin to optimize the resulting atlas image file.


npm install --save-dev gulp gulp-spritesmith spritesmith-texturepacker gulp-imagemin

Once installed we just need to create our gulp file with a task to create the texture atlas image and json file.


var gulp = require('gulp');
var spritesmith = require('gulp.spritesmith');
var imagemin = require('gulp-imagemin');
var texturepacker = require('spritesmith-texturepacker');

gulp.task('sprites', function() {
    var spriteData = gulp.src('src/images/sprites/*.png')
        .pipe(spritesmith({
            imgName: 'sprites.png',
            cssName: 'sprites.json',
            algorithm: 'binary-tree',
            cssTemplate: texturepacker
    }));
    spriteData.img.pipe(imagemin()).pipe(gulp.dest('build/images/'));
    spriteData.css.pipe(gulp.dest('build/images'));
});

I’ve created a task (sprites) that pulls all .png files from the src directory, pipes it into spritesmith with the texturepacker template. I save the return value of the operation to spriteData, and individually pipe them out so I can run the image through imagemin.

Now anytime I need to add or update a sprite, I just drop it into the source file and run ‘gulp sprites’.

The .json file outputted will be in JSON hash format. In order to load the spritesheet into a Phaser project you’ll use the atlasJSONHash method. I’m using this:


this.load.atlasJSONHash('sprites', 'build/images/sprites.png', 'build/images/sprites.json');

Each image is saved as a frame in the .json file. You’ll refer to it by the filename minus the extension. As an example, I’m loading the standing.png frame into my player class with the following:


Phaser.Sprite.call(this, game, x, y, 'sprites', 'standing');

So there it is, a simple way to speed up your workflow. Works great if you like to incrementally build out you’re Phaser game like I do.

Chrome Developer Tools Tips

I spend a lot of time working in Chrome’s DevTools, so I’m always trying to learn new tricks to help speed up and optimize my workflow. The DevTools are and enormous and always being enhanced with each Chrome release, so there is always plenty to learn.

Here are a couple recent resources I found useful:

DevTools Tips

A collections of quick DevTools tips. Using copy() to store an object (as a string representation per the documentation) could be useful.

Advanced Debugging Techniques with Chrome

In this video Paul Irish, developer advocate for Chrome, covers some advanced debugging features that are available now, and a few interesting features coming soon. He gives the talk at light speed, it’s more of an overview, but left me with a good amount of things to research.

Stuff I found Interesting (July 2014)

The Graphing Calculator Story – This is an awesome talk about a couple software developers that didn’t give up after their project was cancelled.

Hacks for dealing with specificity [in CSS] – Did you know you can chain a selector with itself to increase specificity? This could definitely come in handy for quick fixes or systems that you don’t have complete control over.

Things I didn’t know about CSS – The previous tip and more are discussed in the video linked on this page.

NoJS experiment – An experiment also mentioned in the previous link. The experiment is completely HTML & CSS- no JavaScript in sight.

Quick tip: Using Google trends and auto-complete to produce content

If you’re a small business with a website, writing articles or blogging is the best way to get some Google juice and attract more traffic to your website. Coming up with content idea’s related to your small business can sometimes be difficult though.

One of the best ways to keep a constant flow of content is to just keep focused on content during your everyday activities. Questions your customer ask, interactions with customers, and everyday research into your business are good starting points.

It’s important to keep a list and add to it immediately when an idea comes up for a new article or piece of content for your website. It’s very easy to become inspired and come up with tons of great ideas in an afternoon, only to forget them later that night. Pick up a list app or something similar for your phone to keep track, there are plenty on all the popular app marketplaces.

But, what about coming up with ideas on demand? Say you have some free time to up your content footprint on the web, but you’re fresh out of idea’s. One technique I’ve advised often is to use Google trends.

It’s as simple as going to Google trends, typing a phrase related to your business-which can be either generic or specific-and checking out the related searches.

Google Trends Screenshot - related coffee searches

Look over both the top and the rising searches, and if they’re too generic, try grabbing something from there and searching trends for it.

Google Trends Screenshot - coffee trends

Still having trouble finding something not too generic? Try using Google search auto-complete. When you begin typing in a search term, pay attention to the auto-complete suggestions. One of these might yield a great suggestion as a topic or for another Google trends mining search.

Google search screenshot - green coffee

You may even find looking through trends will spark an idea for something completely unrelated to your original search.

Stuff I found Interesting (June 2014)

An interesting article about ‘The Scroll Up Bar‘, a navigation trend on the web that has recently been becoming more popular. I’m a fan of this style as it really helps save some valuable screen space when browsing on devices.

Defensive BASH Programming – A load of techniques for BASH programming. I picked up a few good tips for cleaning up some BASH scripts I’ve written.

One Top Quest – A surprisingly entertaining web game considering how simple it is.

JSNice – A neat JavaScript deobfuscatator that uses statistical renaming of variables and attempts to guess type annotations. From the few examples I tried it seemed to do a decent job of making obfuscated code readable.

Human JavaScript – free online book about building browser apps.

What I found interesting this week (May 18th 2014)

WTF? Forms – A nice bit of css for some common form controls.

Digging, Debugging – This talk is loaded with great tips on debugging with Chrome devtools.

CCNA Training Videos – 88 videos covering CCNA training, crowd funded through Kickstarter and now available to stream free on YouTube.

Littlewargame – HTML5 rts game, amazing performance for an HTML5 game.

And there’s this: Cats and Dogs dressed as people, 100 years ago.