Read my book

I wrote books about Webpack and React. Check them out!

Thursday, January 31, 2013

Business Card Design Using CSS, cont.

You might remember an earlier post of mine in which I showed how to design your business card using some CSS. Converting the designs to printable images wasn't as straight-forward as I had hoped initially. I ended up zooming them up in my web browser and simply taking screengrabs. Thankfully I have a high resolution monitor to use.

I think a HTML to SVG converter might be another option. WebVector is an example of such. I have not given it a go personally but it might be an interesting alternative. I had no idea you could convert HTML to SVG.

I used a local printshop for the first round of cards. 30 cards cost me around 30 euros so it wasn't entirely cheap. They do print bigger series (think 400) quite affordably but we didn't need that much. As 30 wasn't enough I ordered the rest via Moo.

I have had good experiences with Moo before and this case wasn't an exception. In fact I accidentally forgot to flip other side of my card so they did that for me. The user interface has been designed horizontal layouts in mind so it was an easy thing to miss. I hope they fix this later on.

100 normal sized cards cost me around 18 euros (+ postage). The quality was great as expected. Bigger amounts are comparatively cheaper of course. I've grown fond of their minicards. And they are about to introduce NFC based alternative in the near future for the geekiest of us.

If you want to check out Moo, consider using my affiliate link. It will give you a nice 10% discount for your first order. They have other discounts going on quite regularly. I could not imagine ordering my cards from any other service. They are that good.

Oh, and to make this post less bland, here's a photo of the end result. The cards are a bit "stubbier" than in the initial layout but I can definitely live with that. I guess that had something to do with the fact I used American standard instead of European one. There appears to be a minor difference in their ratio.

Elovalo business cards

Friday, January 25, 2013

Book Review - Selenium Testing Tools Cookbook

Disclaimer: I received a digital review copy of this book from the publisher, Packt Publishing.

Selenium Testing Tools Cookbook by Unmesh Gundecha contains a massive amount of recipes. There are two digital bonus chapters even. It is clear this guy knows what he is talking about. The examples provided are comprehensive and straight to the point.

I didn't try out each example and skipped quite a few. That's the nature of cookbooks, though. Nobody expects you to go through each recipe. Apply and savor as needed.

Broad Selection of Recipes

The book starts out by describing how various selectors work in Selenium and then shows how you can use the API to mimic user actions. I wasn't particularly fond of the use of ids in various examples. I for one try to avoid those except in some quick hacks. Each to his own I guess.

There is information on more advanced concepts such as data-driven testing, performance testing, extending Selenium and HTML5 testing. I recommend checking out the full table of contents if you are interested in the exact topics covered.

Average Supplementary Material, No Highlighting 

I found it a bit disappointing that the supplementary material didn't contain the markup in which the book refers to. At times the examples referred to files at Dropbox. I don't think this is a particularly good strategy.

As an ebook reader I would have appreciated if the code examples would have been highlighted. I know it's a small thing but it makes a huge difference for code readability even though the examples were quite simple as-is.

Good Overview of Capabilities

To be honest I don't use Selenium a lot myself. The book actually gave me a better idea of its capabilities, though. While at it I found out there are some really nice bindings available for Node. These could come in handy one day.

Selenium is bound to be great for regression testing bigger services. Selenium Grid covered in an extra chapter in particular makes things easier as it allows you to run your tests through multiple browsers without any significant manual effort.

Conclusion

I wasn't entirely thrilled about the fact that most examples were based on Java. Fortunately the ideas are quite easy to transfer from platform to other. Besides there were times when examples were provided in multiple languages, perhaps excessively even.

Overall I was pleasantly surprised by the book. If you use Selenium actively you'll find this book invaluable. For others the value proposition is bit of so-so. You'll likely serve yourself better by picking up some other book aimed more towards beginners.

Sunday, January 20, 2013

Business Card Design Using CSS

I faced an interesting dilemma this morning. I had to design a business card for Elovalo. As of late I've grown really fond of JS Bin so I thought why not to give it a go using a bit of good ol' CSS. Apparently this isn't that bad a way to design. Sure CSS has its limitations but it isn't as bad a choice as you might think.

