Uzu (渦) [![build status](https://travis-ci.org/scmorrison/uzu.svg?branch=master)](https://travis-ci.org/scmorrison/uzu) === Uzu is a static site generator with built-in web server, file modification watcher, live reload, i18n, themes, multi-page support, inject external data via local Perl 6 module, and external pre/post command execution. - [Features](#features) - [Getting started](#getting-started) - [Usage](#usage) - [Config](#config) * [Config variables](#config-variables) - [Project folder structure (Template6)](#project-folder-structure-template6) - [Project folder structure (Mustache)](#project-folder-structure-mustache) - [Public and Assets directories](#public-and-assets-directories) - [i18n YAML and Templating](#i18n-yaml-and-templating) * [Nested i18n variable files](#nested-i18n-variable-files) * [i18n output paths](#i18n-output-paths) - [Template Features](#template-features) * [Template6](#template6) + [Examples](#examples-template6) * [Mustache](#mustache) + [Examples](#examples-mustache) * [Theme layouts](#theme-layouts) * [Partials](#partials) * [Global variables](#global-variables) * [Extended variables](#extended-variables) * [Template variables](#template-variables) * [Layout variables](#layout-variables) * [Related / linked pages](#related--linked-pages) - [Page render conditions](#page-render-conditions) - [Installation](#installation) - [Todo](#todo) - [Requirements](#requirements) - [Troubleshooting](#troubleshooting) - [Authors](#authors) - [Contributors](#contributors) - [License](#license) - [See also](#see-also) Features ======== * **Easy to use**: Based on existing static site generator conventions * **Built-in development webserver**: Test your modifications (http://localhost:3000) as you work * **Auto Re-render**: `uzu watch` monitors the `theme/[your-theme]/`, `pages/`, `partials/`, and `i18n/` folders for modifications and auto-renders to build * **Live reload**: `uzu watch` automatically reloads the browser when a re-render occurs * **Templating**: Supports [Template6](#template6) and [Mustache](#mustache) template engines. * **i18n support**: Use YAML to define each language in the `i18n/` folder (e.g. `i18n/en.yml`) * **Page / layout support**: Generate individual pages wrapped in the same theme layout * **Extended variables**: Inject dynamically generated data into project via external `Perl 6` module. * **Pre/Post commands**: Trigger external commands to execute before or after build. * **YAML variables**: Create page-specific and partial-specific variables as a [YAML block](#page-variables) at the top of any page or partial template. * **Trigger rebuild manually**: Press `r enter` to initiate a full rebuild. This is useful for when you add new files or modify files that are not actively monitored by `uzu`, e.g. images, css, fonts, or any non `.tt`, `.mustache`, or `.yml` files * **Actively developed**: More features coming soon (e.g. more tests, AWS, Github Pages, SSH support...) **Note**: Uzu is a work in progress. It is functional and does a bunch of cool stuff, but it isn't perfect. Please post any [issues](https://github.com/scmorrison/uzu/issues) you find. Getting started =============== After [installing](#installation) uzu, run the following command from an empty directory: ``` uzu init ``` Enter your site name, default language, and template engine when prompted. Usage ===== ``` Usage: uzu init - Initialize new project uzu webserver - Start local web server uzu build - Render all templates to build uzu clear - Delete build directory and all of its contents uzu watch - Start web server and re-render build on template modification uzu version - Print uzu version and exit Optional arguments: --config= - Specify a custom config file Default is `config` e.g. uzu --config=path/to/config.yml init --no-livereload - Disable livereload when running uzu watch. --clear - Delete build directory before render when running with build. --page-filter - Restrict build to pages starting from this directory --theme - Limit build / watch to single theme e.g. uzu --theme=default build ``` Config ====== Each project has its own `config.yml` which uses the following format: ```yaml --- # # Core variables # # Name of the project name: uzu-starter # Languages to use, determines which # i18n/*.yml file to use for string variables # # The first language in the list is considered # the default language. The defualt language # will render to non-suffixed files (e.g index.html). # All other languages will render with the # language as a file suffix (e.g index-fr.html, # index-ja.html). This will be overridable in # future releases. language: - en - ja - fr # i18n scheme (default: suffix) i18n_scheme: 'directory' # Render non-default languages to /[lang]/[page name].[extension] # Template engine # - Template6: tt # - Mustache: mustache template_engine: mustache # Stored theme directories under themes/[theme-name] # # Themes can be specified with either the single theme # variable: theme: default # .. or multiple themes: themes: - default # Specify a theme directory using the default options - summer2017: build_dir: web2017 # Override build director port: 4333 # Port to start watch on for this theme. exclude_pages: # List of page template names to ignore for this theme - index # Optional parameters (also, comments like this are ok) # Use a custom dev server port, default is 3000 port: 4040 # Specify a custom project root path # default is . project_root: path/to/project/folder # List of page template names to ignore for all themes exclude_pages: - about - blog/fiji-scratch # List of directories and files to exclude from build/ exclude: - node_modules - packages.json - yarn.lock # Pre / post build commands pre_command: "webpack" post_command: "echo 'post-build command'" # Omit .html extension from generated HTML files omit_html_ext: true ``` ### Config variables Config variables are defined in `config.yml`: * `name`: Project name * `language`: List of languages to render for site. First item is default language. When rendering, the `language` variable is set to the current rendering language and can be referenced in templates. For example, if `uzu` is rendering an `en` version of a page, then the `language` variable will be set to `en`. * `i18n_scheme`: By default `uzu` will generate files with the language suffix appended for non-default language output. (e.g. `fr`: `index-fr`). This behaviour can be set to 'directory' witch will render non-default languages to `/[lang]/[page name].[extension]` (e.g. `fr`: `/fr/index.html`). * `theme`: The theme to apply to the layout (themes/themename). `default` refers to the folder named `default` in the themes folder. * `themes`: Alternatively, using the `themes` yaml hash supports multiple themes. Themes will be rendered at the same time into their target build directories. By default the theme build directory is `build/[theme-name]`. This can be overridden with the `build_dir` variable. Relative and absolute paths are supported: * `build_dir`: ```yaml themes: - summer2017: build_dir: web2017 ``` * `port`: A dev web server will spawn for rach theme specified in the `themes` yaml dict. The default port for the first theme is `3000`, this port number is incremented by one for every subsequent theme listed in the `themes` dict. This variable will override that behavior. ```yaml themes: - summer2017: port: 4444 ``` * `exclude_pages`: List page templates that should not be rendered for the associated theme. ```yaml themes: - summer2017: exclude_pages: - about - blog/fiji - sitemap.xml ``` * `exclude`: List of directories and files to exclude from `build/` ```yaml exclude: - node_modules - packages.json - yarn.lock ``` * `pre_command`: Run command prior to build step * `post_command`: Run command after to build step * `host`: Host IP for the dev server. Defaults to `127.0.0.1`. * `port`: Host TCP port for dev server. Defaults to `3000`. * `project_root`: Project root folder. Defaults to `.`. * `omit_html_ext`: Omit `.html` from generated HTML files. ### Accessing config variables in templates Config variables can be accessed from inside templates directly (e.g. `port`, `theme`, etc.) ### Accessing non-core variables in templates Non-core variables are any additional variables found in config.yml and can be accessed in templates using `site.variablename` (e.g. `site.url`, `site.author`). Project folder structure (Template6) ======================== ``` ├── config.yml # Uzu config file ├── pages # Each page becomes a .html file │ ├── about.tt │ ├── index.tt │ └── blog # Pages can be nested in sub-folders. Their URI │ └── vacation.tt # will follow the same path (e.g. /blog/vacation.html) │ ├── partials # Partials can be included in pages │ ├── footer.tt # and theme layouts │ ├── head.tt │ ├── home.tt │ ├── jumbotron.tt │ ├── navigation.tt │ └── profiles.tt ├── public # Static files / assets independant of theme (copied to /) ├── i18n # Language translation files │ └── blog │ └── vacation # i18n variables can be defined for specific pages │ └── en.yml │ ├── en.yml │ ├── fr.yml │ ├── ja.yml └── themes # Project themes └── default ├── assets # Theme specific static files / assets (copied to /) │ ├── css │ ├── favicon.ico │ ├── fonts │ ├── img │ ├── js ├── partials # Theme specific partials. These will override any top-level │ ├── footer.tt # partials with the same file name. └── layout.tt # Theme layout file ``` Project folder structure (Mustache) ======================== ``` ├── config.yml # Uzu config file ├── pages # Each page becomes a .html file │ ├── about.mustache │ ├── index.mustache │ └── blog # Pages can be nested in sub-folders. Their URI │ └── vacation.mustache # will follow the same path (e.g. /blog/vacation.html) │ ├── partials # Partials can be included in pages │ ├── footer.mustache # and theme layouts │ ├── head.mustache │ ├── home.mustache │ ├── jumbotron.mustache │ ├── navigation.mustache │ └── profiles.mustache ├── public # Static files / assets independant of theme (copied to /) ├── i18n # Language translation files │ └── blog │ └── vacation # i18n variables can be defined for specific pages │ └── en.yml │ ├── en.yml │ ├── fr.yml │ ├── ja.yml └── themes # Project themes └── default ├── assets # Theme specific static files / assets (copied to /) │ ├── css │ ├── favicon.ico │ ├── fonts │ ├── img │ ├── js ├── partials # Theme specific partials. These will override any top-level │ ├── footer.tt # partials with the same file name. └── layout.mustache # Theme layout file ``` See [uzu-starter](https://github.com/scmorrison/uzu-starter) for a full example. # Public and Assets directories * `public/` - The root public directory is where project-wide static assets are stored. * `themes/**/assets/` - The theme's assets directory is where theme-specific static assets are stored. Files found in either of these directories are copied wholesale to the root of the `build/` directory on successful build. For example: * `public/js/site.js` will be copied to `build/js/site.js` * `themes/default/assets/img/logo.png` will be copied to `build/img/logo.png` **Note:** Any tmp / swp files created by editors will also be copied into `build/`. Most editors provide options to configure this behavior. For example, you can have all `vim` `.swp` files saved into a central directory by adding something like this to `~/.vimrc`: ``` set backupdir=~/.vim/backup// set directory=~/.vim/swp// ``` # i18n YAML and Templating You can separate out the content text to YAML files located in a project-root folder called `i18n`. Simply create a separate file for each language, like this: ``` ─ i18n ├── blog │ └── vacation # Page specific i18n variables │ ├── en.yml # en i18n variables for page pages/blog/vacation.tt │ └── ja.yml # ja i18n variables for page pages/blog/vacation.tt ├── en.yml # Main en i18n variables ├── fr.yml # Main fr i18n variables └── ja.yml # Main ja i18n variables ``` An example i18n YAML file might look like this: ```yaml --- # Template access i18n.site_name site_name: The Uzu Project Site # Template access i18n.url url: https://github.com/scmorrison/uzu-starter # Template access i18n.founders founders: - name: Sam title: "Dish Washer" - name: Elly title: CEO - name: Tomo title: CFO # Comments start with a # # Do not use blank values this_will_break_things: do_this_instead: "" ``` ### Accessing i18n variables in templates Variables defined in i18n files can be accessed in templates using the `i18n.variablename` format (e.g. `i18n.site_name`, `i18n.founders`). ```html