Add computed fields#
A computed field is a property that the wizard never asks about.
Cookieplone renders its default as a Jinja2 expression and stores the result with the other answers, so template files use it like any answer.
The examples on this page come from the example repository docs/_examples/template-features/ in the Cookieplone source tree.
Define a computed field#
In your template's cookieplone.json, set "format": "computed" on a property, and write the expression in default:
{
"docs_enabled": {
"type": "string",
"format": "computed",
"default": "{{ '1' if cookiecutter.has_docs else '0' }}"
}
}
Expressions reach the answers through the cookiecutter namespace, for example cookiecutter.has_docs.
Use filters in computed fields#
A computed field can transform an answer with a filter:
{
"package_path": {
"type": "string",
"format": "computed",
"default": "{{ cookiecutter.python_package_name | package_path }}"
}
}
Cookieplone's filters are not available by default.
List each filter that the template uses in config.extensions:
{
"config": {
"extensions": [
"cookieplone.filters.package_name",
"cookieplone.filters.package_namespace",
"cookieplone.filters.package_path",
"cookieplone.filters.pascal_case"
]
}
}
A filter that is missing from the list stops the generation with an error such as No filter named 'pascal_case'.
See Use built-in filters.
Order computed fields#
Cookieplone asks all visible questions first.
Then it computes the hidden fields in the order they appear in properties.
A computed field can use every answer to a visible question, and the computed fields that appear before it:
{
"package_path": {
"type": "string",
"format": "computed",
"default": "{{ cookiecutter.python_package_name | package_path }}"
},
"module_path": {
"type": "string",
"format": "computed",
"default": "src/{{ cookiecutter.package_path }}"
}
}
A reference to a computed field that appears later renders as an empty string, without an error. Check the order when a computed value comes out empty.
Add a constant field#
A property with "format": "constant" is hidden too, but Cookieplone uses its default as-is and doesn't render it:
{
"generator": {
"type": "string",
"format": "constant",
"default": "example-templates 1.0"
}
}
Check the result#
The example template defines the computed and constant fields above:
{
"id": "features",
"schema": {
"title": "Template features",
"description": "Validators, computed fields, and filters.",
"version": "2.0",
"properties": {
"project_title": {
"type": "string",
"title": "Project title",
"default": "Example Add-on"
},
"project_slug": {
"type": "string",
"title": "Project slug",
"default": "example-addon",
"validator": "my_validators.no_spaces"
},
"python_package_name": {
"type": "string",
"title": "Python package name",
"default": "collective.example_addon"
},
"author_email": {
"type": "string",
"title": "Author email",
"default": "jane@example.com",
"validator": "cookieplone.validators.not_empty"
},
"has_docs": {
"type": "boolean",
"title": "Add documentation?",
"default": true
},
"package_path": {
"type": "string",
"format": "computed",
"default": "{{ cookiecutter.python_package_name | package_path }}"
},
"module_path": {
"type": "string",
"format": "computed",
"default": "src/{{ cookiecutter.package_path }}"
},
"class_name": {
"type": "string",
"format": "computed",
"default": "{{ cookiecutter.python_package_name | package_name | pascal_case }}"
},
"docs_enabled": {
"type": "string",
"format": "computed",
"default": "{{ '1' if cookiecutter.has_docs else '0' }}"
},
"generator": {
"type": "string",
"format": "constant",
"default": "example-templates 1.0"
}
}
},
"config": {
"extensions": [
"cookieplone.filters.package_name",
"cookieplone.filters.package_namespace",
"cookieplone.filters.package_path",
"cookieplone.filters.pascal_case"
]
}
}
Its README.md uses them:
# {{ cookiecutter.project_title }}
- Package: `{{ cookiecutter.python_package_name }}`
- Namespace: `{{ cookiecutter.python_package_name | package_namespace }}`
- Code: `{{ cookiecutter.module_path }}`
- Main class: `{{ cookiecutter.class_name }}`
- Documentation enabled: {{ cookiecutter.docs_enabled }}
- Generated by: {{ cookiecutter.generator }}
With the default answers, the generated README.md contains:
# Example Add-on
- Package: `collective.example_addon`
- Namespace: `collective`
- Code: `src/collective/example_addon`
- Main class: `ExampleAddon`
- Documentation enabled: 1
- Generated by: example-templates 1.0