You can find a demo of possible results below. Note that the card is two-sided. The other side can be seen on hover. I know this doesn't work on iPad and such but I'm fine with that limitation. If someone's really interested, I suppose it's possible to hack up something that works using a bit of JavaScript.

Actual cards can be extracted for printing by first defining a print CSS (missing at the moment) and then exporting the result via web browser (print -> as pdf).

EDIT

It appears it isn't entirely trivial to set up print CSS. Particularly background images are troublesome. I did find out two handy properties: -webkit-print-color-adjust: exact; and content: url(...).

Instead of doing it this way it's probably preferably just to take a screen grab. Since we're using relative measures, we won't have any trouble scaling. Only the images may suffer a bit depending on their original quality.

Elovalo Business Card

Friday, January 18, 2013

GitHub + Markdown - a Great Combination for CVs

A while ago there was a popular topic about how to create a CV in LaTeX. Naturally I gave it a go. The resulting PDF looked just fine and I was quite happy with the results.

Today I wanted to convert my LaTeX into HTML so that I could host the CV easily. Sure the PDF can be hosted but it's not that nice to use in many cases. Besides you can convert your HTML into PDF simply by printing it.

Initially I thought this should be something that is very easy to do. Unfortunately pandoc appears to be broken at MacPorts currently. And I really didn't feel like fiddling with it so I decided to do something different.

I've always like Markdown as a format. So why not to use that and generate the HTML based on that? I took a good look at my PDF generated based on LaTeX and more or less replicated the results. While at it I came up with a custom addition to the language so that I could use definition lists. The basic syntax is very simple. It looks something like this: * Lion -- Lion is a big cat-like animal.

You can see my results at GitHub. Be sure to check out the resulting CV as well. I know it's far from the best CV in the world and probably could use some extra styling. But you have to start from somewhere. :)

Tuesday, January 15, 2013

Raspberry Pi as an Internet Radio

I own a Tivoli Model Two table radio. It's a great set. I'm particularly happy about the sound quality. Unfortunately it has been a pain to keep it in tune due to the amount of FM channels around. I have wanted to solve this problem for quite a while.

As I happened to have an extra Raspberry Pi around that got me thinking. What if turned that into an internet radio and then fed the audio to my Tivoli via its aux input? During my research I noticed several people (1, 2) have already done this.

It isn't entirely trivial to set up. You'll need some hardware and a little bit of software work to make it happen. Since I'm not entirely comfortable having a naked Pi around I bought a case from ModMyPi. While at it I bought a microSD adapter to avoid having an SD card jutting from the side. Obviously I needed to purchase a mini-stereo cable (male-male) to hook up the Pi with Tivoli.

Setting Up Raspberry Pi and SSH

If you are starting from scratch, you might want to study Engadget's surprisingly good article about how to set Raspberry Pi up. In order to make the Pi "headless", you'll want to set up SSH. The whole basic procedure goes like this:

  • Execute rm /etc/ssh/ssh_host_* && dpkg-reconfigure openssh-server at Pi. This is just a security precaution to avoid man in the middle type of attacks.
  • Figure out the IP address of your Pi using ifconfig. You should see multiple addresses there. In my setup I use a WLAN dongle so I needed to use its IP (192.168.something.something).
  • Connect to your Pi from some remote computer at your network using ssh raspi_ip -l pi. This assumes you'll be using the default account provided with Raspbian image.
  • To make it easier to connect, define an alias at ~/.ssh/config . The configuration should look something like this:
    • Host rpi 192.168.something.something
    • Hostname 192.168.something.something
    • User pi
  • To make it faster to connect (avoid password), set up a ssh key. You can achieve this using two commands. Use ssh-keygen on Pi side. In order to copy the key to your remote, use ssh-copy-id rpi . Note that this depends on the alias we just defined.

Installing Audio Dependencies

After you have SSH set up you'll need to install some dependencies required by audio. The following command should install all the needed ones. I've compiled this from various sources. Here we go: sudo apt-get install alsa-utils mpg321 lame mpd mpc .

In addition you'll likely want to configure the analog output (mini-stereo one) to be used. You can do this using amixer like this: amixer cset numid=3 1 .

Setting Up Streaming

