From ac4d0409932513abd7103b6f585a4fd3b3d108d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moura?= Date: Sat, 27 Feb 2021 20:48:22 +0100 Subject: [PATCH] Allow calling `extra` (#35) * allow calling extra after exception * render extra without exception * extra items override mkdocsConfig items * explain usage of extra on README * print informative error message before jinja exception * add test for extra * add test for numbered files * add Joao to contributors Co-authored-by: Joao Pinto Moura --- README.md | 26 +++++++++++++++++++------- markdownextradata/plugin.py | 11 +++++++++-- test/docs/_data/1_foo.yaml | 1 + test/docs/index.md | 8 ++++++++ test/test_basic.py | 3 +++ 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 test/docs/_data/1_foo.yaml diff --git a/README.md b/README.md index 1766c43..3034bf5 100644 --- a/README.md +++ b/README.md @@ -91,16 +91,27 @@ plugins: ``` by default it will search in the folder where your mkdocs.yml is kept -and in the docs folder for another folder called `_data` +and in the docs folder for another folder called `_data` +(i.e. `./docs/_data/site.yaml`), available as `{{ site.whatever_variable_in_the_yaml}}`. -i.e. `./docs/_data/site.yaml` - available as '{{ site.whatever_variable_in_the_yaml}}' +If these paths are found, the plugin will read all `.yml|.yaml` and `.json` +files inside them and add the data in them under the `extra` key. -If this path is found, the plugin will read all `.yml|.yaml` and `.json` -files inside it and add the data in them, to the template context. +For example, if you have a file called `[path/to/datafiles/]sections/captions.yaml` +which includes a variable `foo` - where `[path/to/datafiles/]` is the path declared +in your configuration under `data` - the data inside that file will be available in + your templates as `{{sections.captions.foo}}` or `{{sections['captions']['foo']}}`. + +Alternatively, you can access all files and variable declared under `data` in template +using `extra` key. +This is particularly useful if your folder or filename do not comply with the Python +variable naming rules. +For example, if you have a file `[path/to/datafiles/]1_example/captions.yaml` +which includes a variable `bar`, writting the template as +`{{1_example.captions.bar}}` returns a `jinja2.exceptions.TemplateSyntaxError` since +the folder `1_example` starts with a number. Instead, you can call this file with + when the template is `{{extra['1_example']['captions']['bar']}}`. -If inside your data folder you have a directory and a file file -called `[path/to/datafiles/]sections/captions.yaml` - where `[path/to/datafiles/]` is the path in your configuration - -the data inside that file will be available in your templates as `sections.captions.whatever_variable_in_the_yaml`. ### Jinja2 Template Engine Configuration @@ -142,3 +153,4 @@ If you want to contribute to the code of this project, please read the [Contribu - [Ross Crawford-d'Heureuse](https://github.com/rosscdh) - [Emiliano Heyns](https://github.com/retorquere) - [Michael Jess](https://github.com/miffels) +- [João Moura](https://github.com/operte) diff --git a/markdownextradata/plugin.py b/markdownextradata/plugin.py index 13db22a..d738ef9 100644 --- a/markdownextradata/plugin.py +++ b/markdownextradata/plugin.py @@ -105,5 +105,12 @@ def on_config(self, mkdocsConfig, **kwargs): # Apply Jinja2 substitution to specified string def apply_template(self, template_string): - md_template = self.env.from_string(template_string) - return md_template.render(**self.mkdocsConfig.get("extra")) + try: + md_template = self.env.from_string(template_string) + return md_template.render({**self.mkdocsConfig, **self.mkdocsConfig.get("extra")}) + except jinja2.exceptions.TemplateSyntaxError: + print(f"ERROR\t- markdownextradata - One or more yaml files might not comply with " + "Python's variable naming conventions. Try accessing the variable through the " + "'extra' dictionary. Check the README for more information.") + raise + diff --git a/test/docs/_data/1_foo.yaml b/test/docs/_data/1_foo.yaml new file mode 100644 index 0000000..9e165fb --- /dev/null +++ b/test/docs/_data/1_foo.yaml @@ -0,0 +1 @@ +bar: 42 \ No newline at end of file diff --git a/test/docs/index.md b/test/docs/index.md index 8172151..850f641 100644 --- a/test/docs/index.md +++ b/test/docs/index.md @@ -2,6 +2,14 @@ Welcome to {{ customer.web_url }} Where we should see junk.a_key: {{ junk.a_key }} +Which can also be written as junk['a_key']: {{junk['a_key']}} + +Or even extra['junk']['a_key']: {{extra['junk']['a_key']}} + +Use `extra` to call a file which violates Python variable naming rules. + +For example, if the file starts with a number: {{extra['1_foo']['bar']}} + Inside the included md file there 3 {{ star }} diff --git a/test/test_basic.py b/test/test_basic.py index cd3d23c..5278910 100644 --- a/test/test_basic.py +++ b/test/test_basic.py @@ -23,6 +23,9 @@ def test_basic_working(): contents = index_file.read_text() assert 'Where we should see junk.a_key: has a value' in contents, f"docs/_data.junk.yaml does not have the right key/val junk.a_key" + assert "Which can also be written as junk['a_key']: has a value" in contents, f"docs/_data.junk.yaml does not have the right key/val junk['a_key']" + assert "Or even extra['junk']['a_key']: has a value" in contents, f"docs/_data.junk.yaml does not have the right key/val extra['junk']['a_key']" + assert "For example, if the file starts with a number: 42" in contents, f"docs/_data.1_foo.yaml does not have the right key/val extra['1_foo']['bar']" assert 'Hi there, Your name here' in contents, f"customer.name is not in index" assert '

Inside the included md file there 3 star

' in contents, f"customer.star is not in index or not rendering as expected" assert f"Welcome to {customer.get('web_url')}" in contents, f"customer.web_url is not in index"