rosscdh / mkdocs-markdownextradata-plugin

A MkDocs plugin that injects the mkdocs.yml extra variables into the markdown template
MIT License
83 stars 18 forks source link

Variable naming restrictions #34

Closed operte closed 3 years ago

operte commented 3 years ago

I'm working on a project with lots of different .md files. For a lot of these we need to import variables specific to each of the files. Our idea is to export these variables into a .yaml file per .md file and use mkdocs-markdownextradata-plugin to use those variables in the text.

mkdocs-markdownextradata-plugin does exactly this, but we have an issue: all out filenames start with numbers and we want our .yaml and .md files to have the same name. However, Jinja2 has variable naming restrictions similar to those of Python (see here), so starting a variable with a number is not possible.

Here's an example of the file structure:

mkdocs.yaml
docs/
    1_foo.md
    assets/
        1_foo.yaml

The plugins section of mkdocs.yaml:

plugins:
    - search
    - markdownextradata:
        data: docs/assets

1_foo.yaml:

bar: 42

1_foo.md:

The answer to everything is {{1_foo.bar}}

When I mkdocs serve this I get the following error:

  File "/home/operte/workspace/conda/envs/py36/lib/python3.6/site-packages/markdownextradata/plugin.py", line 97, in on_page_markdown
    return self.apply_template(markdown)
  File "/home/operte/workspace/conda/envs/py36/lib/python3.6/site-packages/markdownextradata/plugin.py", line 107, in apply_template
    md_template = self.env.from_string(template_string)
  File "/home/operte/workspace/conda/envs/py36/lib/python3.6/site-packages/jinja2/environment.py", line 941, in from_string
    return cls.from_code(self, self.compile(source), globals, None)
  File "/home/operte/workspace/conda/envs/py36/lib/python3.6/site-packages/jinja2/environment.py", line 638, in compile
    self.handle_exception(source=source_hint)
  File "/home/operte/workspace/conda/envs/py36/lib/python3.6/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/home/operte/workspace/conda/envs/py36/lib/python3.6/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "<unknown>", line 22, in template
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got '_foo'

We were wondering if there's a workaround for this already in place in this plugin or if we could come up with something (for example letting the plugin add an underscore prefix (so {{ _1_foo.bar }} could work).

rosscdh commented 3 years ago

Hey there,

unfortunately the project is subject the restrictions of the

implementing language. I am also not comfortable impementing some kind of renaming pattern to cater to this issue.

As you have already indicated simply start the file with _ which should enable you!

I wish you the best for your project! Ross

On Thu, Feb 25, 2021 at 9:52 AM João Moura notifications@github.com wrote:

I'm working on a project with lots of different .md files. For a lot of these we need to import variables specific to each of the files. Our idea is to export these variables into a .yaml file per .md file and use mkdocs-markdownextradata-plugin to use those variables in the text.

mkdocs-markdownextradata-plugin does exactly this, but we have an issue: all out filenames start with numbers and we want our .yaml and .md files to have the same name. However, Jinja2 has variable naming restrictions similar to those of Python (see here https://stackoverflow.com/questions/17687534/jinja2-variables-naming-are-variables-naming-restrictions-the-same-as-for-pyth), so starting a variable with a number is not possible.

Here's an example of the file structure:

mkdocs.yaml docs/ 1_foo.md assets/ 1_foo.yaml

The plugins section of mkdocs.yaml:

plugins:

  • search
  • markdownextradata: data: docs/assets

1_foo.yaml:

bar: 42

1_foo.md:

The answer to everything is {{1_foo.bar}}

We were wondering if there's a workaround for this already in place in this plugin or if we could come up with something (for example letting the plugin add an underscore prefix (so {{ _1_foo.bar }} could work).

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rosscdh/mkdocs-markdownextradata-plugin/issues/34, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA6MU7VG5MSKHP2S5B4ODTAYFUFANCNFSM4YGCWHMA .

operte commented 3 years ago

Hi @rosscdh! Thanks for the quick reply.

I was discussing this together with @timvink and we think that it is rather common for documentation files to start with numbers, so we believe this issue might happen with other users. Nevertheless, we understand your concerns in making exceptions just for this particular issue, so we thought of a different way to solve this.

This is an issue with the Jinja2 dot notation to less verbosely access dictionary items. One can instead use the normal python dictionary notation instead to access the elements. In my previous example, if I had told markdownextradata to search for files inside docs instead of docs/assets, I could have called my variable with {{assets['1_foo']['bar']}} and this works fine.

Our first proposal is thus that we catch the TemplateSyntaxError in the apply_template function and forward the user to an explanation of why this happens and how to fix it, in the documentation.

In the case that we search for files inside docs/assets, from our interpetation of the codebase of markdownextradata, it should be possible to access the variables as {{extra['1_foo']['bar']}}. Our second proposal is to change apply_template so that the user can also call extra and not just the elements under extra.

We would be happy to making a PR to fix these issues, if you are open to it.

operte commented 3 years ago

An alternative to letting the user call extra is to include the main folder declared on the data parameter in the namespace.

For example, right now given the folder structure on my first comment and data: docs/assets, assets is not available in the namespace, only whatever is inside assets. If we made assets available I think this would make the system more flexible.

If this were permitted, then one could simply declare data: docs and access all variables inside any file in docs (with any name) as {{docs['assets']['1_foo']['bar']}}.

We could make this such that it doesn't interfere with the current namespacing method that you already have in place, so it is retrocompatible.

rosscdh commented 3 years ago

Sure! am happy to take PRs guys! Please feel free!

On Thu, Feb 25, 2021 at 3:57 PM João Moura notifications@github.com wrote:

An alternative to letting the user call extra is to include the main folder declared on the data parameter in the namespace.

For example, right now given the folder structure on my first comment and data: docs/assets, assets is not available in the namespace, only whatever is inside assets. If we made assets available I think this would make the system more flexible.

If this were permitted, then one could simply declare data: docs and access all variables inside any file in docs (with any name) as {{docs['assets']['1_foo']['bar']}}.

We could make this such that it doesn't interfere with the current namespacing method that you already have in place, so it is retrocompatible.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rosscdh/mkdocs-markdownextradata-plugin/issues/34#issuecomment-785961690, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADA6MUCQFNJ4GEECUWZCW3TAZQOJANCNFSM4YGCWHMA .