Get 10$ Digital Ocean SSD Hosting Credit for free.

First Thoughts on the Google Polymer Project from a GWT and AngularJS perspective

The Polymer Project Logo

The Polymer Project Logo

Motivation

Probably because I did a lot of development using the Google Web Toolkit (GWT), I have always been an addict of the Google IO session videos. Every year there is a nerdy excitement growing inside me, of what the Google Devs will come up with this year.

I can remember hearing about ‘Shadow DOM’ two years ago in this IO 2012 session. A year later the Polymer Project was announced and this year at Google IO 2014 a lot of sessions where dedicated to it in combination with the (in my opinion) awesome new Google UI and UX guidelines called “Material Design”.

Material Design Guidelines

Material Design Guidelines

So what is Polymer exactally? Here the definition from the offical landing page:

Web Components usher in a new era of web development based on encapsulated and interoperable custom elements that extend HTML itself. Built atop these new standards, Polymer makes it easier and faster to create anything from a button to a complete application across desktop, mobile, and beyond.

Although big parts of Polymer are still only polyfills of future web standards, especially if you use anything other than the latest Chrome Browser, I decided to give it a try and realized a small web project with it.

FoodTrack.de

FoodTrack.de Screenshot

FoodTrack.de Screenshot

FoodTrack is basically build around another passion of mine, which is eating delicious food. The Food Truck trend is finally coming from the US to Germany and FoodTrack.de helps you find the best ones in your area *Shamless self advertising* 😉

Thoughts from a GWT and AngularJS perspective

I have a strong background in a lot of Java and GWT programming, which is currently switching the other way around in the direction of using more and more native JavaScript with AngularJS as client side framework and even NodeJS on the server.

Coming from this perspective, here are some opinions on the fundamental new things Polymer brings to the web development table,
divided into the three parts ‘HTML imports’, ‘Custom Elements and Shadow DOM’ and ‘HTML Templates and Data Binding’.

HTML imports

HTML imports are a native way to decompose your HTML into multiple file chunks.

Example

<link rel="import" href="components/foodtruck-card/foodtruck-card.html">

Why it is cool

This enables you to structure your project as you would in GWT with various Java Classes and Packages or in AngularJS by dividing your JS in to separate files and loading the views as partials.
Also it allows easier embedding of widgets like a Facebook ‘Like Button’ by just importing a lightweight widget directly from the provider, instead of scamping ugly iframes into the page via JavaScript snippets.
The downside is the amount of requests necessary to load your page will increase, here you can use the build tool ‘Vulcanize’ to concatenate your imports into one HTML file for production.

Importance: To be able to divide a project into multiple files is an absolute basic for every serious maintainable development project.

Custom Elements and Shadow DOM

With Custom Elements and Shadow DOM you can create your own HTML elements, which can contain their own logic, view and style, without cluttering the DOM of the main page.

Example

<!-- Define your custom element -->
<polymer-element name="foodtruck-card" attributes="name img website review currentDay shortestDistanceReadable list">

    <!-- TEMPLATE (...) -->
   
     <script>
        (function () {
            Polymer('foodtruck-card', {
                name: 'Food Truck',
                img: "images/default.jpg",
                description: [],
                hoveredMarkerId: null,
                ready: function () {
                    this.selected = true;
                }
            });
        })();
    </script>
</polymer-element>
<!-- Use your custom element -->
<foodtruck-card name="Ribwich" website="http://www.ribwich.de" selected="false"></foodtruck-card>

Why it is cool

Basically you can think about custom elements and Shadow DOM like Panels and Widgets in GWT, just natively direct in the browser. Here you can really take your GWT abstraction and modularization thinking and apply it to native web development to create complex applications. You can extend other elements and compose multiple elements inside of another one.
In AngularJS you can accomplish similar things by creating your own directives, which can also have nested elements and their own logic and templates.

Importance: To be able to abstract your user interface into reusable and composable parts and hierarchies is a mandatory requirement for all projects that are not completely trivial.

HTML Templates and Data Binding

HTML templates and Polymer two way data binding enables you to create reusable templates of HTML chunks with designated substitution hooks for the actual data model, that update automatically on changes.

