Playing with Polymer 1.0

At the Google I/O conference, they announced the release of Polymer 1.0.  I’ve been wanting to get into Polymer for a while now, and that was the one nudge that I needed.  I decided to take a stab at redesigning my website’s home page with Polymer.

Home Page Using Polymer

Here’s what I have learned…

Installing with Bower

One of my constraints is that I am working with a PHP system.  I don’t want to have a node webserver and a PHP webserver running all at the same time.  I need the PHP at least for the backend.

I even set me up a little PHP script that I could call through AJAX without having to SSH onto the server. I had to set the BOWERPHP_TOKEN environment in order to avoid getting limited too much on the GitHub calls. Also, I had to create a bower_home directory and point my HOME to that. I believe that is where it will place it’s “.cache” directory.

function callBower($parms) {
    global $bowerBinary, $out, $bowerToken, $bowerHome, $bowerPath, $bowerAppPath;

    putenv("BOWERPHP_TOKEN=$bowerToken");
    putenv("HOME=$bowerHome");

    $cmd = new stdClass();
    $cmd->command =  "$bowerPath $parms";
    $out->command = $cmd->command;
    $cmd->lines = array();
    exec($cmd->command, $cmd->lines);
    $cmd->result = join("", $cmd->lines);
    $out->bowerOutput[] = $cmd;
    return $cmd;
}

Bower PHP would install webcomponents and polymer.  I couldn’t get it to install the actual elements — iron, paper, gold, etc.  It says those packages don’t exist.

Instead, I downloaded the elements that I needed from the Polymer Elements Catalog.  I placed the ones that I wanted in the shopping cart.  Then, I clicked download (not install with bower).  I extracted the bower_components contents from the archive into my bower_components folder.

Documentation

I found that the documentation for the new version of Polymer (1.0) was very limited.  You have to watch the version because there are some differences.

I did find a very good series on YouTube that was great for getting started:  Learn Polymer 1.0.  (Thank you “Stretch Projects”)

Theoretically, you should be able to use the Migration Guide to help understand use any of the 0.5 documentation with regards to the new 1.0.  I found that easier said than done.

Including Polymer and Elements in the Page

One of the confusing things that I am not sure that I still understand. Normally, I include all of the scripts in the “head” section. Instead, Stretch Projects recommends placing the requirements directly in the body of the page:

<body>
    <script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
    <link rel="import" href="bower_components/polymer/polymer.html">

Next, you need to import the html file for each web component that you use. Stretch Projects recommends doing that in the body right before you use the element. For example:

            <link rel="import" href="bower_components/paper-header-panel/paper-header-panel.html">
            <paper-header-panel drawer>
                <link rel="import" href="bower_components/paper-toolbar/paper-toolbar.html">
                <paper-toolbar>
                    <div>DigitalEagle.net</div>
                </paper-toolbar>
            </paper-header-panel>

I saw some resources talking about using the Vulcanize project. I assume that going that route would put all of the imports up in the “head” area of the page. Also, that requires the use of Node. I didn’t find a PHP alternative.

Another tool that I like is head.js. I didn’t see any resources about using head.js for loading these imports.

Basic Scaffolding

Based on what I learned from the Stretch Project videos, you can create a basic structure for a website/app with this structure:

    <body class="vertical layout">
        <script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
        <link rel="import" href="bower_components/polymer/polymer.html">

        <link rel="import" href="bower_components/paper-drawer-panel/paper-drawer-panel.html">
        <paper-drawer-panel>

            <link rel="import" href="bower_components/paper-header-panel/paper-header-panel.html">
            <paper-header-panel drawer>
                <link rel="import" href="bower_components/paper-toolbar/paper-toolbar.html">
                <paper-toolbar>
                    <div>Drawer Title</div>
                </paper-toolbar>
            </paper-header-panel>

            <paper-header-panel main>
                <paper-toolbar>
                    <h1>Title</h1>
                </paper-toolbar>

                <div>Main Body Area</div>

            </paper-header-panel>
        </paper-drawer-panel>
    </body>

Layout

The layout for Polymer 1.0 is different from the older versions, and I had trouble finding resources for how to use it. Thanks to a nice thread on Google Groups, I finally found a Plunkr with a very good reference.

