Help language development. Donate to The Perl Foundation

Uzu cpan:SACOMO last updated on 2018-11-27

Uzu-0.2.6/

Uzu (渦) build status

Uzu is a static site generator with built-in web server, file modification watcher, live reload, i18n, themes, and multi-page support.

Features

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 you find.

Getting started

After installing 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:

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

# 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'"

Config variables

Config variables are defined in config.yml:

  • exclude_pages: List page templates that should not be rendered for the associated theme. yaml themes: <ul> <li>summer2017: exclude_pages: <ul> <li>about</li> <li>blog/fiji</li> <li>sitemap.xml
  • exclude: List of directories and files to exclude from build/ yaml exclude: <ul> <li>node_modules</li> <li>packages.json</li> <li>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 ..
  • 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 for a full example.

    Public and Assets directories

    Files found in either of these directories are copied wholesale to the root of the build/ directory on successful build. For example:

    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:

    ---
    # 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).

    <h1>[% i18n.site_name %]</h1>
    

    Nested i18n variable files

    Any variables defined in page specific i18n files, e.g. i18n/blog/vacation/en.yml, will override any top-level language i18n file (e.g i18n/en.yml) defined variables that share the same name. For example:

    # i18n/en.yml
    site_name: Uzu Starter Project
    

    ...will be overridden by:

    # i18n/blog/vacation/en.yml
    site_name: "Our Vacation 2017"
    

    Template Features

    Template6

    Uzu supports the Template Toolkit templating format for template files. This is the default template engine.

    Features include:

    Examples (Template6)

    Single i18n variable

    <a class="navbar-brand" href="/">[% i18n.site_name %]</a>
    

    For loop from yaml dict (non-core variable) defined in config.yml

    <h1>Company Founders</h1>
    <ul>
    [% for founder in site.founders %]
      <li>[% founder.name %], [% founder.title %]</a>
    [% end %]
    </ul>
    

    IF/ELSEIF/UNLESS

    [% if site.graphics %]
        <img src="[% images %]/logo.gif" align=right width=60 height=40>
    [% end %]
    

    Mustache

    Uzu also supports the Mustache templating format for template files.

    Enable mustache support by adding the following line to your config.yml:

    template_engine: mustache

    For example:

    ---
    name: mysite
    language:
      - en
    theme: default
    template_engine: mustache
    

    Examples (Mustache)

    Single i18n variable

    <a class="navbar-brand" href="/">{{ i18n.site_name }}</a>
    

    For loop from yaml dict (non-core variable) defined in config.yml

    <h1>Company Founders</h1>
    <ul>
    {{#founders}}
      <li>{{ name }}, {{ title }}</a>
    {{/founders}}
    </ul>
    

    If conditionals

    Mustache is a 'logic-less' templating system, but you can test for the existence of a variable, and if it exists then anything inside the test block with be processed. Otherwise it is ignored.

    {{#site.graphics}}
        <img src="{{ images }}/logo.gif" align=right width=60 height=40>
    {{/site.graphics}}
    

    Theme layouts

    Theme layout templates are located at the themes/THEME_NAME/layout.tt or themes/THEME_NAME/layout.mustache. Use the content partial to include rendered page content in a layout.

    For Template6:

    <!doctype html>
    <html lang="[% language %]">
    [% INCLUDE "head" %]
        <body>
          [% INCLUDE "navigation" %]
          <!-- Rendered page content -->
          [% INCLUDE "content" %]
          [% INCLUDE "footer" %]
        </body>
    </html>
    

    For Mustache:

    <!doctype html>
    <html lang="{{ language }}">
    {{> head }}
        <body>
          {{> navigation }}
          <!-- Rendered page content -->
          {{> content }}
          {{> footer }}
        </body>
    </html>
    

    Partials

    Partials are stored in the partials and themes/THEME_NAME/partials directories. Any theme partial will override any partial found in the top-level partials directory with the same file name. Partials can be include in layouts, pages, and other partials.

    For Template6:

    [% INCLUDE "navigation" %]
    <div>
        [% INCLUDE "login_form" %]
    </div>
    

    For Mustache:

    {{> navigation }}
    <div>
        {{> login_form }}
    </div>
    

    Global variables

    Some variables are generated dynamically and exposed to templates for use:

    Template variables

    You can define variables using a yaml block at the top of any page or partial (pages/, partials/):

    pages/index.tt

    ---
    title: 'Welcome to Uzu'
    date:  '2017/07/16'
    ---
    

    To access these variables inside of a template you do not need to use the i18n. scope prefix.

    For Template6:

    partials/head.tt

    <head>
        <meta charset="utf-8">
        <title>[% title %] - [% date %]</title>
    </head>
    

    ...and for Mustache:

    partials/head.mustache

    <head>
        <meta charset="utf-8">
        <title>{{ title }} - {{ date }}</title>
    </head>
    

    Layout variables

    You can define variables in the layout template and access them using the layout. prefix in templates;

    For example:

    Define yaml definitions in themes/**/layout.tt or themes/**/layout.mustache:

    ---
    root_url: https://www.perl6.org
    name: Dark Theme
    ---
    <!doctype html>
    <html>
    ...
    

    Will be accessible in templates like this:

    For Template6:

    <a href="[% layout.root_url %]/about-this-theme.html">[% layout.name %]</a>
    

    ...and for Mustache:

    <a href="{{ layout.root_url }}/about-this-theme.html">{{ layout.name }}</a>
    

    Uzu will append any yaml dict ending with _pages with additional page-related variables if the variables are defined in the associated page template.

    ---
    related_pages:
        - page: about
        - page: blog/fiji
        - page: https://www.perl6.org
          title: The Perl 6 Programming Language
          author: Perl 6
    ---
    <ul>
    {{#related_pages}}
        <li>
            <a href="{{ url }}">{{ title }}</a> [{{ author }}]
        </li>
    {{/related_pages}}
    </ul>
    

    The above produces the following HTML. Note that the author and title values are pulled from the related page's template yaml variables:

    <ul>
        <li>
            <a href="/about.html">About Us</a> [Camelia]
        </li>
        <li>
            <a href="/blog/fiji.html">Fiji Vacation</a> [Camelia]
        </li>
        <li>
            <a href="https://www.perl6.org">The Perl 6 Programming Language</a> [Perl 6]
        </li>
    </ul>
    

    Disable layout rendering for page template

    To disable layout rendering for specific pages add the nolayout variable to the page's yaml variables:

    ---
    nolayout: true
    ---
    

    Page render conditions

    In order to reduce build times Uzu will try to avoid rerendering a page if it hasn't been modified.

    Pages will only be rendered under the following conditions:

    Installation

    zef install Uzu
    

    Installation issue? See Troubleshooting.

    Todo

    Requirements

    Troubleshooting

    Authors

    Contributors

    License

    Uzu is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0. (Note that, unlike the Artistic License 1.0, version 2.0 is GPL compatible by itself, hence there is no benefit to having an Artistic 2.0 / GPL disjunction.) See the file LICENSE for details.

    See also