Getting started
To follow the steps and to tweak the code yourself, you need to sign up for a free account. We also recommend installing it. In addition to the Javascript from Flatdoc, the code consists of HTML and server side tags (HandlebarsJS) and should be easy to follow for any budding web dev/signer.
We also recommend checking out the finished result.
Setting up database collections (and the REST API)
Setting up a database structure (schema) in restdb.io is done quickly in "Developer Mode" (learn more here). We use two collections (tables) in restdb.io: projects and docs. Each project record may contain many (child) document records. The child relation is set up with the field docs as shown in the screenshot below. The REST API is automatically available and reflects the structure. You can read more about parent-child relationships in the documentation.
A record in the document collection contains the following fields:
- slug
- human (and SEO) friendly URL
- title
- text
- documentation text in Markdown format
- sort
- display order of help documents
- published
- noliterate
- A Flatdoc setting. If true, will display code examples in a separate column on the right.
The screenshot below shows how Markdown is enabled for the text field. This setting makes restdb.io display a Markdown editor for editing (restdb.io use the SimpleMDE editor internally).
Adding data and content
A project is added in the database by creating a new Project record. Docs are added as children records (see screenshots below).
Writing and editing documentation with Markdown is shown below.
Serving the content with Pages
So now we have the structure and some data in place. How do we create a website to present the documentation? We use restdb.io Pages.
In addition to be a REST enabled NoSQL database, restdb.io can serve Pages over http. They can be simple HTML, XML, in fact any kind of file/mime-type. Pages can also have special dynamic routes and run database queries on the server side. In other words, they can serve almost any type of content directly from the database.
When developing this template, we started out by creating the web page (and route) for displaying a Markdown file using Flatdoc. As we shall see this page also uses another Page/route to retrieve the Markdown document text from the database.
We also have a number of other pages: project overview, sitemap.xml, a notfound page and also the flatdoc css and javascript file (see screenshot below). We'll leave it up to you to check out these in the template source.
Flatdoc
Flatdoc is basically a little Javascript and some CSS. The Javascript can fetch a Markdown file either from Github or from a URL (which is what we use here). Flatdoc parses the Markdown file and dynamically produce a HTML page with a multi-level menu which, when clicked, scrolls nicely to the document section. It can also put code examples in a column of its own, just like the famous Stripe docs used to do (it's called a "noliterate" setting).
Serving the docs
The main file for displaying docs is a Page in HTML using Flatdoc with a few server side HandlebarsJS tags (see commented source code below). The {{#context}}}
block runs a query for fetching a record from the docs collection with a parameter "slug" as given in the path. In restdb.io, a Page with a name like a path /docs/:slug
will behave like a route where :slug
is the dynamic part which can be accessed in a Page with the tag {{pathparams.slug}}
.
Queries in restdb.io always returns an array, so both the {{#unless}}
and the {{#with}}
blocks adresses the first element of the query result like this: docs.[0]
. Note that the {{root}}
tag has to be used so that the page can be viewed correctly internally in the restdb.io admin backend. If you know HandlebarsJS], you'll now why it is used with a ../
. The root tag belongs to the top scope and when used within another block it must be adressed this way.
{{#context}}
{
"docs":{
"collection": "docs",
"query":{"slug":"{{pathparams.slug}}", "published":true}
}
}
{{/context}}
<!doctype html>
{{#unless docs.[0]}}
<html>
<body>
<h3>No doc found with this URL. Is it public?</h3>
</body>
</html>
{{/unless}}
{{#with docs.[0]}}
<html>
<head>
<meta charset='utf-8'>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no">
<title>{{title}}</title>
<!-- Flatdoc -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="{{../root}}/flatdoc.js"></script>
<!-- Flatdoc theme -->
<link href="{{../root}}/flatdoc-theme.css" rel='stylesheet'>
<link href="{{../root}}/styles.css" rel="stylesheet">
<script src="{{../root}}/flatdoc-theme.js"></script>
<!-- Meta -->
<meta content="{{name}}" property="og:title">
<meta content="{{description}}" name="description">
<!-- Initializer -->
<script>
// use the Flatdoc file method to fetch markdown from the restdb.io route /markdown/:slug
Flatdoc.run({
fetcher: Flatdoc.file('{{../root}}/markdown/{{slug}}')
});
// get other docs in the same project and inject in the top menu
$.getJSON("{{../root}}/docsforparent/{{_parent_id}}",function(doc){
$("#projectname").text(doc.project.name);
$.each(doc.docs,function(index,thedoc){
if(thedoc.published){
var elem = ["<li id='",thedoc.slug,"'><a href='{{../root}}/docs/",thedoc.slug,"'>",thedoc.title,"</a></li>"].join("");
$("#doc-menu").append($(elem));
}
});
// highlight the current document in the menu
$("#doc-menu #{{slug}}").addClass("active");
});
</script>
</head>
<body class="big-h3 large-brief {{#if noliterate}}no-literate{{/if}}" role='flatdoc'>
<div class='header'>
<div class='left'>
<h1><a href="{{../root}}/" style="font-size:1.6em">« </a><span id="projectname"></span></h1>
<ul id="doc-menu">
</ul>
</div>
<div class='right'>
<!-- not in use -->
</div>
</div>
<div class='content-root'>
<div class='menubar'>
<div class='menu section' role='flatdoc-menu'></div>
</div>
<div role='flatdoc-content' class='content'></div>
</div>
<!-- include the content on the server side - for SEO -->
<div class="servercontent">
{{markdown text}}
</div>
</body>
</html>
{{/with}}
Flatdoc fetches the Markdown text using the URL /markdown/:slug
. We set up a simple Page to serve this content as text (mime type text/plain).
{{#context}}
{
"docpages": {
"collection": "docs",
"query": {"slug":"{{pathparams.slug}}"},
"hints": {}
}
}
{{/context}}
{{#with docpages.[0]}}{{{text}}}{{/with}}
This page actually just runs a query, fetching a record matching the "slug" in the path parameter and then returns the "text" field as unescaped text (note the three braces {{{text}}}
).
Conclusion
We've shown you how we used an awesome Javascript utility, Flatdoc, and adapted it to fetch data from a restdb.io database organized around projects and docs. If you found this template useful, either for learning a bit more about Pages or because you actually need it, then go ahead and install your copy.