3.3 KiB
Frequently Asked Questions
How can I alter the context before rendering the project?
Similar questions:
- How can I add/remove variables to/from the rendering context?
- How to infer context variables based on the users answers, without prompting users?
Answer:
Use the ContextHook
extension.
The ContextHook
extension lets you modify the context used to render
templates, so that you can add, change or remove variables.
In order for Copier to be able to load and use the extension when generating a project,
it must be installed alongside Copier itself. More details in the
jinja_extensions
docs.
You can then configure your Jinja extensions in Copier's configuration file:
_jinja_extensions:
- copier_templates_extensions.TemplateExtensionLoader
- extensions/context.py:ContextUpdater
Following this example, you are supposed to provide a context.py
file in the
extensions
folder at the root of your template to modify the context. If for example
your copier.yaml
contains a multiple-choice variable like this:
flavor:
type: str
choices:
- docker
- instances
- kubernetes
- none
The context.py
file contains your context hook which could look like:
from copier_templates_extensions import ContextHook
class ContextUpdater(ContextHook):
def hook(self, context):
flavor = context["flavor"] # user's answer to the "flavor" question
return {
"isDocker": flavor == "docker"
"isK8s": flavor == "kubernetes"
"isInstances": flavor == "instances"
"isLite": flavor == "none"
"isNotDocker": flavor != "docker"
"isNotK8s": flavor != "kubernetes"
"isNotInstances": flavor != "instances"
"isNotLite": flavor != "none"
"hasContainers": flavor in {"docker", "kubernetes"}
}
Before rendering each templated file/folder, the context will be updated with this new
context object that you return from the hook. If you wish to update the context in-place
rather than update it, set the update
class attribute to false:
from copier_templates_extensions import ContextHook
class ContextUpdater(ContextHook):
update = False
def hook(self, context):
flavor = context["flavor"] # user's answer to the "flavor" question
context["isDocker"] = flavor == "docker"
context["isK8s"] = flavor == "kubernetes"
context["isInstances"] = flavor == "instances"
context["isLite"] = flavor == "none"
context["isNotDocker"] = flavor != "docker"
context["isNotK8s"] = flavor != "kubernetes"
context["isNotInstances"] = flavor != "instances"
context["isNotLite"] = flavor != "none"
context["hasContainers"] = context["isDocker"] or context["isK8s"]
# you can now actually remove items from the context
del context["flavor"]
Now you can use these added variables in your Jinja templates, and in files and folders names!