Skip to content

Commit 7d28936

Browse files
authored
Add CLI to generate the site map. (#32)
1 parent 79830e6 commit 7d28936

File tree

2 files changed

+88
-5
lines changed

2 files changed

+88
-5
lines changed

src/render_engine_cli/cli.py

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import click
66
from dateutil import parser as dateparser
77
from dateutil.parser import ParserError
8-
from render_engine import Collection
8+
from render_engine import Collection, Page
9+
from render_engine.site_map import SiteMap
910
from rich.console import Console
1011

1112
from render_engine_cli.event import ServerEventHandler
@@ -25,6 +26,8 @@
2526
validate_module_site,
2627
)
2728

29+
MODULE_SITE_HELP = "The module (python file) and site (the Site object) for your site in the format module:site"
30+
2831
try:
2932
# Get the RE version for display. If it's not set it means we're working locally.
3033
from render_engine.__version__ import version as re_version
@@ -122,7 +125,7 @@ def init(template: str, extra_context: str, no_input: bool, output_dir: Path, co
122125
@click.option(
123126
"--module-site",
124127
type=click.STRING,
125-
# help="The module (python file) and site (the Site object) for your site in the format module:site",
128+
help=MODULE_SITE_HELP,
126129
callback=validate_module_site,
127130
)
128131
@click.option(
@@ -145,7 +148,7 @@ def build(module_site: str, clean: bool):
145148
@click.option(
146149
"--module-site",
147150
type=click.STRING,
148-
# help="The module (python file) and site (the Site object) for your site in the format module:site",
151+
help=MODULE_SITE_HELP,
149152
callback=validate_module_site,
150153
)
151154
@click.option(
@@ -206,7 +209,7 @@ def serve(module_site: str, clean: bool, reload: bool, port: int):
206209
@click.option(
207210
"--module-site",
208211
type=click.STRING,
209-
# help="The module (python file) and site (the Site object) for your site in the format module:site",
212+
help=MODULE_SITE_HELP,
210213
callback=validate_module_site,
211214
)
212215
@click.option(
@@ -347,7 +350,7 @@ def new_entry(
347350
@click.option(
348351
"--module-site",
349352
type=click.STRING,
350-
# help="The module (python file) and site (the Site object) for your site in the format module:site",
353+
help=MODULE_SITE_HELP,
351354
callback=validate_module_site,
352355
)
353356
@click.option(
@@ -396,5 +399,42 @@ def templates(module_site: str, theme_name: str, filter_value: str):
396399
)
397400

398401

402+
@app.command
403+
@click.option(
404+
"--module-site",
405+
type=click.STRING,
406+
help=MODULE_SITE_HELP,
407+
callback=validate_module_site,
408+
)
409+
@click.option(
410+
"-x",
411+
"--xml",
412+
help="Generate site map as XML",
413+
type=click.BOOL,
414+
is_flag=True,
415+
default=False,
416+
)
417+
@click.option("-o", "--output", help="File to output site map to.", type=click.Path(exists=False))
418+
def sitemap(xml: bool, output: click.File, module_site: str):
419+
"""
420+
CLI for generating the site map in HTML (default) or XML to either the console (default) or a file.
421+
"""
422+
module, site_name = split_module_site(module_site)
423+
site = get_site(module, site_name)
424+
site_map = SiteMap(site.route_list, site.site_vars.get("SITE_URL", ""))
425+
if xml:
426+
site.theme_manager.engine.globals.update(site.site_vars)
427+
site_map_page = Page()
428+
site_map_page.template = "sitemap.xml"
429+
site_map_page.site_map = site_map
430+
content = site_map_page._render_content(site.theme_manager.engine)
431+
else:
432+
content = site_map.html
433+
if output:
434+
Path(output).write_text(content)
435+
else:
436+
click.echo(content)
437+
438+
399439
if __name__ == "__main__":
400440
app()

tests/test_cli_commands.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,46 @@ def test_serve_command_with_reload(runner, test_site_module, monkeypatch):
387387

388388
assert result.exit_code == 0, result.output
389389
mock_get_paths.assert_called_once_with(mock_site)
390+
391+
392+
@pytest.mark.parametrize(
393+
"params, expected",
394+
[
395+
([], ["console", "html"]),
396+
(["-x"], ["console", "xml"]),
397+
(["-x", "-o", "sitemap.xml"], ["file", "xml"]),
398+
(["-o", "sitemap.html"], ["file", "html"]),
399+
],
400+
)
401+
def test_sitemap(runner, test_site_module, monkeypatch, params, expected):
402+
"""Tests sitemap generation command"""
403+
404+
class MockSiteMap:
405+
def __init__(self, *args, **kwargs): ...
406+
407+
@property
408+
def html(self):
409+
return "sitemap"
410+
411+
class MockPage:
412+
def __init__(self, *args, **kwargs): ...
413+
414+
def _render_content(self, *args, **kwargs):
415+
return "sitemap"
416+
417+
with (
418+
patch("render_engine_cli.cli.get_site") as mock_get_site,
419+
):
420+
monkeypatch.setattr("render_engine_cli.cli.SiteMap", MockSiteMap)
421+
monkeypatch.setattr("render_engine_cli.cli.Page", MockPage)
422+
mock_site = Mock()
423+
mock_get_site.return_value = mock_site
424+
with runner.isolated_filesystem():
425+
result = runner.invoke(app, ["sitemap", "--module-site", "test:test", *params])
426+
output_loc, output_type = expected
427+
expected_out = f"sitemap.{output_type}"
428+
match output_loc:
429+
case "console":
430+
assert result.output.strip() == "sitemap"
431+
case "file":
432+
assert Path(expected_out).read_text().strip() == "sitemap"

0 commit comments

Comments
 (0)