Skip to content

richinfante/docgen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

docgen

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.

Feature Roadmap

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" with link = { title: 'HI' } -> href="HI")
  • layout includes via layout js variable and x-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.

Building from source

brew install yasm autoconf
set AUTOCONF="$(which autoconf)"
cargo build

Runing example

cargo run -- -i examples/demo.html

Process

  1. render the page to html if it's markdown.
  2. render using the main docgen process, in a top-down manner.
  • evaluate any script static tags.
  • replace all template variables

Template Examples

At the moment, docgen only produces processes html templates. This will change in the future, with options for markdown, etc.

Source Template

<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>

Result Output

<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>

Converting from liquid

If statements

{% if variable_name %}
<span>Hello, World!</span>
{% endif %}
<span x-if="variable_name">Hello, World</span>

Attribute bindings

<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>

For loops

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>

Template Extension

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>

HTML Include

This currently only works with HTML files. In a later revision, they will work with all supported types.

<slot src="./example.html"></slot>

About

Rust + Spidermonkey + Servo -> Static Site Generator

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published