NOTE: Docgen is experimental "alpha" software.
Docgen is a static site renderer which is built using servo's html5ever and spidermonkey. It aims to make static site generation to be effortless and removing templating languages such as liquid.
Docgen's template syntax is based on / inspired by the syntax used by vuejs's templates. the rationale behind this is that all templates become are normal HTML pages and do not need extra text nodes containing the conditional / template logic. (like liquid, mustache, others..). This means pages can be developed and tested in their pure template form, without needing much (or any) tooling to do so in a nice way.
Templates also allow <script> tags to be run (At compile time) with the static
attribute set.
Please note that the generation does NOT currently expose the normal javascript dom api, such as document.createElement
, etc. It is an empty javascript context only used for templating. If this feature would be useful to you, file an issue with use cases / info.
these are features I'd like to have initially, in no particular order.
- add html parser
- add js engine
- conditional logic with
x-if
(tentative name) - attribute variable expansion (
:href="link.title"
withlink = { title: 'HI' }
->href="HI"
) - layout includes via
layout
js variable andx-content-slot
attribute. - iteration logic with
x-each
(tentative name) Experimentally Implemented - (partially implemented) conditional css class generation (similar to vuejs's :class attribute). (can do bind
:class="compute_class_string_fn()"
) - html partials via
<slot src="file.html"></slot>
. - (partially implemented) filesystem interaction - allow simple load to string from fs
- raw html
- way to extract the contents of a div to replace it. Potentially called
x-extract
- json/yaml/etc data file loading for configuration / data.
- markdown support with front-matter data + rendering (similar to jekyll)
- page-fork rendering: instead of iterating a page via
x-each
, render multiple copies of a page with different elements. To be used for dynamic tagging. (this is a place where jekyll doesn't work well.) - helper application to call the main
docgen
binary for site generation. This is the template engine, from which the actual site generator will discover supported template pages and render them for upload.
brew install yasm autoconf
set AUTOCONF="$(which autoconf)"
cargo build
cargo run -- -i examples/demo.html
- render the page to html if it's markdown.
- render using the main
docgen
process, in a top-down manner.
- evaluate any
script static
tags. - replace all template variables
At the moment, docgen only produces processes html templates. This will change in the future, with options for markdown, etc.
<html>
<head>
<script static>
let links = [{
href: 'https://google.com',
title: 'google'
}, {
href: 'https://apple.com',
title: 'apple'
},{
href: 'https://amazon.com',
title: 'amazon'
}]
</script>
</head>
<body>
<ul>
<li x-for="link in links">
<a :href="link.href">{{link.title}}</a>
</li>
</ul>
</body>
</html>
<html>
<head>
</head>
<body>
<ul>
<li>
<a href="https://google.com">google</a>
</li><li>
<a href="https://apple.com">apple</a>
</li><li>
<a href="https://amazon.com">amazon</a>
</li>
</ul>
</body>
</html>
{% if variable_name %}
<span>Hello, World!</span>
{% endif %}
<span x-if="variable_name">Hello, World</span>
<span class="{{className}}">Test</span>
Note: the :class
binding may be updated in the future to allow a dictionary, which in turn renders to a space-separated class string based on all the keys that have truthy values. (equivalent to: Object.entries(classDict).filter(el => el[1]).map(el => el[0]).join(' ')
)
<span :class="className">Test</span>
note: for loops are not feature complete. All for loops currently bind to item
and the syntax is likely to change.
<ul>
{% for item in items %}
<li>
<a href="{{item.url}}">{{item.title}}</a>
</li>
{% endfor %}
</ul>
<ul>
<li x-for="item in items">
<a :href="item.url">{{item.title}}</a>
</li>
</ul>
<!-- or: -->
<ul>
<li x-each="items" x-as="item">
<a :href="item.url">{{item.title}}</a>
</li>
</ul>
hello.md
<script>
layout = './base.html'
title = 'Example'
</script>
# Hello, World
base.html
<html>
<head>{{child.title}}</head>
<body>
<div x-content-slot></div>
</body>
</html>
out.html
<html>
<head>Example</head>
<body>
<h1>Hello, World</h1>
</body>
</html>
This currently only works with HTML files. In a later revision, they will work with all supported types.
<slot src="./example.html"></slot>