Web development

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!

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.

Ludum Dare 28 – Make a game in 48 hours

Ludum Dare is an event where people all around the world attempt to make a game in 48 hours, based on a theme voted on and announced at the start of the competition. There are no prizes, it’s more of a challenge to generate ideas and get people to make games.

I’ve wanted to participate in Ludum Dare for a couple years now and it just happened to fall on a completely free weekend for me this time, so I made my first HTML5 game.

Well, I consider it a prototype at this point. I used an HTML5 framework called Phaser, which I’ve had my eye on for awhile but haven’t worked with before. I spent a ton of time learning the framework through the excellent documentation and examples on the Phaser website.

I feel it was a success as now I have a working game prototype, instead of just a vague idea in my head. There is plenty of work to do but I feel it was definitely a worthwhile way to blow a weekend.

Check out my entry on the Ludum Dare website here:

http://www.ludumdare.com/compo/ludum-dare-28/?action=preview&uid=15070

 

P.S. – I’m running off about 10 hours of sleep over the weekend, please excuse the rambling nature of this post.

Setting up a TLD for local web development in Ubuntu

Like any good developer, I have a local LAMP server set up so I can develop locally before pushing a site or app to a live production site. This allows me to completely test any modifications to the code base and helps minimize and prevent any possible bugs once the site is live. Once everything is well tested and good to go, I can easily push to production, test again, and be confident everything is working correctly.

My development server is a 64-bit Debian Server running inside a VirtualBox VM on my desktop PC. I run Ubuntu based Linux distributions on all my PC’s, so I could install a LAMP stack on any of them, but I prefer to keep it separated. By using a virtual machine I can more closely emulate the most common server I deploy to, which also minimizes any bugs I might run in to.

So what does all this have to do with setting up a local development top level domain?

Well, my standard process has always been something like this:

  1. Create a directory for project on local server
  2. Set up new virtual host in Apache (usually ‘project.dev’)
  3. Update /etc/hosts file to point ‘project.dev’ to virtual machine’s ip

That works fine, but I have to add project.dev to any computer on the network that I want to be able to access the .dev site. It’s one of those things that I just have been doing for so long that I do it unconsciously. As a developer, I’m always looking for ways to streamline processes and be more efficient.

Enter dnsmasq

What I want is to make the .dev TLD always point to my virtual machine. Wildcards are not supported in your /etc/hosts file on Linux, so we’ll use dnsmasq.

Dnsmasq is a lightweight, easy to configure DNS forwarder and DHCP server.

You can set up dnsmasq on all the local computers on your network to make them all hit your development VM for all request to *.dev.

If dnsmasq is not already installed on your Ubuntu based distro, a simple ‘sudo apt-get install dnsmasq’ will do.

Next, edit /etc/dnsmasq.conf and add this one line:

address=/.dev/172.24.35.130

Where 172.24.35.130 is the ip of your VM. My VM is exposed with a bridged connection to allow it open access to the internet and the local network.

You may need to restart network-manager & dnsmasq:

sudo service network-manager restart
sudo service dnsmasq restart

And you’re good to go. Now you can clean out that /etc/hosts file you’ve been piling domains on.

This is a simple, easy, and somewhat obvious fix, but sometimes you get into a routine and forget to check if your processes can be optimized.