Example

<template style="width:100%; height:100%;">
        <style>
            .wrapper {
                background-color: white;
                padding: 16px 16px 8px 16px;
                margin: 8px;
            }
        </style>

        <article class="wrapper">
            <h3>{{name}}</h3>
            <p class="distanceStamp">{{shortestDistanceReadable}}</p>
            <img class="mainImage" src="{{img}}"/>
            <template repeat="{{addr in currentDay}}">
                <div>
                    <div><b>{{addr.startTime}} - {{addr.endTime}}</b></div>
                    <div><a href="http://maps.google.com/?q={{addr.name}}" onmouseover="hoverMarkerId({{addr.markerId}});" onmouseout="hoverMarkerId({{addr.markerId}});" target="_blank">{{addr.name}} {{addr.distanceReadable}}</a></div>
                    <div style="clear: both;"></div>
                </div>
            </template>
            <div class="websiteLink">
                <a href="{{website}}" target="_blank"><core-icon icon="launch" size="12px"></core-icon>&nbsp;Offizielle Website</a>
                <template bind if="{{ review }}">
                    <a href="{{review}}" target="_blank"><img src="/images/nueso.ico"/>&nbsp;Test bei 'Nürnberg und so'</a>
                </template>
                
            </div>
        </article>
    </template>

Why it is cool

This is something that should feel very familiar to every AngularJS developer.
Polymer basically enhances your custom elements with two way data binding and mustache style templating.
For GWT developers this should be somewhat mind blowing, as data binding is pretty awkward in GWT in my opinion and a lot of people who use it are probably still binding data manually. Also the GWT UiBinder syntax is pretty heavy weight XML in comparison to modern templating approaches.

Importance: Using templates with two way data binding will prevail as the standard way of doing front ends, as it reduces a ton of boilerplate code and decreases the hassle of keeping your data model and view in sync immensely.

Sounds cool, is Polymer production ready?

Overall I would say ‘No’ at the moment (which is August 2014). 😐

I will wait until there is better native support of the underlying standards before I would use it for any serious commercial project.

Why not yet

  • Still based on lots of polyfills in most browsers.
  • Everything except Chrome feels a bit sluggish performance wise.
  • There is still a lot of active work going on in the development of the core components. Small API changes and bugs are common.
  • Polymer also officially only supports the latest two versions of each browser, which still excludes a non negligable amount of users. Think older iOs devices or IE8 and IE9

But as stated on the official project page, production readiness is currently not the goal of Polymer, but when it gets there, I will try to be first in line 🙂
Until then I will continue to get more into AngularJS, while still being comfortable maintaining my GWT projects.

Exhaustive additional resources:

http://www.polymer-project.org
http://www.polymer-project.org/resources/video.html
http://webcomponents.org/

Added August, 29th 2014:
Blogpost predicting the future of GWT in face to the new web standards:
http://blog.xam.de/2014/02/gwt-is-coming-back-in-2015.html

Get 10$ Digital Ocean SSD Hosting Credit for free.

GWT UiBinder I18n – Tutorial – The easy way!

The Problem with UiBinder i18n

gwt-logo

Anyone who tried to internationalize a GWT application that uses UiBinder at some point got to the official documentation page:
http://www.gwtproject.org/doc/latest/DevGuideUiBinderI18n.html

In very short the official way of doing UiBinder i18n according to the documentation looks like this:

  • Add three attributes to EVERY UiBinder ui.xml
  • Mark every text you want to translate with a ui:msg or ui:attributes tag
  • Run the compiler with the “-extras” flag to auto generate property files containing the key/message pairs used for translation
  • Copy those generated property files from the extras folder into your project
  • There is one property file per language per UiBinder xml file
  • Keys are incomprehensible MD5 hashes

It took me a while to understand what is going on here. Not a very convenient and straight forward way in my opinion!
Even the official documentation has a hard time to take itself seriously:

(…)run the gwt compiler with -extra /tmp/gwt-extras; you’ll find the file in /tmp/gwt-extras/com.example.app.App/com.example.app.client.HelloBinderImplGenMessages.properties. No kidding. Hopefully this will be cleaned up in a future release of the toolkit.

