diff --git a/muppet/breadcrumbs.py b/muppet/breadcrumbs.py new file mode 100644 index 0000000000000000000000000000000000000000..ae88d3c172eb9eb13d2d0920813c462075296017 --- /dev/null +++ b/muppet/breadcrumbs.py @@ -0,0 +1,59 @@ +""" +Page breadcrumbs. + +Page breadcrumbs are the "how did we get here" at the top of web pages. + +For example, the page +``/modules/example-module/example-class`` would have a breadcrumb list like + +- ``/modules`` - Modules +- ``/modules/example-module`` - Example Module +- ``/modules/example-module/example-class`` Example Class +""" + +import re +from dataclasses import dataclass +from typing import ( + Tuple, +) + + +@dataclass +class Breadcrumb: + """ + A breadcrumb entry. + + :param ref: + A url path. Meaning that it should contain all parents. + :param text: + The displayed text for this entry. + """ + + ref: str + text: str + + +def breadcrumbs(*items: str | Tuple[str, str]) -> list[Breadcrumb]: + """ + Generate a breadcrumb trail. + + :param items: + The parts of the trace. + + Each item should either be a single string, which is then used + as both the name, and the url component, or a tuple, in which + case the left value will be the displaed string, and the right + value the url component. + """ + url = '/' + result = [] + for item in items: + if isinstance(item, str): + url += item + '/' + text = item + else: + url += item[1] + '/' + text = item[0] + url = re.sub('/+', '/', url) + result.append(Breadcrumb(ref=url, text=text)) + return result diff --git a/muppet/output.py b/muppet/output.py index 0aae7ed110656127769f9792d5c8dbf1268a5694..676bbb464f7e58a61c2b027ad6a42464bead527c 100644 --- a/muppet/output.py +++ b/muppet/output.py @@ -29,6 +29,7 @@ from collections.abc import ( ) from .util import group_by from .puppet.strings import isprivate +from .breadcrumbs import breadcrumbs # TODO replace 'output' with base, or put this somewhere else @@ -301,8 +302,15 @@ def setup_module(base: str, module: ModuleEntry, *, path_base: str) -> None: with open(os.path.join(dir, 'index.html'), 'w') as f: template = jinja.get_template('code_page.html') + crumbs = breadcrumbs( + ('Environment', ''), + module.name, + (puppet_class['name'], + 'manifests/' + '/'.join(puppet_class['name'].split('::')[1:])), + ) f.write(template.render(content=format_class(puppet_class), - path_base=path_base)) + path_base=path_base, + breadcrumbs=crumbs)) # puppet_class['file'] # puppet_class['line'] diff --git a/static/style.css b/static/style.css index fb19678a0ed02564100d9635f7bfad42d1827b0e..7ab8ae0de173b84c0b060e2ec9ae7bec47c64d75 100644 --- a/static/style.css +++ b/static/style.css @@ -80,3 +80,17 @@ code.json { .comment p:last-child { margin-bottom: 0; } + +.breadcrumb { + padding: 0; +} + +.breadcrumb li { + display: inline-block; + padding: 0; +} + +.breadcrumb li:not(:first-child)::before { + content: "ยป"; + padding: 1ex; +} diff --git a/templates/base.html b/templates/base.html index c4351755afe6cbce3b23a25cf744b945892446f4..abc40f1975a8116e9791beda27cdd20cc2728a25 100644 --- a/templates/base.html +++ b/templates/base.html @@ -20,6 +20,15 @@ </noscript> </head> <body> + <header> + {% if breadcrumbs %} + <ul class="breadcrumb"> + {%- for item in breadcrumbs -%} + <li><a href="{{ path_base }}{{ item.ref }}">{{ item.text }}</a></li> + {%- endfor -%} + </ul> + {% endif %} + </header> {% block content %} {% endblock %} </body>