Skip to content

Commit ba44e0e

Browse files
authored
Add list of siblings for each page (#24)
The `page["siblings"]` list contains all pages (the full dict, not just the ID) that share the same folder with it excluding itself. This is useful for creating index pages (like a list of blog posts). Had to split the final rendering from the MD->HTML conversion so that templates can access the sibling "body" elements (e.g., for summaries).
1 parent cb267d8 commit ba44e0e

File tree

2 files changed

+55
-12
lines changed

2 files changed

+55
-12
lines changed

nene/_api.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# Distributed under the terms of the MIT License.
33
# SPDX-License-Identifier: MIT
44
"""Public functions used for building and serving the website."""
5+
import itertools
56
import logging
67
import shutil
78
from pathlib import Path
@@ -11,7 +12,7 @@
1112
from .crawling import crawl
1213
from .parsing import load_config, load_data, load_jupyter_notebook, load_markdown
1314
from .printing import make_console, print_dict, print_file_stats
14-
from .rendering import make_jinja_env, render_html, render_markdown
15+
from .rendering import make_jinja_env, markdown_to_html, render_markdown, render_output
1516
from .utils import capture_build_info
1617

1718

@@ -103,6 +104,24 @@ def build(config_file, console=None, style=""):
103104
else:
104105
console.print(" None found.")
105106

107+
def get_parent(item):
108+
"""Return the name of the parent of a page for the groupby."""
109+
page = item[1]
110+
return page["parent"]
111+
112+
console.print(":baby: Adding information on sibling pages:", style=style)
113+
grouped = itertools.groupby(sorted(site.items(), key=get_parent), key=get_parent)
114+
for parent, group in grouped:
115+
if parent == ".":
116+
console.print(" . (base)")
117+
else:
118+
console.print(f" {parent}")
119+
# The groups are also (key, value) pairs like dict.items().
120+
siblings = {key for key, value in group}
121+
for page_id in siblings:
122+
console.print(f" ↳ {page_id}")
123+
site[page_id]["siblings"] = [site[i] for i in (siblings - {page_id})]
124+
106125
return site, source_files, config, build_info
107126

108127

@@ -111,18 +130,18 @@ def render(site, config, build, console=None, style=""):
111130
Render the HTML or other outputs from the assembled website sources.
112131
113132
The ``site``, ``config``, and ``build`` variables are passed to the Jinja2
114-
template for rendering both the Markdown (first) and the HTML (second).
133+
template for rendering the final outputs.
115134
116-
Modifies the pages in ``site`` **in place** to add the rendered HTML of
135+
Modifies the pages in ``site`` **in place** to add the rendered output of
117136
each page.
118137
119138
Parameters
120139
----------
121140
site : dict
122141
The generated website as a dictionary of pages. Each page has a unique
123142
ID (usually the relative file path without extension) and is a
124-
dictionary. The rendered HTML of each page is added to ``page["html"]``
125-
**in place**..
143+
dictionary. The rendered output of each page is added to
144+
``page["output"]`` **in place**..
126145
config : dict
127146
Parameters read from the main configuration file.
128147
build: dict
@@ -144,10 +163,15 @@ def render(site, config, build, console=None, style=""):
144163
console.print(f" {page['source']}")
145164
page["markdown"] = render_markdown(page, config, site, build, jinja_env)
146165

147-
console.print(":art: Rendering templates for HTML output:", style=style)
166+
console.print(":art: Converting Markdown content to HTML:", style=style)
167+
for page in site.values():
168+
console.print(f" {page['source']}")
169+
page["body"] = markdown_to_html(page)
170+
171+
console.print(":art: Rendering templates for final outputs:", style=style)
148172
for page in site.values():
149173
console.print(f" {page['path']}{page['template']}")
150-
page["html"] = render_html(page, config, site, build, jinja_env)
174+
page["output"] = render_output(page, config, site, build, jinja_env)
151175

152176

153177
def export(site, files_to_copy, output_dir, console=None, style=""):
@@ -194,7 +218,7 @@ def export(site, files_to_copy, output_dir, console=None, style=""):
194218
destination = output_dir / Path(page["path"])
195219
console.print(f" {str(destination)} ⇒ id: {page['id']}")
196220
destination.parent.mkdir(parents=True, exist_ok=True)
197-
destination.write_text(page["html"], encoding="utf-8")
221+
destination.write_text(page["output"], encoding="utf-8")
198222

199223
console.print(":bar_chart: Writing Jupyter Notebook image files:", style=style)
200224
pages_with_images = [

nene/rendering.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ def make_jinja_env(templates_dir):
2828
return env
2929

3030

31+
def markdown_to_html(page):
32+
"""
33+
Convert the Markdown content of a page to HTML.
34+
35+
Parameters
36+
----------
37+
page : dict
38+
Dictionary with the parsed YAML front-matter and Markdown body.
39+
40+
Returns
41+
-------
42+
html : str
43+
The converted HTML.
44+
45+
"""
46+
html = myst_parser.main.to_html(page["markdown"])
47+
return html
48+
49+
3150
def render_markdown(page, config, site, build, jinja_env):
3251
"""
3352
Render the templates in Markdown content of the page.
@@ -58,14 +77,15 @@ def render_markdown(page, config, site, build, jinja_env):
5877
return markdown
5978

6079

61-
def render_html(page, config, site, build, jinja_env):
80+
def render_output(page, config, site, build, jinja_env):
6281
"""
63-
Render the full HTML for a page, including conversion of Markdown to HTML.
82+
Render the full template output for a page.
6483
6584
Parameters
6685
----------
6786
page : dict
68-
Dictionary with the parsed YAML front-matter and Markdown body.
87+
Dictionary with the page metadata and body content (in HTML not just
88+
Markdown).
6989
config : dict
7090
A dictionary with the default configuration and variables loaded from
7191
the file.
@@ -82,7 +102,6 @@ def render_html(page, config, site, build, jinja_env):
82102
The converted HTML.
83103
84104
"""
85-
page["body"] = myst_parser.main.to_html(page["markdown"])
86105
template = jinja_env.get_template(page["template"])
87106
html = template.render(page=page, config=config, site=site, build=build)
88107
return html

0 commit comments

Comments
 (0)