Skip to content

Commit

Permalink
Upgraded pathing structure to handle multiple and better handling of …
Browse files Browse the repository at this point in the history
…default locations and better readme
  • Loading branch information
stard0g committed Mar 18, 2020
1 parent abc1cdd commit b521b2d
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 42 deletions.
68 changes: 48 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,33 +35,19 @@ You are then able to use the mkdocs `extra: {}` hash to pass context data into y
> **Note:** If you have no `plugins` entry in your config file yet, you'll likely also want to add the `search` plugin. MkDocs enables it by default if there is no `plugins` entry set, but now you have to enable it explicitly.


### Using external data files

If the `extra: {}` hash is not enough for your data then you are able to make use of external yaml files to provide that context data

```yaml
plugins:
- search
- markdownextradata:
data: path/to/datafiles
```

The data path is optional; when absent, it will look for a `_data`
folder adjacent to your `mkdocs.yml` and inside your `docs_dir`.
If this path is found, the plugin will read all `.yml` and `.json`
files inside it and add the data in them to the data available to the templates.
The paths to these become their variable names, so if inside your data folder you have a file
called `sections/captions.yml`, the data inside that file will be available in your
templates as `sections.captions`.


## Features

### Use Extra Variables in your markdown files

The variables you define in the mkdown.yml `extra:` slot will become available in your templates

```yaml
site_name: My fantastic site
plugins:
- search
- markdownextradata
extra:
customer:
name: Your name here
Expand All @@ -76,6 +62,48 @@ and then in your `*.md` files
<a href="{{ customer.web }}">{{ customer.web }}</a>
```

### Using external data files

If the `extra: {}` hash is not enough for your data then you are able to make use of external yaml files to provide that context data

```yaml
plugins:
- search
- markdownextradata:
data: path/to/datafiles
```

or if you have multiple locations provide a comma (,) separated list of locations

```yaml
plugins:
- search
- markdownextradata:
data: path/to/datafiles, another/path/to/datafiles
```

if you leave `markdownextradata.data` empty

```yaml
plugins:
- search
- markdownextradata
```

by default it will search in the folder where your mkdocs.yml is kept
and in the docs folder for another folder called `_data`

i.e. `./docs/_data/site.yaml` - available as '{{ site.whatever_variable_in_the_yaml}}'

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.

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`.



## Testing

```
Expand Down
60 changes: 39 additions & 21 deletions markdownextradata/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import json
import yaml
import mkdocs
from mkdocs.plugins import BasePlugin

from jinja2 import Template
from pathlib import Path
Expand All @@ -16,7 +17,7 @@
str_type = mkdocs.utils.string_types


class MarkdownExtraDataPlugin(mkdocs.plugins.BasePlugin):
class MarkdownExtraDataPlugin(BasePlugin):
"""
Inject certain config variables into the markdown
"""
Expand All @@ -37,36 +38,53 @@ def __add_data__(self, config, namespace, data):
holder[namespace[0]] = data

def on_pre_build(self, config):
# this loads all data from the supplied data directory, or otherwise a _data directory next to mkdocs.yml or inside the docs_dir. Does nothing if the dir does not exist.
# Loads all data from the supplied data directories
# or, otherwise a _data directory next to mkdocs.yml and/or inside the docs_dir.
# Does nothing if the dir does not exist.

data = self.config.get("data")
for datadir in [
os.path.dirname(config["config_file_path"]),
config["docs_dir"],
]:
if not data:
data = os.path.join(datadir, "_data")
if not os.path.exists(data):
data = None
# assume an empty list if not defined
data_source_folders = self.config.get("data")
# cast as a list if is defined but is a string
if isinstance(data_source_folders, str):
data_source_folders = data_source_folders.split(',')

if data and os.path.exists(data):
path = Path(data)
for filename in chain(path.glob("**/*.yml"), path.glob("**/*.json")):
with open(filename) as f:
namespace = os.path.splitext(os.path.relpath(filename, data))[0]
# if we have not value, then proceed to look in default folders
# and assume a _data folder, add to list of folders to check
if not data_source_folders:
for datadir in [
os.path.dirname(config["config_file_path"]),
config["docs_dir"],
]:
ds_folder = os.path.join(datadir, "_data")
if os.path.exists(ds_folder):
data_source_folders.append(ds_folder)

if not data_source_folders:
return

# iterate of a list of folders and look for data files
for ds_folder in data_source_folders:
if os.path.exists(ds_folder):
path = Path(ds_folder)
for filename in chain(
path.glob("**/*.yaml"),
path.glob("**/*.yml"),
path.glob("**/*.json"),
):
namespace = os.path.splitext(os.path.relpath(filename, ds_folder))[0]
# add data into dict based on its path as a namespace
self.__add_data__(
config,
namespace,
(
yaml.load(f, Loader=yaml.FullLoader)
if filename.suffix == ".yml"
else json.load(f)
yaml.load(filename.read_bytes(), Loader=yaml.FullLoader)
if filename.suffix in [".yml", ".yaml"]
else json.load(filename.read_bytes())
),
)

def on_page_markdown(self, markdown, config, **kwargs):
context = {key: config.get(key) for key in CONFIG_KEYS if key in config}
context.update(config.get("extra", {}))
extra = config.get("extra")
md_template = Template(markdown)
return md_template.render(**extra)
return md_template.render(**config.get("extra"))
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def run_tests(self):

setup(
name='mkdocs-markdownextradata-plugin',
version='0.1.2',
version='0.1.3',
description='A MkDocs plugin that injects the mkdocs.yml extra variables into the markdown template',
long_description=read('README.md'),
long_description_content_type='text/markdown',
Expand Down

0 comments on commit b521b2d

Please sign in to comment.