Skip to content

Commit

Permalink
feat: Support custom templates through objects' extra data
Browse files Browse the repository at this point in the history
PR #70: #70
  • Loading branch information
pawamoy authored May 25, 2023
1 parent d35f2d7 commit 8ff2b06
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 14 deletions.
17 changes: 17 additions & 0 deletions docs/usage/extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Extensions

## :warning: Work in Progress!

The Python handler supports extensions through
[*mkdocstrings*' handler extensions](https://mkdocstrings.github.io/usage/handlers/#handler-extensions).

Specifically, additional templates can be added to the handler,
and Griffe extensions can instruct the handler to use a particular template
for a particular object by setting a value in the Griffe object's `extra` dictionary:

```python title="griffe_extension.py"
obj = ... # get a reference to a Griffe object
if "mkdocstrings" not in obj.extra:
obj.extra["mkdocstrings"] = {}
obj.extra["mkdocstrings"]["template"] = "template_name.html"
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ nav:
- Sphinx: usage/docstrings/sphinx.md
- Advanced:
- Customization: usage/customization.md
- Extensions: usage/extensions.md
# defer to gen-files + literate-nav
- Code Reference: reference/
- Development:
Expand Down
4 changes: 3 additions & 1 deletion src/mkdocstrings_handlers/python/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,8 @@ def render(self, data: CollectorItem, config: Mapping[str, Any]) -> str: # noqa
mutabled_config = dict(copy.deepcopy(config))
final_config = ChainMap(mutabled_config, self.default_config)

template = self.env.get_template(f"{data.kind.value}.html")
template_name = rendering.do_get_template(data)
template = self.env.get_template(template_name)

# Heading level is a "state" variable, that will change at each step
# of the rendering recursion. Therefore, it's easier to use it as a plain value
Expand Down Expand Up @@ -335,6 +336,7 @@ def update_env(self, md: Markdown, config: dict) -> None: # noqa: D102 (ignore
self.env.filters["format_signature"] = rendering.do_format_signature
self.env.filters["filter_objects"] = rendering.do_filter_objects
self.env.filters["stash_crossref"] = lambda ref, length: ref
self.env.filters["get_template"] = rendering.do_get_template

def get_anchors(self, data: CollectorItem) -> set[str]: # noqa: D102 (ignore missing docstring)
try:
Expand Down
13 changes: 13 additions & 0 deletions src/mkdocstrings_handlers/python/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,16 @@ def formatter(code: str, line_length: int) -> str:
return format_str(code, mode=mode)

return formatter


def do_get_template(obj: Object) -> str:
"""Get the template name used to render an object.
Parameters:
obj: A Griffe object.
Returns:
A template name.
"""
extra_data = getattr(obj, "extra", {}).get("mkdocstrings", {})
return extra_data.get("template", "") or f"{obj.kind.value}.html"
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{% with heading_level = heading_level + extra_level %}
{% for attribute in attributes|order_members(config.members_order, members_list) %}
{% if not attribute.is_alias or attribute.is_explicitely_exported %}
{% include "attribute.html" with context %}
{% include attribute|get_template with context %}
{% endif %}
{% endfor %}
{% endwith %}
Expand All @@ -42,7 +42,7 @@
{% with heading_level = heading_level + extra_level %}
{% for class in classes|order_members(config.members_order, members_list) %}
{% if not class.is_alias or class.is_explicitely_exported %}
{% include "class.html" with context %}
{% include class|get_template with context %}
{% endif %}
{% endfor %}
{% endwith %}
Expand All @@ -58,7 +58,7 @@
{% for function in functions|order_members(config.members_order, members_list) %}
{% if not (obj.kind.value == "class" and function.name == "__init__" and config.merge_init_into_class) %}
{% if not function.is_alias or function.is_explicitely_exported %}
{% include "function.html" with context %}
{% include function|get_template with context %}
{% endif %}
{% endif %}
{% endfor %}
Expand All @@ -75,7 +75,7 @@
{% with heading_level = heading_level + extra_level %}
{% for module in modules|order_members(config.members_order, members_list) %}
{% if not module.is_alias or module.is_explicitely_exported %}
{% include "module.html" with context %}
{% include module|get_template with context %}
{% endif %}
{% endfor %}
{% endwith %}
Expand All @@ -91,26 +91,26 @@
filter_objects(filters=config.filters, members_list=members_list, keep_no_docstrings=config.show_if_no_docstring)|
order_members(config.members_order, members_list) %}

{% if not (obj.kind.value == "class" and child.name == "__init__" and config.merge_init_into_class) %}
{% if not (obj.is_class and child.name == "__init__" and config.merge_init_into_class) %}

{% if child.kind.value == "attribute" %}
{% if child.is_attribute %}
{% with attribute = child %}
{% include "attribute.html" with context %}
{% include attribute|get_template with context %}
{% endwith %}

{% elif child.kind.value == "class" %}
{% elif child.is_class %}
{% with class = child %}
{% include "class.html" with context %}
{% include class|get_template with context %}
{% endwith %}

{% elif child.kind.value == "function" %}
{% elif child.is_function %}
{% with function = child %}
{% include "function.html" with context %}
{% include function|get_template with context %}
{% endwith %}

{% elif child.kind.value == "module" and config.show_submodules %}
{% elif child.is_module and config.show_submodules %}
{% with module = child %}
{% include "module.html" with context %}
{% include module|get_template with context %}
{% endwith %}

{% endif %}
Expand Down

0 comments on commit 8ff2b06

Please sign in to comment.