render-engine 2025.10.1a1__tar.gz → 2025.10.3a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/PKG-INFO +1 -1
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/cli.md +6 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/page.md +14 -13
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/parsers.md +7 -3
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/templates.md +7 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/mkdocs.yml +3 -3
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/collection.py +20 -11
- render_engine-2025.10.3a1/src/render_engine/content_managers/__init__.py +7 -0
- render_engine-2025.10.3a1/src/render_engine/content_managers/base_content_manager.py +16 -0
- render_engine-2025.10.3a1/src/render_engine/content_managers/file_content_manager.py +36 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/page.py +32 -11
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/site_map.py +1 -1
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/PKG-INFO +1 -1
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/SOURCES.txt +3 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_page.py +69 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_site_map.py +30 -30
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.all-contributorsrc +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.devcontainer/Dockerfile +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.devcontainer/devcontainer.json +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.devcontainer/setup.sh +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/FUNDING.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/ISSUE_TEMPLATE/config.yaml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/ISSUE_TEMPLATE/form_issue_template.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/dependabot-bot.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/dependabot.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/labeler.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/release.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/devcontainer-ci.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/labeler.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/lint.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/publish.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/scorecard.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/test.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.gitignore +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.markdownlint.json +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.pre-commit-config.yaml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.readthedocs.yml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.vscode/tasks.json +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/CONTRIBUTING.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/README.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/SECURITY.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/.markdownlint.json +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/archive.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/create environment vs code.gif +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/create-app-help.png +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/create-codespace.gif +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/launching a dev container.gif +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/render-engine-init-help.png +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/render-engine-init.png +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/collection.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/contributing/CODE_OF_CONDUCT.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/contributing/CONTRIBUTING.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/contributing/environment_setup.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/custom_collections.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/feeds.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/building-your-site.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/creating-a-collection.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/creating-a-page.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/creating-your-app.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/getting-started.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/installation.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/layout.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/index.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/plugins.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/site.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/site_map.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/theme_management.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/requirements.txt +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/noxfile.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/pyproject.toml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/requirements.txt +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/setup.cfg +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/.gitignore +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/__init__.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/__main__.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/_base_object.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/archive.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/blog.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/engine.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/extras/__init__.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/feeds.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/hookspecs.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/links.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/parsers/markdown.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/plugins.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/py.typed +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/__init__.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/archive.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/base.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/base_collection_path.md +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/base_templates/_archive.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/base_templates/_base.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/base_templates/_page.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/components/footer.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/components/page_title.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/page.html +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/rss2.0.xml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/rss2.0_items.xml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/sitemap.xml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/render_engine_templates/sitemap_item.xml +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/site.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/themes.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/utils/__init__.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/dependency_links.txt +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/requires.txt +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/top_level.txt +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/conftest.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_archive.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_base_object.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_blog.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_collections.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_engine.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_feeds/conftest_feed.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_feeds/test_feeds.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_parsers_remove_2024_3_1.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_plugins.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_site.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_templates/test_base_html.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_theme_manager.py +0 -0
- {render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: render_engine
|
|
3
|
-
Version: 2025.10.
|
|
3
|
+
Version: 2025.10.3a1
|
|
4
4
|
Summary: A Flexible Static Site Generator for Python
|
|
5
5
|
Project-URL: homepage, https://github.com/render-engine/render-engine/
|
|
6
6
|
Project-URL: repository, https://github.com/render-engine/render-engine/
|
|
@@ -7,6 +7,12 @@ tags: ["render-engine", "cli", "site-setup", "build", "serve"]
|
|
|
7
7
|
|
|
8
8
|
Render Engine comes with a CLI that can be used to create, build, and serve your site.
|
|
9
9
|
|
|
10
|
+
> !!! Note
|
|
11
|
+
The CLI is no longer a part of the Render Engine package and must be installed
|
|
12
|
+
separately. To install run `pip install render-engine-cli`. Render Engine can be
|
|
13
|
+
installed together with the CLI as well using
|
|
14
|
+
`pip install render-engine[cli]`.
|
|
15
|
+
|
|
10
16
|
## pyproject.toml Configuration
|
|
11
17
|
|
|
12
18
|
The Render Engine CLI can be configured through your `pyproject.toml` file to set default values and avoid repetitive command-line arguments.
|
|
@@ -63,17 +63,18 @@ When you create a page, you specify variables passed into rendering template.
|
|
|
63
63
|
|
|
64
64
|
**Attributes:**
|
|
65
65
|
|
|
66
|
-
| Name | Type
|
|
67
|
-
| ---
|
|
68
|
-
| `content_path` | `str
|
|
69
|
-
| `extension` | `str
|
|
70
|
-
| `engine` | `str
|
|
71
|
-
| `reference` | `str
|
|
72
|
-
| `routes` | `str
|
|
73
|
-
| `template` | `str
|
|
74
|
-
| `Parser` | `type[BasePageParser]`
|
|
75
|
-
| `title` | `str`
|
|
76
|
-
| `skip_site_map` | `
|
|
66
|
+
| Name | Type | Description |
|
|
67
|
+
| --- |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------|
|
|
68
|
+
| `content_path` | `str \| None` | The path to the file that will be used to generate the Page's `content`. |
|
|
69
|
+
| `extension` | `str \| None` | The suffix to use for the page. Defaults to `.html`. |
|
|
70
|
+
| `engine` | `str \| None` | If present, the engine to use for rendering the page. **This is normally not set and the `Site` 's engine will be used.** |
|
|
71
|
+
| `reference` | `str \| None` | Used to determine how to reference the page in the `Site`'s route_list. Defaults to `slug`. |
|
|
72
|
+
| `routes` | `str \| None` | The routes to use for the page. Defaults to `["./"]`. |
|
|
73
|
+
| `template` | `str \| None` | The template used to render the page. If not provided, the `Site`'s `content`will be used. |
|
|
74
|
+
| `Parser` | `type[BasePageParser]` | The parser to generate the page's `raw_content`. Defaults to `BasePageParser`. |
|
|
75
|
+
| `title` | `str` | The title of the page. Defaults to the class name. |
|
|
76
|
+
| `skip_site_map` | `bool` | When set to `True` the `Page` will not be included in the generated `SiteMap`. Defaults to `False`. |
|
|
77
|
+
| `no_prerender` | `bool` | When set to `True` the `Page`'s `content` will not be pre-rendered as a `Template` even if `{{ site_map }}` is present. Defaults to `False`. |
|
|
77
78
|
|
|
78
79
|
## About Page Attributes
|
|
79
80
|
|
|
@@ -109,8 +110,8 @@ By default Page._content will return the result of `Page.Parser.parse(Page.conte
|
|
|
109
110
|
### Accessing URLs for other pages in the site from within the page content
|
|
110
111
|
|
|
111
112
|
In order to allow lookup of URLs for other pages within a Site the `content` of a page may be
|
|
112
|
-
a template. If the `content` matches the pattern `{{.*?}}` we will render the `content` as a
|
|
113
|
-
template prior to rendering the page itself
|
|
113
|
+
a template. If the `content` matches the pattern `{{.*?site_map.*?}}` we will render the `content` as a
|
|
114
|
+
template prior to rendering the page itself unless the `no_prerender` attribute of the page is `True`.
|
|
114
115
|
|
|
115
116
|
Example:
|
|
116
117
|
|
|
@@ -51,7 +51,7 @@ my_page._render_content()
|
|
|
51
51
|
In many cases, you will want to create rich content. The `MarkdownPageParser`. You can also pass in attributes to the page via frontmatter at the top of the markdown file.
|
|
52
52
|
|
|
53
53
|
```python
|
|
54
|
-
from
|
|
54
|
+
from render_engine_markdown import MarkdownPageParser
|
|
55
55
|
from render_engine.page import Page
|
|
56
56
|
|
|
57
57
|
base_markdown = """
|
|
@@ -63,8 +63,8 @@ This is **dynamic** content
|
|
|
63
63
|
"""
|
|
64
64
|
|
|
65
65
|
class MyPage(Page):
|
|
66
|
-
parser =
|
|
67
|
-
content =
|
|
66
|
+
parser = MarkdownPageParser
|
|
67
|
+
content = base_markdown
|
|
68
68
|
|
|
69
69
|
my_page = MyPage()
|
|
70
70
|
my_page.title
|
|
@@ -78,6 +78,10 @@ my_page._render_content()
|
|
|
78
78
|
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
> !!! Note
|
|
82
|
+
`MarkdownPageParser` is found in the `render_engine_markdown` package.
|
|
83
|
+
To install run `pip install render_engine_markdown`.
|
|
84
|
+
|
|
81
85
|
## Creating Custom Parsers
|
|
82
86
|
|
|
83
87
|
You can create custom parsers.
|
|
@@ -95,3 +95,10 @@ By default this will format to the site's `DATETIME_FORMAT` (default: `"%d %b %Y
|
|
|
95
95
|
{{ page.date | format_datetime("%B %d, %Y") }} --> January 01, 2000
|
|
96
96
|
|
|
97
97
|
```
|
|
98
|
+
|
|
99
|
+
## Site Map
|
|
100
|
+
|
|
101
|
+
Render builds a site map prior to rendering the content. The contents of this
|
|
102
|
+
site map are available to be used in both Page objects (see
|
|
103
|
+
[Page object documentation](/page/#accessing-urls-for-other-pages-in-the-site-from-within-the-page-content).)
|
|
104
|
+
Please see the [site map documentation](/site_map.html) for more information.
|
|
@@ -18,13 +18,12 @@ nav:
|
|
|
18
18
|
- contributing/CONTRIBUTING.md
|
|
19
19
|
- Components:
|
|
20
20
|
- Page Objects: page.md
|
|
21
|
-
- Collection:
|
|
21
|
+
- Collection Objects:
|
|
22
22
|
- Collection: collection.md
|
|
23
23
|
- Custom Collection: custom_collections.md
|
|
24
24
|
- Archive: archive.md
|
|
25
25
|
- RSS Feed: feeds.md
|
|
26
|
-
- Site:
|
|
27
|
-
- Site: site.md
|
|
26
|
+
- Site Objects: site.md
|
|
28
27
|
- Extending Render Engine:
|
|
29
28
|
- Plugins: plugins.md
|
|
30
29
|
- Parsers: parsers.md
|
|
@@ -32,6 +31,7 @@ nav:
|
|
|
32
31
|
- Templates and Themes:
|
|
33
32
|
- Templates: templates.md
|
|
34
33
|
- ThemeManager: theme_management.md
|
|
34
|
+
- Site Map: site_map.md
|
|
35
35
|
|
|
36
36
|
markdown_extensions:
|
|
37
37
|
- toc
|
|
@@ -6,10 +6,12 @@ from pathlib import Path
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
import dateutil.parser as dateparse
|
|
9
|
-
from more_itertools import batched
|
|
9
|
+
from more_itertools import batched
|
|
10
10
|
from render_engine_parser import BasePageParser
|
|
11
11
|
from slugify import slugify
|
|
12
12
|
|
|
13
|
+
from render_engine.content_managers import ContentManager, FileContentManager
|
|
14
|
+
|
|
13
15
|
from ._base_object import BaseObject
|
|
14
16
|
from .archive import Archive
|
|
15
17
|
from .feeds import RSSFeed
|
|
@@ -56,6 +58,9 @@ class Collection(BaseObject):
|
|
|
56
58
|
title: str
|
|
57
59
|
template: str | None
|
|
58
60
|
archive_template str | None: The template to use for the archive pages.
|
|
61
|
+
ContentManager: type[ContentManager] | None = FileContentManager
|
|
62
|
+
content_manager: ContentManager
|
|
63
|
+
content_manager_extras: dict[str, Any]: kwargs to pass to the ContentManager when instantiating
|
|
59
64
|
|
|
60
65
|
Methods:
|
|
61
66
|
|
|
@@ -84,6 +89,8 @@ class Collection(BaseObject):
|
|
|
84
89
|
template_vars: dict[str, Any]
|
|
85
90
|
template: str | None
|
|
86
91
|
plugin_manager: PluginManager | None
|
|
92
|
+
ContentManager: type[ContentManager] | None = FileContentManager
|
|
93
|
+
content_manager_extras: dict[str, Any]
|
|
87
94
|
|
|
88
95
|
def __init__(
|
|
89
96
|
self,
|
|
@@ -102,9 +109,16 @@ class Collection(BaseObject):
|
|
|
102
109
|
self.title = self._title
|
|
103
110
|
self.template_vars = getattr(self, "template_vars", {})
|
|
104
111
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
cm_extras = {
|
|
113
|
+
"content_path": getattr(self, "content_path", None),
|
|
114
|
+
"include_suffixes": getattr(self, "include_suffixes", None),
|
|
115
|
+
"collection": self,
|
|
116
|
+
}
|
|
117
|
+
if hasattr(self, "content_manager_extras"):
|
|
118
|
+
cm_extras.update(self.content_manager_extras)
|
|
119
|
+
self.content_manager = self.ContentManager(**cm_extras)
|
|
120
|
+
if hasattr(self, "pages"):
|
|
121
|
+
self.content_manager.pages = self.pages
|
|
108
122
|
|
|
109
123
|
def get_page(
|
|
110
124
|
self,
|
|
@@ -116,8 +130,6 @@ class Collection(BaseObject):
|
|
|
116
130
|
Parser=self.Parser,
|
|
117
131
|
)
|
|
118
132
|
|
|
119
|
-
if getattr(self, "_pm", None):
|
|
120
|
-
_page.register_plugins(self.plugins, **self.plugin_settings)
|
|
121
133
|
_page.parser_extras = getattr(self, "parser_extras", {})
|
|
122
134
|
_page.routes = self.routes
|
|
123
135
|
_page.template = getattr(self, "template", None)
|
|
@@ -162,7 +174,7 @@ class Collection(BaseObject):
|
|
|
162
174
|
"""
|
|
163
175
|
try:
|
|
164
176
|
return sorted(
|
|
165
|
-
(page for page in self
|
|
177
|
+
(page for page in self),
|
|
166
178
|
key=self._sort_key(self.sort_by),
|
|
167
179
|
reverse=self.sort_reverse,
|
|
168
180
|
)
|
|
@@ -231,10 +243,7 @@ class Collection(BaseObject):
|
|
|
231
243
|
return f"{__name__}"
|
|
232
244
|
|
|
233
245
|
def __iter__(self):
|
|
234
|
-
|
|
235
|
-
self.pages = [self.get_page(page) for page in self.iter_content_path()]
|
|
236
|
-
for page in self.pages: # noqa: UP028
|
|
237
|
-
yield page
|
|
246
|
+
yield from self.content_manager
|
|
238
247
|
|
|
239
248
|
def _run_collection_plugins(self, site, hook_type: str):
|
|
240
249
|
"""
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from collections.abc import Generator, Iterable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ContentManager(ABC):
|
|
6
|
+
"""Base ContentManager abstract class"""
|
|
7
|
+
|
|
8
|
+
@property
|
|
9
|
+
@abstractmethod
|
|
10
|
+
def pages(self) -> Iterable:
|
|
11
|
+
"""The Page objects managed by the content manager"""
|
|
12
|
+
...
|
|
13
|
+
|
|
14
|
+
def __iter__(self) -> Generator:
|
|
15
|
+
"""Iterator for the ContentManager"""
|
|
16
|
+
yield from self.pages
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from more_itertools import flatten
|
|
5
|
+
|
|
6
|
+
from render_engine.content_managers import ContentManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FileContentManager(ContentManager):
|
|
10
|
+
"""Content manager for content stored on the file system as individual files"""
|
|
11
|
+
|
|
12
|
+
def __init__(
|
|
13
|
+
self,
|
|
14
|
+
content_path: Path | str,
|
|
15
|
+
collection,
|
|
16
|
+
include_suffixes: Iterable[str] = ("*.md", "*.html"),
|
|
17
|
+
**kwargs,
|
|
18
|
+
):
|
|
19
|
+
self.content_path = content_path
|
|
20
|
+
self.include_suffixes = include_suffixes
|
|
21
|
+
self.collection = collection
|
|
22
|
+
self._pages = None
|
|
23
|
+
|
|
24
|
+
def iter_content_path(self):
|
|
25
|
+
"""Iterate through in the collection's content path."""
|
|
26
|
+
return flatten([Path(self.content_path).glob(suffix) for suffix in self.include_suffixes])
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def pages(self) -> Iterable:
|
|
30
|
+
if self._pages is None:
|
|
31
|
+
self._pages = [self.collection.get_page(page) for page in self.iter_content_path()]
|
|
32
|
+
yield from self._pages
|
|
33
|
+
|
|
34
|
+
@pages.setter
|
|
35
|
+
def pages(self, value: Iterable):
|
|
36
|
+
self._pages = value
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import re
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Any
|
|
@@ -10,6 +11,8 @@ from render_engine.themes import ThemeManager
|
|
|
10
11
|
from ._base_object import BaseObject
|
|
11
12
|
from .plugins import PluginManager
|
|
12
13
|
|
|
14
|
+
logger = logging.getLogger("Page")
|
|
15
|
+
|
|
13
16
|
|
|
14
17
|
class BasePage(BaseObject):
|
|
15
18
|
"""
|
|
@@ -28,6 +31,8 @@ class BasePage(BaseObject):
|
|
|
28
31
|
extension (str): The file extension for the page. Defaults to ".html".
|
|
29
32
|
routes (list[str] | Path): The list of routes for the page. Defaults to ["./"].
|
|
30
33
|
template (str | Template | None): The template to use for rendering the page.
|
|
34
|
+
site: The Site object that owns the page.
|
|
35
|
+
no_prerender: Flag to not prerender the content
|
|
31
36
|
"""
|
|
32
37
|
|
|
33
38
|
extension: str = ".html"
|
|
@@ -36,7 +41,8 @@ class BasePage(BaseObject):
|
|
|
36
41
|
rendered_content: str | None
|
|
37
42
|
_reference: str = "_slug"
|
|
38
43
|
plugin_manager: PluginManager | None
|
|
39
|
-
site = None
|
|
44
|
+
site = None # This is a Site but circular imports so we can't actually type hint it.
|
|
45
|
+
no_prerender: bool = False
|
|
40
46
|
|
|
41
47
|
@property
|
|
42
48
|
def _content(self) -> any:
|
|
@@ -69,20 +75,35 @@ class BasePage(BaseObject):
|
|
|
69
75
|
return f"/{route}/{self.path_name}"
|
|
70
76
|
|
|
71
77
|
def _render_from_template(self, template: Template, **kwargs) -> str:
|
|
72
|
-
"""
|
|
78
|
+
"""
|
|
79
|
+
Renders the page from a template.
|
|
80
|
+
|
|
81
|
+
If the content looks like a template that
|
|
82
|
+
|
|
83
|
+
:param template: Template to render
|
|
84
|
+
:param **kwargs: Data to pass into the template for rendering.
|
|
85
|
+
:return: The rendered page
|
|
86
|
+
"""
|
|
73
87
|
template_data = {"data": self._data, "content": self._content}
|
|
74
88
|
if site := getattr(self, "site", None):
|
|
75
89
|
template_data["site_map"] = site.site_map
|
|
76
|
-
if isinstance(self._content, str) and re.search(r"{{
|
|
90
|
+
if not self.no_prerender and isinstance(self._content, str) and re.search(r"{{.*?site_map.*?}}", self._content):
|
|
77
91
|
# If the content looks like a template, try to render it.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
try:
|
|
93
|
+
content_template = Template(self._content)
|
|
94
|
+
except Exception:
|
|
95
|
+
logger.info(f"Failed to parse {repr(self.path_name)} as a template.", exc_info=True)
|
|
96
|
+
else:
|
|
97
|
+
try:
|
|
98
|
+
template_data["content"] = content_template.render(
|
|
99
|
+
**{
|
|
100
|
+
**self.to_dict(),
|
|
101
|
+
**template_data,
|
|
102
|
+
**kwargs,
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
except Exception:
|
|
106
|
+
logger.info(f"Failed to pre-render {repr(self.path_name)}.", exc_info=True)
|
|
86
107
|
|
|
87
108
|
return template.render(
|
|
88
109
|
**{
|
|
@@ -22,7 +22,7 @@ class SiteMapEntry:
|
|
|
22
22
|
self._route = f"/{route.lstrip('/')}/{self.path_name}" if from_collection else f"/{self.path_name}"
|
|
23
23
|
self.entries = list()
|
|
24
24
|
case Collection():
|
|
25
|
-
self._route = f"/{
|
|
25
|
+
self._route = f"/{entry.routes[0].lstrip('/')}"
|
|
26
26
|
self.entries = [
|
|
27
27
|
SiteMapEntry(collection_entry, self._route, from_collection=True) for collection_entry in entry
|
|
28
28
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: render_engine
|
|
3
|
-
Version: 2025.10.
|
|
3
|
+
Version: 2025.10.3a1
|
|
4
4
|
Summary: A Flexible Static Site Generator for Python
|
|
5
5
|
Project-URL: homepage, https://github.com/render-engine/render-engine/
|
|
6
6
|
Project-URL: repository, https://github.com/render-engine/render-engine/
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/SOURCES.txt
RENAMED
|
@@ -82,6 +82,9 @@ src/render_engine.egg-info/SOURCES.txt
|
|
|
82
82
|
src/render_engine.egg-info/dependency_links.txt
|
|
83
83
|
src/render_engine.egg-info/requires.txt
|
|
84
84
|
src/render_engine.egg-info/top_level.txt
|
|
85
|
+
src/render_engine/content_managers/__init__.py
|
|
86
|
+
src/render_engine/content_managers/base_content_manager.py
|
|
87
|
+
src/render_engine/content_managers/file_content_manager.py
|
|
85
88
|
src/render_engine/extras/__init__.py
|
|
86
89
|
src/render_engine/parsers/markdown.py
|
|
87
90
|
src/render_engine/render_engine_templates/__init__.py
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import pathlib
|
|
2
3
|
|
|
3
4
|
import jinja2
|
|
@@ -96,3 +97,71 @@ def test_rendered_page_from_template_has_data():
|
|
|
96
97
|
data = [1, 2, 3, 4]
|
|
97
98
|
|
|
98
99
|
assert CustomPage()._render_from_template(template=CustomPage.template) == "1234"
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def test_page_fails_to_render_content_as_template(caplog):
|
|
103
|
+
"""Tests handling content that fails to render as a template"""
|
|
104
|
+
caplog.set_level(logging.INFO)
|
|
105
|
+
|
|
106
|
+
template = "{% for d in data %}{{d}}{% endfor %}\n{{content}}"
|
|
107
|
+
|
|
108
|
+
environment = jinja2.Environment(loader=jinja2.DictLoader({"test.html": template}))
|
|
109
|
+
|
|
110
|
+
class CustomPage(Page):
|
|
111
|
+
template = environment.get_template("test.html")
|
|
112
|
+
data = [1, 2, 3, 4]
|
|
113
|
+
content = "{{ site_map.find('test') }}"
|
|
114
|
+
|
|
115
|
+
assert CustomPage()._render_from_template(template=CustomPage.template) == "1234\n{{ site_map.find('test') }}"
|
|
116
|
+
assert "Failed to pre-render" in caplog.messages[0]
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_braces_ignored_without_sitemap():
|
|
120
|
+
"""Tests that braces in content are ignored without `site_map`"""
|
|
121
|
+
template = "{% for d in data %}{{d}}{% endfor %}\n{{content}}"
|
|
122
|
+
|
|
123
|
+
environment = jinja2.Environment(loader=jinja2.DictLoader({"test.html": template}))
|
|
124
|
+
|
|
125
|
+
class CustomPage(Page):
|
|
126
|
+
template = environment.get_template("test.html")
|
|
127
|
+
data = [1, 2, 3, 4]
|
|
128
|
+
content = "{{ example }}"
|
|
129
|
+
|
|
130
|
+
assert CustomPage()._render_from_template(template=CustomPage.template) == "1234\n{{ example }}"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def test_exception_in_parsing_content_as_template(monkeypatch, caplog):
|
|
134
|
+
"""Test failing to parse content as template"""
|
|
135
|
+
|
|
136
|
+
def mock_template():
|
|
137
|
+
raise jinja2.exceptions.UndefinedError("Mocked error")
|
|
138
|
+
|
|
139
|
+
monkeypatch.setattr("render_engine.page.Template", mock_template)
|
|
140
|
+
caplog.set_level(logging.INFO)
|
|
141
|
+
|
|
142
|
+
template = "{% for d in data %}{{d}}{% endfor %}\n{{content}}"
|
|
143
|
+
|
|
144
|
+
environment = jinja2.Environment(loader=jinja2.DictLoader({"test.html": template}))
|
|
145
|
+
|
|
146
|
+
class CustomPage(Page):
|
|
147
|
+
template = environment.get_template("test.html")
|
|
148
|
+
data = [1, 2, 3, 4]
|
|
149
|
+
content = "{{ site_map.find('test') }}"
|
|
150
|
+
|
|
151
|
+
assert CustomPage()._render_from_template(template=CustomPage.template) == "1234\n{{ site_map.find('test') }}"
|
|
152
|
+
assert "Failed to parse" in caplog.messages[0]
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_no_prerender():
|
|
156
|
+
"""Test pre-rendering does not occur when no_prerender is True"""
|
|
157
|
+
template = "{% for d in data %}{{d}}{% endfor %}\n{{content}}"
|
|
158
|
+
|
|
159
|
+
environment = jinja2.Environment(loader=jinja2.DictLoader({"test.html": template}))
|
|
160
|
+
|
|
161
|
+
class CustomPage(Page):
|
|
162
|
+
template = environment.get_template("test.html")
|
|
163
|
+
data = [1, 2, 3, 4]
|
|
164
|
+
content = "{{ site_map.find('test') }}"
|
|
165
|
+
no_prerender = True
|
|
166
|
+
|
|
167
|
+
assert CustomPage()._render_from_template(template=CustomPage.template) == "1234\n{{ site_map.find('test') }}"
|
|
@@ -60,7 +60,7 @@ def site(tmp_path_factory):
|
|
|
60
60
|
for collection in ["coll1", "coll2"]:
|
|
61
61
|
|
|
62
62
|
class MyColl(Collection):
|
|
63
|
-
routes = [collection]
|
|
63
|
+
routes = [f"{collection}-route"]
|
|
64
64
|
pages = coll_pages[collection]
|
|
65
65
|
|
|
66
66
|
collection_class = MyColl
|
|
@@ -82,19 +82,19 @@ def test_site_map_to_html(site):
|
|
|
82
82
|
sm = SiteMap(site.route_list, "")
|
|
83
83
|
assert sm.html == (
|
|
84
84
|
"<ul>\n"
|
|
85
|
-
'\t<li><a href="/coll1">coll1</a></li>\n'
|
|
85
|
+
'\t<li><a href="/coll1-route">coll1</a></li>\n'
|
|
86
86
|
"\t<ul>\n"
|
|
87
|
-
'\t\t<li><a href="/coll1/page0.html">coll1 -- Page 0</a></li>\n'
|
|
88
|
-
'\t\t<li><a href="/coll1/page1.html">coll1 -- Page 1</a></li>\n'
|
|
89
|
-
'\t\t<li><a href="/coll1/page2.html">coll1 -- Page 2</a></li>\n'
|
|
90
|
-
'\t\t<li><a href="/coll1/page3.html">coll1 -- Page 3</a></li>\n'
|
|
87
|
+
'\t\t<li><a href="/coll1-route/page0.html">coll1 -- Page 0</a></li>\n'
|
|
88
|
+
'\t\t<li><a href="/coll1-route/page1.html">coll1 -- Page 1</a></li>\n'
|
|
89
|
+
'\t\t<li><a href="/coll1-route/page2.html">coll1 -- Page 2</a></li>\n'
|
|
90
|
+
'\t\t<li><a href="/coll1-route/page3.html">coll1 -- Page 3</a></li>\n'
|
|
91
91
|
"\t</ul>\n"
|
|
92
|
-
'\t<li><a href="/coll2">coll2</a></li>\n'
|
|
92
|
+
'\t<li><a href="/coll2-route">coll2</a></li>\n'
|
|
93
93
|
"\t<ul>\n"
|
|
94
|
-
'\t\t<li><a href="/coll2/page0.html">coll2 -- Page 0</a></li>\n'
|
|
95
|
-
'\t\t<li><a href="/coll2/page1.html">coll2 -- Page 1</a></li>\n'
|
|
96
|
-
'\t\t<li><a href="/coll2/page2.html">coll2 -- Page 2</a></li>\n'
|
|
97
|
-
'\t\t<li><a href="/coll2/page3.html">coll2 -- Page 3</a></li>\n'
|
|
94
|
+
'\t\t<li><a href="/coll2-route/page0.html">coll2 -- Page 0</a></li>\n'
|
|
95
|
+
'\t\t<li><a href="/coll2-route/page1.html">coll2 -- Page 1</a></li>\n'
|
|
96
|
+
'\t\t<li><a href="/coll2-route/page2.html">coll2 -- Page 2</a></li>\n'
|
|
97
|
+
'\t\t<li><a href="/coll2-route/page3.html">coll2 -- Page 3</a></li>\n'
|
|
98
98
|
"\t</ul>\n"
|
|
99
99
|
'\t<li><a href="/page0.html">Page 0</a></li>\n'
|
|
100
100
|
'\t<li><a href="/page1.html">Page 1</a></li>\n'
|
|
@@ -109,21 +109,21 @@ def test_site_map_to_html(site):
|
|
|
109
109
|
("page1", {}, "/page1.html"),
|
|
110
110
|
("page1", {"attr": "slug"}, "/page1.html"),
|
|
111
111
|
("page3", {"attr": "slug"}, None),
|
|
112
|
-
("page3", {"attr": "slug", "full_search": True}, "/coll1/page3.html"),
|
|
113
|
-
("page3", {"attr": "slug", "collection": "coll2"}, "/coll2/page3.html"),
|
|
112
|
+
("page3", {"attr": "slug", "full_search": True}, "/coll1-route/page3.html"),
|
|
113
|
+
("page3", {"attr": "slug", "collection": "coll2"}, "/coll2-route/page3.html"),
|
|
114
114
|
("page1.html", {"attr": "path_name"}, "/page1.html"),
|
|
115
115
|
("page3.html", {"attr": "path_name"}, None),
|
|
116
|
-
("page3.html", {"attr": "path_name", "full_search": True}, "/coll1/page3.html"),
|
|
117
|
-
("page3.html", {"attr": "path_name", "collection": "coll2"}, "/coll2/page3.html"),
|
|
116
|
+
("page3.html", {"attr": "path_name", "full_search": True}, "/coll1-route/page3.html"),
|
|
117
|
+
("page3.html", {"attr": "path_name", "collection": "coll2"}, "/coll2-route/page3.html"),
|
|
118
118
|
("page1", {"attr": "slug"}, "/page1.html"),
|
|
119
119
|
("page3", {"attr": "slug"}, None),
|
|
120
|
-
("page3", {"attr": "slug", "full_search": True}, "/coll1/page3.html"),
|
|
121
|
-
("page3", {"attr": "slug", "collection": "coll2"}, "/coll2/page3.html"),
|
|
120
|
+
("page3", {"attr": "slug", "full_search": True}, "/coll1-route/page3.html"),
|
|
121
|
+
("page3", {"attr": "slug", "collection": "coll2"}, "/coll2-route/page3.html"),
|
|
122
122
|
("Page 1", {"attr": "title"}, "/page1.html"),
|
|
123
123
|
("coll1 -- Page 3", {"attr": "title"}, None),
|
|
124
|
-
("coll1 -- Page 3", {"attr": "title", "full_search": True}, "/coll1/page3.html"),
|
|
124
|
+
("coll1 -- Page 3", {"attr": "title", "full_search": True}, "/coll1-route/page3.html"),
|
|
125
125
|
("coll1 -- Page 3", {"attr": "title", "collection": "coll2"}, None),
|
|
126
|
-
("coll2 -- Page 3", {"attr": "title", "collection": "coll2"}, "/coll2/page3.html"),
|
|
126
|
+
("coll2 -- Page 3", {"attr": "title", "collection": "coll2"}, "/coll2-route/page3.html"),
|
|
127
127
|
],
|
|
128
128
|
)
|
|
129
129
|
def test_site_map_search(site, value, params, expected):
|
|
@@ -137,7 +137,7 @@ def test_site_map_search(site, value, params, expected):
|
|
|
137
137
|
|
|
138
138
|
def test_find_in_template(site):
|
|
139
139
|
site.render()
|
|
140
|
-
assert (site.output_path / "page1.html").read_text() == "Page 1\n/coll1/page0.html"
|
|
140
|
+
assert (site.output_path / "page1.html").read_text() == "Page 1\n/coll1-route/page0.html"
|
|
141
141
|
|
|
142
142
|
|
|
143
143
|
def test_site_map_to_xml(site):
|
|
@@ -148,34 +148,34 @@ def test_site_map_to_xml(site):
|
|
|
148
148
|
== """<?xml version="1.0" encoding="UTF-8"?>
|
|
149
149
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
150
150
|
<url>
|
|
151
|
-
<loc>http://localhost:8000/coll1</loc>
|
|
151
|
+
<loc>http://localhost:8000/coll1-route</loc>
|
|
152
152
|
</url>
|
|
153
153
|
<url>
|
|
154
|
-
<loc>http://localhost:8000/coll1/page0.html</loc>
|
|
154
|
+
<loc>http://localhost:8000/coll1-route/page0.html</loc>
|
|
155
155
|
</url>
|
|
156
156
|
<url>
|
|
157
|
-
<loc>http://localhost:8000/coll1/page1.html</loc>
|
|
157
|
+
<loc>http://localhost:8000/coll1-route/page1.html</loc>
|
|
158
158
|
</url>
|
|
159
159
|
<url>
|
|
160
|
-
<loc>http://localhost:8000/coll1/page2.html</loc>
|
|
160
|
+
<loc>http://localhost:8000/coll1-route/page2.html</loc>
|
|
161
161
|
</url>
|
|
162
162
|
<url>
|
|
163
|
-
<loc>http://localhost:8000/coll1/page3.html</loc>
|
|
163
|
+
<loc>http://localhost:8000/coll1-route/page3.html</loc>
|
|
164
164
|
</url>
|
|
165
165
|
<url>
|
|
166
|
-
<loc>http://localhost:8000/coll2</loc>
|
|
166
|
+
<loc>http://localhost:8000/coll2-route</loc>
|
|
167
167
|
</url>
|
|
168
168
|
<url>
|
|
169
|
-
<loc>http://localhost:8000/coll2/page0.html</loc>
|
|
169
|
+
<loc>http://localhost:8000/coll2-route/page0.html</loc>
|
|
170
170
|
</url>
|
|
171
171
|
<url>
|
|
172
|
-
<loc>http://localhost:8000/coll2/page1.html</loc>
|
|
172
|
+
<loc>http://localhost:8000/coll2-route/page1.html</loc>
|
|
173
173
|
</url>
|
|
174
174
|
<url>
|
|
175
|
-
<loc>http://localhost:8000/coll2/page2.html</loc>
|
|
175
|
+
<loc>http://localhost:8000/coll2-route/page2.html</loc>
|
|
176
176
|
</url>
|
|
177
177
|
<url>
|
|
178
|
-
<loc>http://localhost:8000/coll2/page3.html</loc>
|
|
178
|
+
<loc>http://localhost:8000/coll2-route/page3.html</loc>
|
|
179
179
|
</url>
|
|
180
180
|
<url>
|
|
181
181
|
<loc>http://localhost:8000/page0.html</loc>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/.github/workflows/devcontainer-ci.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/create-app-help.png
RENAMED
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/create-codespace.gif
RENAMED
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/render-engine-init-help.png
RENAMED
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/assets/render-engine-init.png
RENAMED
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/contributing/CODE_OF_CONDUCT.md
RENAMED
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/contributing/CONTRIBUTING.md
RENAMED
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/contributing/environment_setup.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/creating-a-page.md
RENAMED
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/getting-started.md
RENAMED
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/docs/docs/getting-started/installation.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/extras/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine/parsers/markdown.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/requires.txt
RENAMED
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/src/render_engine.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_parsers_remove_2024_3_1.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{render_engine-2025.10.1a1 → render_engine-2025.10.3a1}/tests/test_templates/test_base_html.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|