My website has a list of projects defined roughly as:

- Index.html
<body>
<div class="projects">
<div class="project">
<span>Project Name</span>
<video>Project Video</video>
</div>
<div class="project">
<span>2nd Project Name</span>
...
</div>
</body>


The simple way to solve this is by manually writing this template over and over for each project.

This isn't scalable however and a pain to update, so I want to encapsulate the HTML into a web-component. This would would result in an index page that looks something like this:

- Index.html
<body>
<div class="projects">
<project text="Example" video="example.mp4"></project>
<project text="AnotherExample" video="example2.mp4"></project>
</div>
</body>


You'll note the custom "project" tags being used along with non-standard properties being passed into them. This is a web-component, which I need to define in Project.html

Without any frameworks, a raw web-component would result in code looking something like this (shown in full mostly for effect):

- Project.html
<template>
<div>
<span></span>
<video></video>
</div>
</template>

<script>
function(window, document, undefined) {

var template = document.querySelector('template').content;

var projectProto = Object.create(HTMLElement.prototype);

projectProto.createdCallback = function() {

var clone = document.importNode(template, true);

};

projectProto.attributeChangedCallback = function(attr, oldVal, newVal) {
if (attr == "text")
this.spanNode.textContent = newVal;
else if (attr == "video")
this.videoNode.textContent = newVal;
};

window.project = document.registerElement('project', {
prototype: projectProto
});
})(window, document);
</script>


This defines the web component in VanillaJS[1], along with two data-bindings to the internal tags that need to be filled in.

Binding values directly to values however is again an unscalable solution. A number of frameworks are emerging to try solve this problem by offering data-binding for the template.

The following is the same as above but now using Google's Polymer 1.0 framework.

- Project.html

<polymer-element name="project">
<template>
<style>
:host {
border: 1px solid red;
}
</style>
<div>
<span>{{text}}</span>
<video>{{video}}</video>
</div>
</template>

<script>
Polymer('project', {
text: "Default",
video: "default.mp4",
});
</script>
</polymer-element>


This is obviously much cleaner[1:1] than the pure web-components example because of the in-built data-binding.

I've also shown in the above how styling can be applied to a web-component. With the above structure, I can now update the project's style individually by updating this file rather than Index.html or a separate style-sheet.

1. I saw the 2.0 implementation at the Polymer Summit (17th Oct) which is an even cleaner example than above given their move over to ES6 class-based style. ↩︎ ↩︎