Compose a tree from maps

We are now going to create a little site tree with a home page and a posts area organized into a navigational hierarchy:

g index.html <!DOCTYPE html> <html lang="en"> <head… ->index.html index.html posts ->posts posts posts/post1.html <p>This is <strong>post 1</strong>.</p> posts->posts/post1.html post1.html posts/post2.html <p>This is <strong>post 2</strong>.</p> posts->posts/post2.html post2.html posts/post3.html <p>This is <strong>post 3</strong>.</p> posts->posts/post3.html post3.html

Using Map objects to represent this tree will be straightforward.

  • The posts area (the circle in the middle of the above diagram) will be the result of applying the HtmlMap transformation to a map of markdown documents. Those could come from anywhere; for this demonstration we’ll use the file-based markdown collection.
  • The index.html page will use that posts map to construct links to all the posts.

Composing the site’s root node #

We need a way to combine these two pieces into a new map to form the root of our tree (the circle on the left above). This is a good job for a stock Map!

/* src/site/site.js */

import markdown from "./files.js";
import HtmlMap from "./HtmlMap.js";
import indexPage from "./indexPage.js";

const posts = new HtmlMap(markdown);

export default new Map([
  ["index.html", indexPage(posts)],
  ["posts", posts],
]);

Alternatively, we could define the root node with an ObjectMap:

import markdown from "./files.js";
import HtmlMap from "./HtmlMap.js";
import indexPage from "./indexPage.js";
import ObjectMap from "./ObjectMap.js";

const posts = new HtmlMap(markdown);

export default new ObjectMap({
  "index.html": indexPage(posts),
  posts,
});

This requires a separate import statement, but the tree definition itself is slightly more concise and arguably more legible.

Displaying the site #

Because our site is a tree of maps, we can dump the entire contents of the site to the console using our json utility.

$ node json site.js
{
  "index.html": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <title>Blog home</title>\n  </head>\n  <body>\n    <h1>Posts</h1>\n    <ul>\n      <li><a href=\"/posts/post1.html\">post1</a></li>\n      <li><a href=\"/posts/post2.html\">post2</a></li>\n      <li><a href=\"/posts/post3.html\">post3</a></li>\n    </ul>\n  </body>\n</html>",
  "posts": {
    "post1.html": "<p>This is <strong>post 1</strong>.</p>\n",
    "post2.html": "<p>This is <strong>post 2</strong>.</p>\n",
    "post3.html": "<p>This is <strong>post 3</strong>.</p>\n"
  }
}

The index.html page is a little hard to read inside the block of JSON — but the content is all there and correct.

Of course, what we really want to do is browse this site tree.

 

Next: Serve a tree »