From 2e81caa7b7704be0b68df7d3716695c17fadd2f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Apr 2022 19:06:38 +0200 Subject: [PATCH 01/13] docs: Document the context hook extension --- docs/configuring.md | 145 ++++++++++++++++++++++++++++++++++- docs/reference/subproject.md | 4 + 2 files changed, 148 insertions(+), 1 deletion(-) diff --git a/docs/configuring.md b/docs/configuring.md index 64db9944a..6c03dc0bd 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -701,7 +701,8 @@ on them, so they are always installed when Copier is installed. - [`copier_templates_extensions.TemplateExtensionLoader`](https://github.com/pawamoy/copier-templates-extensions): enhances the extension loading mecanism to allow templates writers to put their - extensions directly in their templates. + extensions directly in their templates. It also allows to modify the context before + rendering templates, see [using a context hook](#using-a-context-hook). - [`jinja_markdown.MarkdownExtension`](https://github.com/jpsca/jinja-markdown): provides a `markdown` tag that will render Markdown to HTML using [PyMdown extensions](https://facelessuser.github.io/pymdown-extensions/). @@ -1035,6 +1036,148 @@ _commit: v1.0.0 By default, copier will copy from the last release found in template git tags, sorted as [PEP 440][]. +## Augmenting Copier's context before rendering + +[TL;DR: Using a context hook](#using-a-context-hook) + +Most of the time, only a few questions/answers are needed to render simple templates. +But as your template grows, both in complexity and functionality, you may find yourself +in a situation where you need to ask more and more questions to users, and to use more +and more Jinja conditions in your templated files, making them hard to read and +maintain. + +As it happens, you find that to simplify your template, you would like to be able to add +or change variables of the Jinja context used to render templated files and folders, as +it would allow to get rid of some questions that would then become redundant, and would +not need to be asked to the users anymore. + +An example was brought up by a Copier user. Let say you support multiple flavors of +containerization for Terraform projects generated with your template: + +```yaml title="copier.yaml" +flavor: + type: str + choices: + - Docker + - Instances + - Kubernetes + - None +``` + +You generate different files depending on users answers: + +``` +. +├── {% if flavor == 'docker' %}ecs{% endif %} +├── {% if flavor == 'kubernetes' %}eks{% endif %} +├── {% if flavor == 'instance' %}bastion{% endif %} +├── {% if flavor == 'docker' or flavor == 'kubernetes' %}portainer{% endif %} +└── {% if flavor != 'none' %}vpc{% endif %} +``` + +Each of these folders then have multiple templated files that must also repeat again and +again these Jinja conditions to render the contents correctly. + +You can reduce repetitions with +[macros](https://jinja.palletsprojects.com/en/2.10.x/templates/#macros) or updated +context objects that you can import from special templated files +([see issue #229](https://github.com/copier-org/copier/issues/229#issuecomment-661686740)). + +It would be easier if you could add variables to the context, like `isDocker`, or +`hasContainers` when either Docker or Kubernetes was selected. It would make it easier +to write your templated files and folders since you would just have to use the added +variables instead of potentially complex Jinja conditions: + +``` +. +├── {% if isDocker %}ecs{% endif %} +├── {% if isKubernetes %}eks{% endif %} +├── {% if isInstance %}bastion{% endif %} +├── {% if hasContainers %}portainer{% endif %} +└── {% if isLite %}vpc{% endif %} +``` + +We have good news for you: this is possible. A Copier/Jinja extension was written +specially for this use-case: +[copier-templates-extensions](https://github.com/copier-org/copier-templates-extensions) +and its +[`ContextHook` extension](https://github.com/copier-org/copier-templates-extensions#context-hook-extension). + +### Using a context hook + +The +[`ContextHook` extension](https://github.com/copier-org/copier-templates-extensions#context-hook-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. If Copier was installed with pip in a +virtualenv, just `pip install copier-templates-extensions` as well, and tell your users +to do the same. If Copier was installed with +[pipx](https://github.com/pipx-project/pipx), inject it with +`pipx inject copier copier-templates-extensions`, and tell your users to do the same. + +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. This file contains your context hook: + +```python +from copier_templates_extensions import ContextHook + + +class ContextUpdater(ContextHook): + def hook(self, context): + flavor = context["flavor"] + 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 +from copier_templates_extensions import ContextHook + + +class ContextUpdater(ContextHook): + update = False + + def hook(self, context): + context["isDocker"] = context["flavor"] == "docker" + context["isK8s"] = context["flavor"] == "kubernetes" + context["isInstances"] = context["flavor"] == "instances" + context["isLite"] = context["flavor"] == "none" + + context["isNotDocker"] = context["flavor"] != "docker" + context["isNotK8s"] = context["flavor"] != "kubernetes" + context["isNotInstances"] = context["flavor"] != "instances" + context["isNotLite"] = context["flavor"] != "none" + + context["hasContainers"] = context["isDocker"] or context["isK8s"] + + del context["flavor"] +``` + +Now you can use these added variables in your Jinja templates, and in files and folders +names! + ## Patterns syntax Copier supports matching names against patterns in a gitignore style fashion. This works diff --git a/docs/reference/subproject.md b/docs/reference/subproject.md index 571d4dc0f..f3c15c0ab 100644 --- a/docs/reference/subproject.md +++ b/docs/reference/subproject.md @@ -1 +1,5 @@ +| Some | Table | +| ---- | ----- | +| Some | Cell | + ::: copier.subproject From 9df68b06d5fce93c1d900062c7619bdfe3d046a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Apr 2022 19:16:40 +0200 Subject: [PATCH 02/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuring.md b/docs/configuring.md index 6c03dc0bd..7f04c06e7 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -1128,7 +1128,7 @@ _jinja_extensions: Following this example, you are supposed to provide a `context.py` file in the `extensions` folder at the root of your template. This file contains your context hook: -```python +```python title="extensions/context.py" from copier_templates_extensions import ContextHook @@ -1152,7 +1152,7 @@ Before rendering each templated file/folder, the context will be updated with th `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 +```python title="extensions/context.py" from copier_templates_extensions import ContextHook From 68ccb7f0209e2533a01dec294bab35c7ea7b731f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Apr 2022 19:18:03 +0200 Subject: [PATCH 03/13] fixup! docs: Document the context hook extension --- docs/reference/subproject.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/reference/subproject.md b/docs/reference/subproject.md index f3c15c0ab..571d4dc0f 100644 --- a/docs/reference/subproject.md +++ b/docs/reference/subproject.md @@ -1,5 +1 @@ -| Some | Table | -| ---- | ----- | -| Some | Cell | - ::: copier.subproject From 9d06dc945c3d578caa8465b8d8702358e2b7abeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Apr 2022 19:25:02 +0200 Subject: [PATCH 04/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuring.md b/docs/configuring.md index 7f04c06e7..3e11c56b0 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -699,7 +699,7 @@ on them, so they are always installed when Copier is installed. provides a `slugify` filter using [python-slugify](https://github.com/un33k/python-slugify). - - [`copier_templates_extensions.TemplateExtensionLoader`](https://github.com/pawamoy/copier-templates-extensions): + - [`copier_templates_extensions.TemplateExtensionLoader`](https://github.com/copier-org/copier-templates-extensions): enhances the extension loading mecanism to allow templates writers to put their extensions directly in their templates. It also allows to modify the context before rendering templates, see [using a context hook](#using-a-context-hook). From f431f005dce1c39fae99e251c18c82981169330b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Thu, 14 Apr 2022 19:30:26 +0200 Subject: [PATCH 05/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/configuring.md b/docs/configuring.md index 3e11c56b0..6631e9c2e 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -1149,7 +1149,7 @@ class ContextUpdater(ContextHook): ``` 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 +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" @@ -1160,18 +1160,21 @@ class ContextUpdater(ContextHook): update = False def hook(self, context): - context["isDocker"] = context["flavor"] == "docker" - context["isK8s"] = context["flavor"] == "kubernetes" - context["isInstances"] = context["flavor"] == "instances" - context["isLite"] = context["flavor"] == "none" + flavor = context["flavor"] + + context["isDocker"] = flavor == "docker" + context["isK8s"] = flavor == "kubernetes" + context["isInstances"] = flavor == "instances" + context["isLite"] = flavor == "none" - context["isNotDocker"] = context["flavor"] != "docker" - context["isNotK8s"] = context["flavor"] != "kubernetes" - context["isNotInstances"] = context["flavor"] != "instances" - context["isNotLite"] = context["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"] ``` From 6df42b081ecdfccb5c659d564977f222e5ebbbf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Fri, 15 Apr 2022 10:30:55 +0200 Subject: [PATCH 06/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/docs/configuring.md b/docs/configuring.md index 6631e9c2e..04fba83df 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -1079,7 +1079,7 @@ Each of these folders then have multiple templated files that must also repeat a again these Jinja conditions to render the contents correctly. You can reduce repetitions with -[macros](https://jinja.palletsprojects.com/en/2.10.x/templates/#macros) or updated +[macros](https://jinja.palletsprojects.com/en/3.0.x/templates/#macros) or updated context objects that you can import from special templated files ([see issue #229](https://github.com/copier-org/copier/issues/229#issuecomment-661686740)). @@ -1111,11 +1111,7 @@ lets you modify the context used to render templates, so that you can add, chang 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. If Copier was installed with pip in a -virtualenv, just `pip install copier-templates-extensions` as well, and tell your users -to do the same. If Copier was installed with -[pipx](https://github.com/pipx-project/pipx), inject it with -`pipx inject copier copier-templates-extensions`, and tell your users to do the same. +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: @@ -1148,9 +1144,9 @@ class ContextUpdater(ContextHook): } ``` -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: +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 From 8ef1300ab6509d5160842d094fd035e63f41f85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Fri, 15 Apr 2022 10:31:10 +0200 Subject: [PATCH 07/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/configuring.md b/docs/configuring.md index 04fba83df..f236413e2 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -1111,7 +1111,8 @@ lets you modify the context used to render templates, so that you can add, chang 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](#jinja_extensions). +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: From d62397951249805d6406d26abe52d59c10f2efd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 17 Apr 2022 21:02:19 +0200 Subject: [PATCH 08/13] fixup! docs: Document the context hook extension --- docs/comparisons.md | 6 ++ docs/configuring.md | 142 -------------------------------------------- docs/faq.md | 86 +++++++++++++++++++++++++++ mkdocs.yml | 1 + 4 files changed, 93 insertions(+), 142 deletions(-) create mode 100644 docs/faq.md diff --git a/docs/comparisons.md b/docs/comparisons.md index 89ad29fbe..264df34bb 100644 --- a/docs/comparisons.md +++ b/docs/comparisons.md @@ -26,6 +26,7 @@ docs! We don't want to be biased, but it's easy that we tend to be: | Requires programming | No | No | Yes, JS | | Requires templates to have a suffix | Yes by default, configurable[^3] | No, not configurable | You choose | | Task hooks | Yes | Yes | Yes | +| Context hooks | Yes[^5] | Yes | ? | | Template in a subfolder | Not required, but you choose | Yes, required | Yes, required | | Template package format | Git repo[^2], Git bundle, folder | Git or Mercurial repo, Zip file | NPM package | | Template updates | **Yes**[^4] | No | No | @@ -49,3 +50,8 @@ docs! We don't want to be biased, but it's easy that we tend to be: [^4]: Only for git templates, because Copier uses git tags to obtain available versions and extract smart diffs between them. + +[^5]: Context hooks are provided through the [`ContextHook` extension][context-hook]. + +[context-hook]: + https://github.com/copier-org/copier-templates-extensions#context-hook-extension diff --git a/docs/configuring.md b/docs/configuring.md index f236413e2..b6f5bd402 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -1036,148 +1036,6 @@ _commit: v1.0.0 By default, copier will copy from the last release found in template git tags, sorted as [PEP 440][]. -## Augmenting Copier's context before rendering - -[TL;DR: Using a context hook](#using-a-context-hook) - -Most of the time, only a few questions/answers are needed to render simple templates. -But as your template grows, both in complexity and functionality, you may find yourself -in a situation where you need to ask more and more questions to users, and to use more -and more Jinja conditions in your templated files, making them hard to read and -maintain. - -As it happens, you find that to simplify your template, you would like to be able to add -or change variables of the Jinja context used to render templated files and folders, as -it would allow to get rid of some questions that would then become redundant, and would -not need to be asked to the users anymore. - -An example was brought up by a Copier user. Let say you support multiple flavors of -containerization for Terraform projects generated with your template: - -```yaml title="copier.yaml" -flavor: - type: str - choices: - - Docker - - Instances - - Kubernetes - - None -``` - -You generate different files depending on users answers: - -``` -. -├── {% if flavor == 'docker' %}ecs{% endif %} -├── {% if flavor == 'kubernetes' %}eks{% endif %} -├── {% if flavor == 'instance' %}bastion{% endif %} -├── {% if flavor == 'docker' or flavor == 'kubernetes' %}portainer{% endif %} -└── {% if flavor != 'none' %}vpc{% endif %} -``` - -Each of these folders then have multiple templated files that must also repeat again and -again these Jinja conditions to render the contents correctly. - -You can reduce repetitions with -[macros](https://jinja.palletsprojects.com/en/3.0.x/templates/#macros) or updated -context objects that you can import from special templated files -([see issue #229](https://github.com/copier-org/copier/issues/229#issuecomment-661686740)). - -It would be easier if you could add variables to the context, like `isDocker`, or -`hasContainers` when either Docker or Kubernetes was selected. It would make it easier -to write your templated files and folders since you would just have to use the added -variables instead of potentially complex Jinja conditions: - -``` -. -├── {% if isDocker %}ecs{% endif %} -├── {% if isKubernetes %}eks{% endif %} -├── {% if isInstance %}bastion{% endif %} -├── {% if hasContainers %}portainer{% endif %} -└── {% if isLite %}vpc{% endif %} -``` - -We have good news for you: this is possible. A Copier/Jinja extension was written -specially for this use-case: -[copier-templates-extensions](https://github.com/copier-org/copier-templates-extensions) -and its -[`ContextHook` extension](https://github.com/copier-org/copier-templates-extensions#context-hook-extension). - -### Using a context hook - -The -[`ContextHook` extension](https://github.com/copier-org/copier-templates-extensions#context-hook-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](#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. This file contains your context hook: - -```python title="extensions/context.py" -from copier_templates_extensions import ContextHook - - -class ContextUpdater(ContextHook): - def hook(self, context): - flavor = context["flavor"] - 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"] - - 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! - ## Patterns syntax Copier supports matching names against patterns in a gitignore style fashion. This works diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 000000000..42726eb5e --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,86 @@ +# 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. This file contains your context hook: + +```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"] + + 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! diff --git a/mkdocs.yml b/mkdocs.yml index 9ef2f5343..1d6b1dc9e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,7 @@ nav: - user_data.py: "reference/user_data.md" - vcs.py: "reference/vcs.md" - Comparisons: comparisons.md + - Frequently Asked Questions: faq.md - Contributing: "contributing.md" - Changelog: "changelog.md" From 5a01efd86bb9fee190dd1f4d67c63bbca410362f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 17 Apr 2022 21:19:20 +0200 Subject: [PATCH 09/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuring.md b/docs/configuring.md index b6f5bd402..76273c0fc 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -702,7 +702,7 @@ on them, so they are always installed when Copier is installed. - [`copier_templates_extensions.TemplateExtensionLoader`](https://github.com/copier-org/copier-templates-extensions): enhances the extension loading mecanism to allow templates writers to put their extensions directly in their templates. It also allows to modify the context before - rendering templates, see [using a context hook](#using-a-context-hook). + rendering templates, see [using a context hook](../faq#how-can-i-alter-the-context-before-rendering-the-project). - [`jinja_markdown.MarkdownExtension`](https://github.com/jpsca/jinja-markdown): provides a `markdown` tag that will render Markdown to HTML using [PyMdown extensions](https://facelessuser.github.io/pymdown-extensions/). From 03d5b6458ce13a7b65f3f65cc4a553d491f0b136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 17 Apr 2022 21:19:43 +0200 Subject: [PATCH 10/13] fixup! docs: Document the context hook extension --- docs/faq.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index 42726eb5e..6148951c5 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -4,18 +4,19 @@ 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?** +- **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. +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 +[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 From a3039d2aa48f3bde9575a450dc04454f1a3fcfd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 24 Apr 2022 11:06:13 +0200 Subject: [PATCH 11/13] Update docs/faq.md Co-authored-by: Tom Verdaat <66591885+verdaatt@users.noreply.github.com> --- docs/faq.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index 6148951c5..fec7c8570 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -31,7 +31,20 @@ _jinja_extensions: ``` Following this example, you are supposed to provide a `context.py` file in the -`extensions` folder at the root of your template. This file contains your context hook: +`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 From e078499a68a6c8fbbcf55c35689416d8f10d4061 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 24 Apr 2022 11:06:19 +0200 Subject: [PATCH 12/13] Update docs/faq.md Co-authored-by: Tom Verdaat <66591885+verdaatt@users.noreply.github.com> --- docs/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/faq.md b/docs/faq.md index fec7c8570..e8883f6ab 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -78,7 +78,7 @@ class ContextUpdater(ContextHook): update = False def hook(self, context): - flavor = context["flavor"] + flavor = context["flavor"] # user's answer to the "flavor" question context["isDocker"] = flavor == "docker" context["isK8s"] = flavor == "kubernetes" From 4c370de53300846674e5a80a9087ef414a6b4195 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Mazzucotelli?= Date: Sun, 24 Apr 2022 11:08:38 +0200 Subject: [PATCH 13/13] fixup! docs: Document the context hook extension --- docs/configuring.md | 3 ++- docs/faq.md | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/docs/configuring.md b/docs/configuring.md index 76273c0fc..8f7610592 100644 --- a/docs/configuring.md +++ b/docs/configuring.md @@ -701,7 +701,8 @@ on them, so they are always installed when Copier is installed. - [`copier_templates_extensions.TemplateExtensionLoader`](https://github.com/copier-org/copier-templates-extensions): enhances the extension loading mecanism to allow templates writers to put their - extensions directly in their templates. It also allows to modify the context before + extensions directly in their templates. It also allows to modify the rendering context + (the Jinja variables that you can use in your templates) before rendering templates, see [using a context hook](../faq#how-can-i-alter-the-context-before-rendering-the-project). - [`jinja_markdown.MarkdownExtension`](https://github.com/jpsca/jinja-markdown): provides a `markdown` tag that will render Markdown to HTML using diff --git a/docs/faq.md b/docs/faq.md index e8883f6ab..db9b54bba 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -31,17 +31,17 @@ _jinja_extensions: ``` 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: +`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 + type: str + choices: + - Docker + - Instances + - Kubernetes + - None ``` The `context.py` file contains your context hook which could look like: