mirror of
https://github.com/copier-org/copier.git
synced 2025-05-22 23:51:17 +00:00
101 lines
3.3 KiB
Markdown
101 lines
3.3 KiB
Markdown
# 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][context-hook].**
|
|
|
|
The [`ContextHook` extension][context-hook] lets you modify the context used to render
|
|
templates, so that you can add, change or remove variables.
|
|
|
|
[context-hook]:
|
|
https://github.com/copier-org/copier-templates-extensions#context-hook-extension
|
|
|
|
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](#jinja_extensions).
|
|
|
|
You can then configure your Jinja extensions in Copier's configuration file:
|
|
|
|
```yaml title="copier.yaml"
|
|
_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:
|
|
|
|
```yaml title="copier.yaml"
|
|
flavor:
|
|
type: str
|
|
choices:
|
|
- docker
|
|
- instances
|
|
- kubernetes
|
|
- none
|
|
```
|
|
|
|
The `context.py` file contains your context hook which could look like:
|
|
|
|
```python title="extensions/context.py"
|
|
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:
|
|
|
|
```python title="extensions/context.py"
|
|
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!
|