Now we should have our audio set up. If you want to do some sanity check, curl a wav file to the Pi (curl some_address > test.wav) and play it (aplay test.wav). If everything went fine, you should hear a sound via your sound system. You should use an active system as the output of Pi is quite weak by default.

We still have to do one thing. We need to make it stream some radio channel. We can use mpc for this. Figure out the address of your channel (Shoutcast, Finnish Channels) and execute mpc add your_channel. To start the playback, just do mpc play . Obviously mpc stop works too.

Adding Support for pls and m3u Playlists

Sometimes it can be difficult to find a link to the stream fo the channel you happen to be interested in. Fortunately there is a way to configure mpd to accept pls and m3u. The following steps should suffice on Raspberry Pi:
  • cd /usr/share/doc/mpc/examples/
  • sudo cp mpd-* /usr/bin
  • cd /usr/bin
  • sudo chmod u+x mpd-*
Now you should have access to mpd-m3u-handler.sh and mpd-pls-handler.sh commands. These take a file argument. In order to get that file simply wget the m3u or pls (wget playlist.pls) of your radio station and pass it to the command.

Conclusion

I hope this brief post gave you an idea how to set up your Raspberry Pi to stream some radio channel. Now that we've got the basic set up done we can move into the interesting stuff. It would be nice to be able to control the whole thing via some kind of a web service for instance. Perhaps that would make a nice sequel to this post.

Friday, January 11, 2013

Minimal Split Reveal in CSS

I recently came by a post that showed how to implement a split reveal effect using some CSS and markup. Unfortunately the method seemed a tad too complex for me. I'm not particularly happy that you have to edit the images you want to use to. As a result I came up with perhaps a smarter way to achieve the same thing with minimal amount of markup and CSS.

My approach is based on the fact that you can use overflow: hidden; property to crop content. I simply set up a cropping container this way and animate the images inside that. I use some trickery to apply the same image to both and then offset them so that it looks like a split.

Here's the basic markup:
<div class="images">
  <div class="crop cat">
    <div class="upper image"></div>
    <div class="lower image"></div>
    <div class="content">Lol, cat!</div>
  </div>
  <div class="crop cattoo">
    <div class="upper image"></div>
    <div class="lower image"></div>
    <div class="content">Lol, cat!</div>
  </div>
</div>

And the CSS:
/* inspired by http://designshack.net/articles/css/perform-a-split-reveal-with-css/ */

