Skip to content

Commit 02b1c92

Browse files
committed
Implements module compliance
1 parent 1218608 commit 02b1c92

19 files changed

Lines changed: 7571 additions & 84 deletions

README.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
An implementation of HTML template by way of the microdata mechanism.
44
### The Gist
55
This JavaScript module should simplify adding dynamic content to HTML documents while staying true to the recommendations of web standards. There are no dependencies here except the JavaScript [ECMA5 standard](http://www.ecma-international.org/ecma-262/5.1/) which enjoys [nearly universal support](http://kangax.github.io/compat-table/es5/) in modern browsers. Also, since the HTML recommendations for integral technologies such as [template](https://www.w3.org/TR/html52/semantics-scripting.html#the-template-element) and [microdata](https://www.w3.org/TR/microdata/) are variably implemented by modern browsers, this module serves as a [polyfill](https://en.wikipedia.org/wiki/Polyfill) to assure reliable results. Best of all, this methodology encourages the writing of low-dependency JavaScript and perfectly valid HTML — even within fully-functional templated markup.
6+
7+
***
68
### Simple Usage
79
**1:** In the HTML document, simply load the module and instantiate when ready:
810
```html
@@ -27,7 +29,6 @@ This JavaScript module should simplify adding dynamic content to HTML documents
2729
</nav>
2830
```
2931

30-
3132
**3:** In JavaScript, create a corresponding set of data and then render it (note that the designated element can be an outer scope):
3233
```javascript
3334
var data = [{
@@ -42,7 +43,6 @@ var templater = new MicrodataTemplate();
4243
templater.render(document.getElementById("example"), data);
4344
```
4445

45-
4646
**4:** The resulting HTML will look like this (the template source persists for future use but remains hidden):
4747
```html
4848
<nav>
@@ -62,7 +62,6 @@ var templater = new MicrodataTemplate();
6262
</nav>
6363
```
6464

65-
6665
**Note:** The example above is simplified for clarity, but more compliant microdata could look like this:
6766
```html
6867
<nav>
@@ -75,6 +74,8 @@ var templater = new MicrodataTemplate();
7574
</menu>
7675
</nav>
7776
```
77+
78+
***
7879
### Advanced Usage
7980
Alternatively, the module can be assigned to a discrete namespace:
8081
```html
@@ -89,8 +90,41 @@ Alternatively, the module can be assigned to a discrete namespace:
8990
});
9091
</script>
9192
```
93+
This module is organized to be attached to an HTML document as a simple external script, but also in a project governed by [Asynchronous Module Definition](https://en.wikipedia.org/wiki/Asynchronous_module_definition) (AMD) with a library such as [RequireJS](https://github.com/requirejs/requirejs), or a [CommonJS](https://en.wikipedia.org/wiki/CommonJS) project governed by a framework such as [NodeJS](https://en.wikipedia.org/wiki/Node.js). The expectations are the same, but the syntax used to load, instantiate, and then address the module will be as a local reference rather than a window namespace.
94+
95+
**AMD (RequireJS) Implementation:**
96+
```javascript
97+
require.config({
98+
paths: { auth: "/path/to/idmorg-auth"},
99+
shim: { auth: { exports: "auth" }}
100+
});
92101

102+
define(["auth"], function(Auth) {
103+
Auth.init({
104+
applicationName: "SomeAppName",
105+
endpoint: "https://comps-dev.idmod.org/api/",
106+
parentElement: someDOMElement
107+
});
108+
109+
Auth.signout();
110+
});
111+
```
112+
**CommonJS (NodeJS) Implementation:**
113+
```javascript
114+
import Auth from "path/to/idmorg-auth.js";
115+
116+
$(function() {
117+
Auth.init({
118+
applicationName: "SomeAppName",
119+
endpoint: "https://comps-dev.idmod.org/api/",
120+
parentElement: someDOMElement
121+
});
122+
123+
Auth.signout();
124+
});
125+
```
93126

127+
***
94128
### The Whole Spiel
95129
When displaying information in an HTML page, it sometimes makes sense for a script to loop over a set of data to extract its values and embed them into a repeatable pattern of markup. This sort of routine is what can easily populate the many rows and columns of a complex `<table>` of data, but is also convenient for rendering more pedestrian page elements like `<menu>` and `<select><option>` lists. Of course, this is nothing new and many JavaScript frameworks and libraries provide for exactly this sort of routine as core to their technology, but standard HTML provides for this as well with the `<template>` element. Even more, HTML has long-supported a special set of [microdata](https://www.w3.org/TR/microdata/) attributes designed to make such rendered information more comprehensible to the machine-reading done by search engine crawlers and the like.
96130

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "minimal-requirejs",
3+
"version": "0.1.0",
4+
"description": "an example implementation of microdata-template",
5+
"main": "index.js",
6+
"license": "MIT",
7+
"dependencies": {
8+
"requirejs": "^2.3.5",
9+
"requirejs-json": "^0.0.3",
10+
"requirejs-text": "^2.0.15"
11+
}
12+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Microdata Template: Example: RequireJS Implementation</title>
6+
<style>
7+
body {
8+
font-family: sans-serif;
9+
}
10+
section {
11+
width: 36%;
12+
margin: 3em auto;
13+
}
14+
blockquote {
15+
padding: 8px;
16+
border-bottom: 1px dotted orangered;
17+
color: #0776A2;
18+
}
19+
blockquote:hover {
20+
background-color: #eeeedd;
21+
}
22+
blockquote h5 {
23+
margin: 0;
24+
}
25+
blockquote p {
26+
margin: 1em;
27+
font-size: larger;
28+
line-height: 1.3;
29+
color: black;
30+
}
31+
blockquote time {
32+
display: inline-block;
33+
width: 100%;
34+
text-align: right;
35+
font-size: smaller;
36+
}
37+
</style>
38+
<script src="../node_modules/requirejs/require.js" data-main="js/app.js"></script>
39+
</head>
40+
<body>
41+
<main id="app">
42+
<article>
43+
<section>
44+
<blockquote itemscope itemid="{{ id }}" itemtype="https://schema.org/UserTweets" hidden>
45+
<h5 itemprop="screen_name">@{{ concat:user.screen_name }} tweeted:</h5>
46+
<p itemprop="text">{{ text }}</p>
47+
<time itemprop="created_at" datetime="{{ parseDateToTimeValue:created_at }}">{{ formatDate:created_at }}</time>
48+
</blockquote>
49+
</section>
50+
</article>
51+
</main>
52+
</body>
53+
</html>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
require.config({
2+
waitSeconds: 0,
3+
paths: {
4+
text: "../../node_modules/requirejs-text/text",
5+
json: "../../node_modules/requirejs-json/json",
6+
templater: "../../../../lib/microdata-template",
7+
exampleModule: "example-transformer"
8+
},
9+
shim: {
10+
exampleModule: {
11+
deps: ["templater"]
12+
}
13+
}
14+
});
15+
define(
16+
[
17+
"exampleModule"
18+
],
19+
function (ExampleModule) {
20+
21+
var element,
22+
currentModule;
23+
24+
var init = function() {
25+
26+
element = document.getElementById("app");
27+
currentModule = new ExampleModule()
28+
currentModule.load({ rootElement: element });
29+
30+
};
31+
32+
try {
33+
if ("jQuery" in window && !!$) {
34+
$(document).ready(init);
35+
36+
} else if (window.hasOwnProperty("addEventListener")) {
37+
window.addEventListener("DOMContentLoaded", init, false);
38+
39+
} else if (window.hasOwnProperty("attachEvent")) {
40+
window.attachEvent("onload", init);
41+
42+
} else {
43+
init();
44+
}
45+
} catch (error) {
46+
console.error("error: " + error.status)
47+
}
48+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
define(
2+
[
3+
"templater",
4+
"json!../../../data/transformer.json"
5+
],
6+
function (templater, json) {
7+
return function() {
8+
9+
var rootElement,
10+
templateElement;
11+
12+
var render = function () {
13+
14+
templater.setTransformer("formatDate", function(value, index) {
15+
var time = Date.parse(value);
16+
var date = new Date(isNaN(time) ? isNaN(value) ? Date.now() : value : time);
17+
return date.toLocaleString();
18+
});
19+
20+
if (!!templateElement && !!json) {
21+
templater.render(templateElement, json);
22+
}
23+
};
24+
25+
return {
26+
load: function (info) {
27+
if (!!info && "rootElement" in info) {
28+
rootElement = info.rootElement;
29+
templateElement = rootElement.querySelector("BLOCKQUOTE[itemscope]");
30+
render();
31+
}
32+
},
33+
unload: function () {
34+
try {
35+
templater.clear(templateElement);
36+
templateElement = null;
37+
rootElement = null;
38+
} catch (error) {
39+
console.error("Example could not be destroyed!", error);
40+
}
41+
}
42+
}
43+
};
44+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2+
# yarn lockfile v1
3+
4+
5+
requirejs-json@^0.0.3:
6+
version "0.0.3"
7+
resolved "https://registry.yarnpkg.com/requirejs-json/-/requirejs-json-0.0.3.tgz#8d512699337757d7a96c54a9e85c6c031a101b16"
8+
9+
requirejs-text@^2.0.15:
10+
version "2.0.15"
11+
resolved "https://registry.yarnpkg.com/requirejs-text/-/requirejs-text-2.0.15.tgz#13138733613fc4457b7e1247e8cb751df7aa5429"
12+
13+
requirejs@^2.3.5:
14+
version "2.3.5"
15+
resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.5.tgz#617b9acbbcb336540ef4914d790323a8d4b861b0"
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<html>
4+
<head>
5+
<meta charset="UTF-8">
6+
<title>Microdata Template: Example: Webpack Implementation</title>
7+
<style>
8+
body {
9+
font-family: sans-serif;
10+
}
11+
table {
12+
width: 25%;
13+
margin: 2em auto;
14+
border: 1px solid silver;
15+
}
16+
table tr:nth-child(odd) {
17+
background-color: #f4f4f0;
18+
}
19+
table td {
20+
padding: 0.5em;
21+
}
22+
table td:nth-child(n+2) {
23+
text-align: right;
24+
}
25+
</style>
26+
<script src="bundle.js"></script>
27+
</head>
28+
<body>
29+
<main id="app">
30+
<article>
31+
<section>
32+
<table>
33+
<thead>
34+
<tr>
35+
<th>State</th>
36+
<th>2000</th>
37+
<th>2010</th>
38+
</tr>
39+
</thead>
40+
<tbody>
41+
<!–– This TR node is configured to iterate over the "StatePopulations" object. -->
42+
<tr itemscope itemref="StatePopulations" itemid="{{ 3 }}" hidden>
43+
<!–– The inserted values are derived from the array index found at each iteration. -->
44+
<td itemprop="Name">{{ 2 }}</td>
45+
<td itemprop="2000">{{ toLocaleString:0 }}</td>
46+
<td itemprop="2010">{{ toLocaleString:1 }}</td>
47+
</tr>
48+
</tbody>
49+
</table>
50+
</section>
51+
</article>
52+
</main>
53+
</body>
54+
</html>

0 commit comments

Comments
 (0)