What UiBinder i18n should be like

For me the basic straight forward way of i18n should be:

  • Create key/value property files for every language
  • Access the messages in UiBinder via the key
  • The key is human readable
  • One property file per language per module

What if I told you, you can actually do this easily with GWT UiBinder?
whatif
The magic key word here is a bit hidden in the developer guide: ui:baseMessagesInterface See the documentation:

ui:baseMessagesInterface
Sets the base interface to use for generated messages. The value must be the fully-qualified class name of an interface that extends Messages. You can then put whatever annotations you want there, making it easy to have company or project-wide settings that can be changed in just one place. You can still use the other attributes to override defaults inherited from that interface if necessary.

Example

What follows is a short example how this style of i18n would look like

WelcomePanel.ui.xml

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g='urn:import:com.google.gwt.user.client.ui'
             ui:baseMessagesInterface="com.sebastianmetzger.gwt.client.i18n.WelcomeMessages">

    <ui:style>
        .wrapper {
            padding: 64px;
        }
    </ui:style>

    <g:HTMLPanel styleName="{style.wrapper}">
        <h1><ui:msg key="heading">Not translated</ui:msg></h1>
        <p><ui:msg key="greeting">Not translated</ui:msg></p>
    </g:HTMLPanel>
</ui:UiBinder>

Notice the ui:baseMessagesInterface attribute in the ui:UiBinder tag, which points at com.sebastianmetzger.gwt.client.i18n.WelcomeMessages

WelcomeMessages.java

package com.sebastianmetzger.gwt.client.i18n;

import com.google.gwt.i18n.client.Messages;

public interface WelcomeMessages extends Messages {
    // Only add Messages here, you need to access outside of UiBinder
}

Note that it is not necessary to explicitly add the keys to the Java interface. They will be taken directly from the property files for UiBinder. You will need to put the messages into the interface, if you want to access the translations from anywhere else though.

WelcomeMessages_en.properties

heading = Welcome
greeting = Can I offer you a juicy hamburger?

WelcomeMessages_de.properties

heading = Willkommen
greeting = Möchten Sie eine leckere Schweinshaxe essen?

Note: The property files have to be in the same package as the corresponding Messages interface to be mapped automatically.

The Result

English version - Locale: en

English version – Locale: en

German version - locale: de

German version – locale: de

Dependent on the set locale the UiBinder template is now filled with the translated messages. Neat!

Get the Example from GitHub

I put the example project into a public github repo. Feel free to use it as a template!

Clone it

git clone https://github.com/Sturmination/gwt_uibinder_i18n

Build and run it (requires Maven)

gwt_uibinder_i18n/mvn clean jetty:run-exploded

Get 10$ Digital Ocean SSD Hosting Credit for free.

How to set up live reloading Unit Tests with jQuery, QUnit and Grunt

Introduction

Frontend JavaScript developers today have a great choice of tools available, that enable a more productive workflow. I currently facilitate Grunt, Bower and Yeoman, which are great build tools that emerged around the NodeJS community. I also use RequireJS for modularization and QUnit for unit testing.

I am always very hesitant in introducing new tools into my workflow, because there is often that period where you do not feel productive and the new tool is more in the way than helping. Very often though I can not imagine living without out that new tool after a while.

To help others to get their JS development faster to a more professional level I decided to write some quick tutorials covering one specific use case at a time, that I found useful for myself when working with the above mentioned tools. It will probably be geared mainly towards the intermediate and advanced JS developer, so total basics will not be covered.

Tutorial

This first post guides you to set up an example project with live reloading unit tests using Grunt and QUnit.

QUnit is the unit testing framework coming from the jQuery community.

Grunt is a task runner, that enables the automation of repetitive tasks.

Prerequisites

1. Download and Install NodeJS

NOTE: You do not need to use NodeJS for your project, but we will need NPM (The NodeJS package manager) to install and run Grunt.

2. Get the latest jquery.js

3. Get the latest qunit.js and qunit.css

OPTIONAL: If you are lazy you can just clone the project from a GitHub Repository I created for this tutorial:

