For the complete documentation index, see llms.txt. This page is also available as Markdown.

Generate

Introduction

The Generate Extension includes the Generate controller, and provides a mechanism for generating common content from template directories. An example use case would be the ability for application developers to easily generate new plugins for their application… similar in other applications such as Chef Software’s chef generate cookbook type utilities.

The Cement Developer Tools use this extension to generate projects, plugins, extensions, scripts, etc for developers building their applications on the framework.

Documentation References:

API References:

Requirements

Cement 3.0.8+:

pip install cement[generate]

Configuration

Application Configuration Settings

This extension honors the following settings under the primary namespace (ex: [myapp]) of the application configuration:

Setting

Description

template_dir

Directory path of a local template directory.

Application Meta Options

This extension honors the following App.Meta options:

Option

Description

template_handler

A template handler to use as the backend for templating

template_dirs

A list of data directories to look for templates

template_module

A python module to look for templates

Usage

Examples

Generate Templates

The Generate Extension looks for a generate sub-directory in all defined template directory paths defined at the application level. If it finds a generate directory it treats all items within that directory as a generate template.

A Generate Template requires a single configuration YAML file called .generate.yml that looks something like:

Generate Template Configuration

The following configurations are supported in a generate template’s config:

ignore

A list of regular expressions to match files that you want to completely ignore

exclude

A list of regular expressions to match files that you want to copy only (not rendered as template)

variables

A list of variable definitions that support the following sub-keys:

Variable Definition Sub-Keys

Key

Description

name

The variable name exposed to the template context (required)

prompt

The prompt displayed to the user. Use prompt: false for a silent variable that takes its default without prompting (requires default)

default

Default value (used on empty input, and as the value for --defaults runs)

case

Optional case transform applied to the value: one of lower, upper, title

validate

Optional regular expression the value must match (generation aborts on mismatch)

type

Cement 3.0.16+ — one of string (default), boolean, choice. See Typed Variables below

extend

Cement 3.0.16+ — list of conditional-effect rules keyed on the resolved value. See extend:

requires

Cement 3.0.16+ — gate this variable on other top-level variables. See requires:

Typed Variables

Cement 3.0.16+

Typed variables let a generate template offer optional features — Y/N toggles and multi-choice pickers that conditionally prompt for extra variables, skip files, and gate on one another. Everything lives in the single variables: list of .generate.yml; each entry may carry a type: and optional extend: / requires: keys.

The mental model:

  • A boolean or choice variable resolves to a real typed value at the top level of the template context — so {% if docker %}

    and {% if web_framework == "flask" %} work directly.

  • An extend: rule fires when the resolved value matches its when:, contributing extra variables: (prompted in place), ignore: patterns (files skipped), and exclude: patterns (files copied verbatim).

  • A requires: key gates a variable on other variables — if the gate fails, the variable is silently resolved to its default and none of its extend: rules fire.

type: string

The classic variable — a plain {name, prompt, default} entry with optional case: / validate:. Omitting type: is equivalent to type: string, so existing templates are unaffected.

type: boolean

A single y/N prompt rendered as <prompt> [(Y)es/(N)o] [<default>]:. With no prompt: key the label defaults to Enable <name>. Input y/yes maps to True, n/no to False, empty input to default. The resolved value is a real Python bool:

For full control of the wording and accepted tokens, give prompt: an object — accept: / reject: are case-insensitive token lists that map the answer to a bool (input matching neither aborts, like a failed validate:):

type: choice

A numbered picker. Each option is either a bare scalar or an object with value: (required — the string the variable resolves to) and an optional prompt: label for the numbered list:

default: is required and must equal one of the option values (validated at config load). It is used on empty input and for --defaults runs.

extend: — conditional effects

Each variable may carry an extend: list. A rule fires when its when: matches the resolved value:

Match form

Example

Applies to

Scalar equality

when: true / when: "flask"

all types

In-list membership

when: ["flask", "fastapi"]

all types

Regular expression

when: "^3\\."

string variables only

A firing rule contributes:

Key

Effect

variables

Extra variables prompted in place, in declaration order (use prompt: false for silent values like versions)

ignore

Regex patterns for files to skip entirely

exclude

Regex patterns for files to copy verbatim (not rendered as templates)

Multiple matching rules compose. An explicit YAML null block (e.g. ignore: with no items) coalesces to an empty list — it does not error.

requires: — variable gating

A variable may be gated on other top-level variables:

Three forms are supported:

Form

Example

Meaning

List

requires: [docker]

each named variable is truthy

Map

requires: {web_framework: flask}

equality

Map+list

requires: {web_framework: [flask, fastapi]}

in-list membership

Multiple entries are AND-ed and resolve order-independently — prerequisites are resolved (and prompted) before their dependents, regardless of declaration order. Interactive prompting is lazy: declining a prerequisite skips the dependent's prompt entirely.

A requires: gate can only reference other top-level variable names (nested extend.variables are not addressable), and a gated variable must have a default: — a missing default raises ValueError.

CLI Invocation

Using Values in Templates

Resolved values land at the top level of the template context — booleans as real bools, choices as strings, and any extend.variables injected by a firing rule as ordinary top-level variables:

Worked Example

The Cement source tree ships a complete working example under demo/generate-features/ — a webapp template combining a string variable (project_name), two booleans (docker, and docker_compose which requires: [docker]), and a choice (web_framework: none/flask/fastapi) with per-branch silent version variables.

Generated with --defaults (docker on, compose on, no framework):

Generated with web_framework=fastapi (everything else default):

Authoring Checklist

  1. Start with your base variables: (plain strings) and template files.

  2. Bucket the optional content — which files/variables belong to which toggle?

  3. Add a type: boolean (or choice) variable per toggle.

  4. Add when: false (or per-choice) ignore: rules for files to drop — remembering that a dependent's cleanup belongs on its prerequisite's decline branch if it must cascade.

  5. Add extend.variables for follow-up prompts (or silent prompt: false metadata) on the enabling branch.

  6. Add requires: for dependencies between toggles.

  7. Gate rendered content inside files with {% if <name> %}.

  8. Test both paths: --defaults and an interactive run that declines each toggle.

Pitfalls & Validation

  • exclude vs ignoreexclude still copies the file (verbatim, no rendering); ignore drops it entirely.

  • Anchor your regexes loosely — patterns match against full paths, so use '.*Dockerfile.*', not 'Dockerfile'.

  • Cyclic requires (A requires B, B requires A) fails fast with a clear ValueError — it will not hang or recurse.

  • requires references variable names only — top-level variables: entries, not arbitrary template variables or nested extend.variables.

  • Schema violations raise ValueError at config load (they survive python -O, unlike assertions): a choice with empty/missing options, a default not present in options, option objects without value:, bool-decoded tokens in accept:/reject:, a requires:-gated variable without a default, and requires: naming an unknown variable.

Last updated