Enoki is a powerfully simple set of tools and interfaces for creating and managing websites and single-page-apps. It’s as vanilla as possible, meant to get out of your way, and play nice with traditional tooling as well as unique environments, such as the peer-to-peer Beaker Browser.
Although fully-featured, Enoki is still early in development. Support for other frameworks and syntax styles are on the roadmap. If something you’d like to see is missing, please feel free to contribute!
- no-db: just files and folders
- simple: written for clarity
- tools: easy ways of traversing data
- cute: first class support for choo, a simple and sturdy front-end framework
- panel: manage your content with a super simple and extensible interface
Although the Enoki library can be used in a variety of ways, for the sake of example let’s just create a fresh little Choo app and require enoki/choo
:
var choo = require('choo')
var app = choo()
app.use(require('enoki/choo')())
Create a /content
directory in the root of your project and make an index.txt
file. Pages (and sub-pages) are just folders with their own index.txt
files:
title: Enoki Example
----
text: Hey, not bad!
Inside your Choo views you can traverse your content with a super handy API:
var Page = require('enoki/page')
var html = require('choo/html')
function view (state, emit) {
var page = new Page(state)
var children = page().children().sort('title', 'asc').value()
return html`
<body>
<h1>${page.value('title')}</h1>
<article>${page.value('text')}</article>
<ul>
${children.map(renderChild)}
</ul>
</body>
`
function renderChild (props) {
var child = page(props)
return html`
<li>
<a href="${child.value('url')}">${child.value('title')}</a>
</li>
`
}
}
To use Enoki with browserify just include the transform which will statically inline the JSON hypha
provides. Ensure you’re using the .readSync()
method and -t enoki/transform
.
The web is becoming re-decentralized! You can use Enoki with Dat in an environment such as Beaker Browser by swapping Node’s fs
for the DatArchive
API. This enables real-time reading of the archives’s files. Ensure you’re using .readAsync()
.
Enoki is early in development. If you’d like to see support for webpack, or whatever other tooling, feel free to contribute!
For specifics on formatting directories and files, take a look at the dependencies’ documenation.
smarkt
for parsing mixed key/value store and yaml plain text fileshypha
for turning folders and files into json
The Page API is a super easy way of traversing your contnet. A few basic rules.
- End a query and return it’s value by calling
.value()
- Every method is chainable (except
.value()
) - Values can be reused in new queries by doing
page(oldQuery)
var Page = require('enoki/page')
function view (state, emit) {
// instantiate the page
var page = new Page(state)
// directly access pages by their href
var site = page('/').value()
var about = page('/about').value()
// grab children and files
var children = page().children().sort('name', 'asc').value()
var files = page().files().value()
// create new queries from previous
var first = page(children).first().value()
var last = page(children).last().value()
// access specific keys
var lastTitle = page(last).value('title')
}
Complete Methods List
Remaps to .pages()
.
Grab an individual file.
Files of the current page
.
Locate a sub-page
of the current page
based on the href
.
Returns the first page
or file
.
Does the current page have a custom view?
Images of the current page.
Is the current page active?
Returns the last page
or file
.
The current page.
Sub-pages of the current page.
The parent of the current page.
Sorts the current value’s .pages
by .order
. Formatting of .order
follows the arguments of .sortBy
seperated by a space. For example, date asc
.
Sort the files
or pages
based by a certain key. Order can be either asc
or desc
. For example, .sortBy('name', 'desc')
or .sortBy('date', 'asc')
.
Converts the values of an object to an array.
Return the current value. Not chainable.
Returns if the current value key visible
is not false
.