git clone https://github.com/Sturmination/livereload_qunit_tut.git

Project Structure

/lib/jquery.js 
/lib/qunit.js
/css/qunit.css

/src/tests.js 
Gruntfile.js
package.json
index.html

File Contents

index.html

<!DOCTYPE html>
<html>
	<head>
		<title>Live Reloading Unit Test are awesome</title>
		<!-- Style -->
		<link href="css/qunit.css" rel="stylesheet" type="text/css" />
	</head>
	<body>
		<!-- Mark Up required by QUnit -->
		<div id="qunit"></div>
  		<div id="qunit-fixture"></div>

  		<!-- Libs -->
		<script src="lib/jquery.js" type=></script>
		<script src="lib/qunit.js"></script>
		<!-- Src -->
		<script src="src/tests.js"></script>
		<!-- LiveReload script served by Grunt -->
		<script src="http://localhost:35729/livereload.js"></script>

	</body>
</html>

The livereload.js is served by a localhost server. This is a NodeJS server opened by grunt later.

src/tests.js

test("This is just a test",function(){
	ok(true, "True is actually true!");
});

Just a very simple QUnit test. For further information see offical QUnit documentation.

Gruntfile.js

//Gruntfile
module.exports = function(grunt) {
  //Initializing the configuration object
  grunt.initConfig({
    watch: {
      // Folders and files that are being watched by grunt
      // Add your additonal project files and folders here!
      files: ["src/**/*.js", "index.html"],
      options: {
        livereload: true
      }
    }
  });

  // Plugin loading
  grunt.loadNpmTasks('grunt-contrib-watch');

  // Set watch as the default task
  grunt.registerTask('default', ['watch']);
};

This is the config file, which tells Grunt what to do. Remember adding your specific project folders and files to the watch task.

package.json

{
  "name": "livereload_tdd_tut",
  "version": "1.0.0",
  "description": "Example project on livereloading unit tests",
  "author": "Sebastian Metzger",
  "devDependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-watch": "~0.6.1"
  }
}

This file is required to tell NPM what dependencies to resolve for your project. We only need grunt and the grunt-contrib-watch task for this example.

Install Packages and Run Grunt

After you have set up your project directory, open a console and switch to that directory.
If you installed NodeJS correctly the following command should install the dependencies specified in the “package.json”

npm install

Now you can see NPM installing grunt in your project!

Next start grunt with the simple command

grunt

We configured in the “Gruntfile.js” the “watch” task as default, so no parameters are required.

If everything went right, the console now should say:

Watching...

This means the watch task is active! Grunt is monitoring your project folder for changes and has opened the NodeJS instance that serves the “livereload.js” file.

Finally open the index.html in the browser of your choice.
You should now see the QUnit interface and the single test successfully executed.

QUnit tests successful

QUnit tests successful!

The “http://localhost:35729/livereload.js” included into your “index.html” should now have established a web socket connection to the server opened by the grunt watch task, which will trigger a page refresh, whenever the watch task detects a file change.
To test this just change anything in the “index.html” or “src/tests.js” and press the save button.

For example extend the “src/tests.js” with another test like this:

test("This is just a test",function(){
	ok(true, "True is actually true!");
});

test("This is just another test",function(){
	ok(true, "True is actually true!");
});

The browser window with the QUnit tests should now reload automatically after you save the file changes.
Isn’t this exciting? I think so! 🙂

Why is this useful?

Now you can basically put the browser with the unit tests on your second monitor and just hack away in your favorite IDE until you see something break in you peripheral vision. You do not have to break your coding workflow constantly to refresh the browser or click around in the user interface.

You can also open the tests in different browsers simultaneously, which all will reload after every change you make. This is very cool because you are constantly aware of cross browser compatibility and see a divergence exactly in the moment you wrote the line of code, that caused the faulty behavior.

I found this a useful workflow when working on a lower level library that does not directly affect any HTML/CSS or user interaction and thus can be better developed against unit tests from the start.

If anything is not working or you think I should go more or less into details in the next posts, please feel free and leave a comment. I also take requests for further tutorial posts. 🙂