render-engine 2025.10.1a2__py3-none-any.whl → 2025.10.3a1__py3-none-any.whl
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/collection.py +20 -11
- render_engine/content_managers/__init__.py +7 -0
- render_engine/content_managers/base_content_manager.py +16 -0
- render_engine/content_managers/file_content_manager.py +36 -0
- render_engine/site_map.py +1 -1
- {render_engine-2025.10.1a2.dist-info → render_engine-2025.10.3a1.dist-info}/METADATA +1 -1
- {render_engine-2025.10.1a2.dist-info → render_engine-2025.10.3a1.dist-info}/RECORD +9 -6
- {render_engine-2025.10.1a2.dist-info → render_engine-2025.10.3a1.dist-info}/WHEEL +0 -0
- {render_engine-2025.10.1a2.dist-info → render_engine-2025.10.3a1.dist-info}/top_level.txt +0 -0
render_engine/collection.py
CHANGED
|
@@ -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
|
render_engine/site_map.py
CHANGED
|
@@ -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/
|
|
@@ -4,7 +4,7 @@ render_engine/__main__.py,sha256=uI7aBBZz0qSDwwwD11nS5oltWsuLw9hStfYo8O1aNws,144
|
|
|
4
4
|
render_engine/_base_object.py,sha256=DIyLdQ6gS4a0DP46zwGYkYIyewh8uRFznJmaUch7d8M,3546
|
|
5
5
|
render_engine/archive.py,sha256=S3-kCmDNVKkEfKDKxcEk-sXkBD0vS0RDnFfPunYkU8g,2072
|
|
6
6
|
render_engine/blog.py,sha256=f9GqFUFsta0KZnFhCiajobpfQyALqvgI5sbLm6zt1zw,1571
|
|
7
|
-
render_engine/collection.py,sha256=
|
|
7
|
+
render_engine/collection.py,sha256=dAGyWdIoXr6S4GMSbPPin4Y5vLJR_onO_85-NEqRaWM,10599
|
|
8
8
|
render_engine/engine.py,sha256=GOtUiq4ny5GHaLSCeH5u1Zk1JnWJVh63vK7etJiwS20,2843
|
|
9
9
|
render_engine/feeds.py,sha256=i-VHsb6pRplMzaenBn6oeqh9yI_N4WVUAExPox6iJgw,921
|
|
10
10
|
render_engine/hookspecs.py,sha256=GhOpw0zTQjfwWOFYYbJ4P7Cvq-oy1MmTPHmd90dr0kg,2292
|
|
@@ -13,8 +13,11 @@ render_engine/page.py,sha256=l6sKWNJ4gBtC_ONEc0u479q3znL-8Q7U_phNqXqmh6w,8988
|
|
|
13
13
|
render_engine/plugins.py,sha256=NXM8QTbbRV-DwgpQRoIhILijJBN4SyYg2Rkk1LUAuZM,4703
|
|
14
14
|
render_engine/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
render_engine/site.py,sha256=URvG7OQSgeFOcrZwrD8vHLUWa6UxDBxIP-UMeLLqhZM,12936
|
|
16
|
-
render_engine/site_map.py,sha256=
|
|
16
|
+
render_engine/site_map.py,sha256=I1p_yMDMy1jpIivgNgZptnsxZa8NkcrpciVJE3DlFlQ,5422
|
|
17
17
|
render_engine/themes.py,sha256=TFG1rd34QCBvBWfeDbawgsn6kprmjsDTa1pdDSwDMic,4207
|
|
18
|
+
render_engine/content_managers/__init__.py,sha256=z1x99J0GNcfqYFrugD0EleiZR6b-sfM6zViDTH1iF0s,161
|
|
19
|
+
render_engine/content_managers/base_content_manager.py,sha256=LSGBRkGbBHMI-oRyoXVTfr5Me-8vYws7NV961VPOnxI,414
|
|
20
|
+
render_engine/content_managers/file_content_manager.py,sha256=yMLT7xBhCw4NLfKuwx-6T_U9I03UTsyTAFz4uxE1uu8,1102
|
|
18
21
|
render_engine/extras/__init__.py,sha256=L4jr4A7Jl-ODnSx1q2fP3_dBo37Dw6yepNRddu1nFNo,72
|
|
19
22
|
render_engine/parsers/markdown.py,sha256=0jpixCaoHaL0IRSvFIljJIRCvFkXoKTEYQNK38LwMDU,287
|
|
20
23
|
render_engine/render_engine_templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -32,7 +35,7 @@ render_engine/render_engine_templates/base_templates/_page.html,sha256=jjrY2BAwl
|
|
|
32
35
|
render_engine/render_engine_templates/components/footer.html,sha256=HkPGGhfN0HcYm7t8zgXWCQ3bsCbT8FxT4_n2-9e1zUE,74
|
|
33
36
|
render_engine/render_engine_templates/components/page_title.html,sha256=l8aE1TY94UPHXHqAyy6jv4IoN2Hv9cbrTPh7ILkMyxg,137
|
|
34
37
|
render_engine/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
35
|
-
render_engine-2025.10.
|
|
36
|
-
render_engine-2025.10.
|
|
37
|
-
render_engine-2025.10.
|
|
38
|
-
render_engine-2025.10.
|
|
38
|
+
render_engine-2025.10.3a1.dist-info/METADATA,sha256=906rgnnlpsL8upgcEtC4-JYstfkIHiqBK2QU6f_fMaw,11895
|
|
39
|
+
render_engine-2025.10.3a1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
40
|
+
render_engine-2025.10.3a1.dist-info/top_level.txt,sha256=aNGALDMsFyrusho04AvUjSivsgEE9tQp_LP_jGr312Q,14
|
|
41
|
+
render_engine-2025.10.3a1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|