You can watch the iron-flex-layout documentation to see when it gets written: iron-flex-layout.

For ease of reference, let me place some of layout examples that I used here. You’ll have to visit the Plunkr to see the rest of them.

Here’s the horizontal layout with a flex section:

Polymer Horizontal Layout

    <div class="horizontal layout">
      <div><p>div</p></div>
      <div class="flex"><p>flex (horizontal layout)</p></div>
      <div><p>div</p></div>
    </div>

Here’s the vertical layout with a flex section:

Polymer Vertical Layout

    <div class="vertical layout" style="height:250px">
      <div><p>div</p></div>
      <div class="flex"><p>flex (vertical layout)</p></div>
      <div><p>div</p></div>
    </div>

Here’s the Layout End Justified:

Polymer Layout End-Justified

    <div class="horizontal layout end-justified" style="height:100px">
      <div><p>horizontal layout end-justified</p></div>
    </div>

Here’s the wrapped layout:

Polymer Wrapped Layout

    <div class="horizontal layout wrap" style="width:150px; height:70px">
      <div><p>horizontal</p></div>
      <div><p>lay</p></div>
      <div><p>out</p></div>
      <div><p>wrap</p></div>
    </div>

Icons

I’m used to Bootstrap having the glphyicons to use to spruce up buttons and things. Come to find out, Polymer has it’s own set of icons. Something is broken on the catalog, so it’s very hard to get to, but the iron-icons demo page has the list of icons included:
iron-icons

For example, here’s how you can use one of those icons in a button:

<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/iron-icon/iron-icon.html">
<link rel="import" href="bower_components/iron-icons/iron-icons.html">
<paper-button class="plain">
    My Link
    <iron-icon icon="icons:open-in-new"</iron-icon>
</paper-button>

Image Autosizing

This topic isn’t really part of Polymer, but I wanted an image that sizes to match the available space. I found Kurt Schindler had an answer.

I wanted to resize the front image:

<img class="familypic" src="front/img/phillips-portrait.jpg">

Here’s the CSS that Kurt recommended:

.familypic {
    max-width: 100%;
    height: auto;
    width: auto\9;
}

It works pretty cool. I have the picture laid out with the Polymer layout constructs so that it takes up about half of the content area. The browser resizes the image to fit whatever that size is.

Menu and Click Event

One challenge I had was getting the menu in the drawer working. Building the menu was pretty simple. I just imported and used the paper-menu element:

<link rel="import" href="bower_components/paper-menu/paper-menu.html">
<link rel="import" href="bower_components/paper-item/paper-item.html">
<paper-menu>
    <paper-item>PSST0101</paper-item>
    <paper-item>Linux Sagas</paper-item>
    <paper-item>Personal</paper-item>
    <paper-item>Resume</paper-item>
</paper-menu>

Using a couple different resources, I found that I needed wrap the document in a “template” tag.

<template id="bind" is="dom-bind">
 ... document
</template>

I didn’t need to wrap the whole document technically, just the menu. But, I thought it would be easier to work with this way. According to this StackOverflow question, the “is” attribute should be “auto-binding”. I found that for Polymer 1.0, it should be dom-bind instead. You can find more information on the 1.0 “Data binding helper elements” doc.

Then, I added an on-click attribute to each paper-item and a “target” attribute to make distinguishing them easier.

<paper-menu>
    <paper-item on-click="menuClick" target="blog-psst0101">PSST0101</paper-item>
    <paper-item on-click="menuClick" target="blog-linuxsagas">Linux Sagas</paper-item>
    <paper-item on-click="menuClick" target="blog-personal">Personal</paper-item>
    <paper-item on-click="menuClick" target="section-resume">Resume</paper-item>
</paper-menu>

Note that I have markers through out my document:

<section><a name="blog-psst0101"></a>

Finally, I placed this event handler at the end of the document:

<script>
    var bind = document.querySelector('#bind');
    bind.menuClick = function(e) {
        window.location = "#" + e.target.attributes['target'].value;
    }
</script>

Resources

Leave a Comment

Your email address will not be published. Required fields are marked *