/* images */
.cat.crop {
  width: 100px;
  height: 100px;
}
.cat.crop .image {
  background: url(http://placekitten.com/100/100);
}

.cattoo.crop {
  width: 300px;
  height: 200px;
}
.cattoo.crop .image {
  background: url(http://placekitten.com/300/200);
}

.catcat.crop {
  width: 400px;
  height: 200px;
}
.catcat.crop .image {
  background: url(http://placekitten.com/400/200);
}

/* animations */
.crop:hover .upper.image {
  top: -30%;
}

.crop:hover .lower.image {
  bottom: -30%;
}

.crop:hover .left.image {
  left: -30%;
}

.crop:hover .right.image {
  right: -30%;
}

/* necessary bits */
.crop {
  position: relative;
  overflow: hidden;
  margin: 2em;
  background: #ecb;
}

.crop .content {
  position: absolute;
  top: 50%;
  width: 100%;
  height: 100%;
  margin-top: auto;
  margin-bottom: auto;
  text-align: center;
}

.crop .image {
  z-index: 1;
  position: absolute;
  width: 100%;
  height: 100%;
  background-repeat: no-repeat;
}

.crop .upper.image, .crop .lower.image {
  height: 50%;
}

.crop .left.image, .crop .right.image {
  width: 50%;
}

.crop .upper.image {
  top: 0;
  -webkit-transition: top 0.3s ease;
  -moz-transition: top 0.3s ease;
  -o-transition: top 0.3s ease;
  -ms-transition: top 0.3s ease;
  transition: top 0.3s ease;
}

.crop .lower.image {
  bottom: 0;
  background-position: 0% 100%;
  -webkit-transition: bottom 0.3s ease;
  -moz-transition: bottom 0.3s ease;
  -o-transition: bottom 0.3s ease;
  -ms-transition: bottom 0.3s ease;
  transition: bottom 0.3s ease;
}

.crop .left.image {
  left: 0;
  background-position: 0% 50%;
  -webkit-transition: left 0.3s ease;
  -moz-transition: left 0.3s ease;
  -o-transition: left 0.3s ease;
  -ms-transition: left 0.3s ease;
  transition: left 0.3s ease;
}

.crop .right.image {
  right: 0;
  background-position: 100%;
  -webkit-transition: right 0.3s ease;
  -moz-transition: right 0.3s ease;
  -o-transition: right 0.3s ease;
  -ms-transition: right 0.3s ease;
  transition: right 0.3s ease;
}
And since just reading the code is boring, give the demo a go:
Split Reveal demo
In other news, I published a post about several Canvas libraries over at JSter.

EDIT: I added definitions for left/right reveal and changed it not to depend on top-margin anymore. That caused some issues with non-square images.

Thursday, January 10, 2013

Vagrant - Virtualization for Web Developers

The Cloud Catcher by kanelstrand (CC BY-NC-SA)
If there's one tool each web developer should know, it's Vagrant. Setting up development environment isn't particularly fun. Imagine you have to resume some old project (maintenance, yay!). Can you remember still how to set everything up? Even if you did, it will likely take a while to go through the procedure.

Vagrant provides an excellent solution to this. You start out with a base box and then define what your box should actually contain by using provisioning. This way you can describe which dependencies your environment should fulfill. The provisioner will then set it up accordingly.

After you have set up a box this way you can access it via a ssh tunnel. You can share your project directory with Vagrant virtual machine, run the project there and preview it on your host using your favorite browser and tools.

Vagrant is dead easy to use and makes these sort of scenarios way easier to handle. It is great in a team environment too. Just set it up once and share the configuration. Your team mates, on different platforms even, can use the same virtual machine for development.

Taken further the virtual machine you use to develop your project should mimic the server environment as closely as possible. One less issue to worry about. Better yet you can set up your provisioning so that it's easy for you to deploy and maintain. No need to ssh to your server manually, fiddle with it and cross your fingers anymore!

If you feel like taking Vagrant for a ride, I've gathered a bunch of starting points for you in the listing below. Enjoy!

Thursday, January 3, 2013

jQuery Event Handlers Rethought

There are times when you need to write simple jQuery event handlers such as these:
$('.gallery_item').on('mouseenter mouseleave', function() {
    $('a', $(this)).toggle();
});
Even though it's not a lot of code I believe it could be less. As a result I came up with a little hack that allows you to write the same in the following syntax:
$('.gallery_item').on('mouseenter mouseleave', $e('a', 'this').toggle);
The magic lies within $e. It is a function that constructs aforementioned functions and has some knowledge of the way jQuery works. It introspects the jQuery API and connects the optional selectors with it.

I've included its full definition below. As I don't want to introspect the API every time $e is called I decided to memoize it. In other words it caches the initial results to the function itself. Performance is probably not an issue but I felt this was a good idea anyway.

It's a bit debatable whether "constructor.prototype" should be used. I cannot guarantee it works in each browser, it likely won't. It is possible to replace that bit with a simple array that contains the names of the jQuery methods you want to access. If someone knows a better way, let me know!
function $e(selector, scope) {
    if(selector) {
        return memoize($e, '_sel',
            function() {
                return selTemplate(function($elem, v) {
                    $(getThis(selector, $elem), getThis(scope, $elem))[v]();
                });
            }
        );
    }

    return memoize($e, '_nosel',
        function() {
            return selTemplate(function($elem, v) {
                $elem[v]();
            });
        }
    );

    function getThis(v, that) {
        return v === 'this'? that: v;
    }

    function selTemplate(cb) {
        var ret = {};
    
        $.each(Object.keys($('body').constructor.prototype),    
            function(i, v) {
                ret[v] = function() {
                    cb($(this), v);
                };
        });

        return ret;
    }
}

function memoize(fn, prop, cb) {
    var ret = fn[prop];
  
    if(ret) return ret;

    fn[prop] = cb();

    return fn[prop];
}

I've set up a little demo at JS Bin. You should be able to see it below:

Shortcut demo