re-plugin-pack 2025.6.1b1__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.
@@ -0,0 +1,4 @@
1
+ from .plugins.latest_entries import LatestEntries
2
+ from .plugins.next_prev import NextPrevPlugin
3
+
4
+ __all__ = [LatestEntries, NextPrevPlugin]
@@ -0,0 +1,133 @@
1
+ """Plugin for giving the latest entries"""
2
+
3
+ from render_engine import Collection, Page, Site
4
+ from render_engine.plugins import hook_impl
5
+
6
+
7
+ class LatestEntries:
8
+ """
9
+ Adds a dictionary to the index page's template_vars:
10
+
11
+ default_settings = {
12
+ "collection": ["url"],
13
+ "entries": ["title", "url"],
14
+ "pages": ["index"],
15
+ "max_entries": 3,
16
+ }
17
+
18
+ To override the default number of entries add to the registration:
19
+ {<collection title>: <max entries>}
20
+ To disable set max entries to 0 for that collection
21
+ To print all entries for a given collection set max entries to a negative number
22
+
23
+ Can be registered on the Site object:
24
+ app.register_plugins(LatestEntries, LatestEntries=<settings overrides>)
25
+
26
+ Can be registered for an individual Page include it in the definition of the page:
27
+ @app.page
28
+ class MyPage(Page):
29
+ plugins = [
30
+ (
31
+ LatestEntries,
32
+ {
33
+ "Collection1": 5, # Include the 5 most recent entries
34
+ "Collection2": 0, # Exclude this collection
35
+ "Collection3": -1, # Include all entries in the collection
36
+ },
37
+ )
38
+ ]
39
+ NOTE: If registering the plugin for an individual page the "page" part of the settings
40
+ is irrelevant and not looked at. That settings is for when registering for the site.
41
+
42
+ NOTE: "Most recent" is defined by the sort order for the given collection.
43
+ The default for a Collection is "title" and the default for a Blog is date.
44
+ You can override the sort order (which will affect the sorting for everything,
45
+ just this plugin) by initializing the Collection object with the following attribute:
46
+ sort_by = <sort attribute>
47
+
48
+ To use put this into your index.html template or content:
49
+ {% for collection, collection_data in COLLECTIONS.items() %}
50
+ Most recent <a href="{{ collection_data['url'] }}">{{ collection }}</a> entries:
51
+ <ul>
52
+ {% for entry in collection_data['entries'] %}
53
+ <li><a href="{{ entry['url'] }}">{{ entry['title'] }}</a></li>
54
+ {% endfor %}
55
+ </ul>
56
+ {% endfor %}
57
+
58
+ NOTE: Above example is using the default settings.
59
+ """
60
+
61
+ default_settings = {
62
+ 'collection': ['url'],
63
+ 'entries': ['title', 'url'],
64
+ 'pages': ['index'],
65
+ 'max_entries': 3,
66
+ }
67
+
68
+ @staticmethod
69
+ @hook_impl
70
+ def pre_build_site(site: Site, settings: dict):
71
+ """
72
+ Pre-build site hook
73
+
74
+ :param site: Site object
75
+ :param settings: Settings dictionary [Not currently used but required by the hook]
76
+ """
77
+ settings = settings['LatestEntries']
78
+ pages = settings.get('pages', list())
79
+ for page_entry in pages:
80
+ page = site.route_list[page_entry]
81
+ LatestEntries.build_latest_entries(site=site, page=page, settings=settings)
82
+
83
+ @staticmethod
84
+ @hook_impl
85
+ def render_content(page: Page, settings: dict, site: Site):
86
+ """
87
+ Render content hook
88
+
89
+ :param page: The page to update
90
+ :param settings: The settings for the plugin
91
+ :param site: The Site object.
92
+ """
93
+ LatestEntries.build_latest_entries(site, page, settings['LatestEntries'])
94
+
95
+ @staticmethod
96
+ def build_latest_entries(site: Site, page: Page, settings: dict):
97
+ """
98
+ Update the page with the latest entries.
99
+
100
+ :param page: The page to update
101
+ :param settings: The settings for the plugin
102
+ :param site: The Site object.
103
+ """
104
+ collections = dict()
105
+ for name, collection in site.route_list.items():
106
+ if isinstance(collection, Collection):
107
+ if not (max_entries := settings.get(collection.title, settings['max_entries'])):
108
+ continue
109
+ if max_entries < 0:
110
+ max_entries = len(collection.sorted_pages)
111
+ collections[collection.title] = {'entries': list()}
112
+ for attr in settings['collection']:
113
+ if attr == 'url':
114
+ value = f'/{collection.routes[0]}/'
115
+ else:
116
+ value = getattr(collection, attr, None)
117
+ collections[collection.title][attr] = value
118
+ for entry in collection.sorted_pages[:max_entries]:
119
+ entry_dict = dict()
120
+ for attr in settings['entries']:
121
+ if attr == 'url':
122
+ value = f'/{entry.routes[0]}/{entry._slug}.html'
123
+ else:
124
+ value = getattr(entry, attr, None)
125
+ entry_dict[attr] = value
126
+ collections[collection.title]['entries'].append(entry_dict)
127
+
128
+ if not hasattr(page, 'template_vars'):
129
+ page.template_vars = dict()
130
+ if existing_collections := page.template_vars.get('COLLECTIONS'):
131
+ existing_collections.update(collections)
132
+ else:
133
+ page.template_vars['COLLECTIONS'] = collections
@@ -0,0 +1,57 @@
1
+ """Plugin to add next & prev links to items in a collection"""
2
+
3
+ from render_engine import Collection, Site
4
+ from render_engine.plugins import hook_impl
5
+
6
+
7
+ class NextPrevPlugin:
8
+ default_settings = {}
9
+
10
+ @staticmethod
11
+ @hook_impl
12
+ def pre_build_collection(collection: Collection, site: Site, settings: dict):
13
+ """
14
+ Update a list of pages with links for the previous and next posts abd the URL for the Collection archive.
15
+
16
+ Can be registered with the Site or one or more Collections.
17
+
18
+ Note that if the sort is reversed for the collection (which is the default for Blog) you will
19
+ want to have `reversed: true` for the settings of this plugin.
20
+
21
+ Example implementation:
22
+ {% if collection_url %}
23
+ <hr/>
24
+ <p style="text-align: center;">
25
+ {% if prev_url %}
26
+ Previous: <a href="{{ prev_url }}">{{ prev_title }}</a>&nbsp;&nbsp;&nbsp;&nbsp;
27
+ {% endif %}
28
+ {% if next_url %}
29
+ &nbsp;&nbsp;&nbsp;&nbsp;Next: <a href="{{ next_url }}">{{ next_title }}</a>
30
+ {% endif %}
31
+ </p>
32
+ {% endif %}
33
+
34
+ :param collection: Collection instance
35
+ :param site: Site object - not used but part of the prototype for this hook
36
+ :param settings: Plugin settings
37
+ """
38
+ settings = settings['NextPrevPlugin']
39
+ reverse = collection.sort_reverse
40
+ pages = collection.sorted_pages[::-1] if reverse else collection.sorted_pages
41
+ collection_url = collection.routes[0]
42
+ max_page = len(pages) - 1
43
+ for i, page in enumerate(pages):
44
+ template_vars = dict()
45
+ if i < max_page:
46
+ template_vars['next_url'] = pages[i + 1].url_for()
47
+ template_vars['next_title'] = pages[i + 1].title
48
+ for attr in settings.get('additional_attributes', list()):
49
+ template_vars[f'next_{attr}'] = getattr(pages[i + 1], attr, None)
50
+ if i > 0:
51
+ template_vars['prev_url'] = pages[i - 1].url_for()
52
+ template_vars['prev_title'] = pages[i - 1].title
53
+ for attr in settings.get('additional_attributes', list()):
54
+ template_vars[f'prev_{attr}'] = getattr(pages[i - 1], attr, None)
55
+ template_vars['collection_url'] = collection_url
56
+ template_vars['collection_title'] = collection._title
57
+ page.template_vars = template_vars
@@ -0,0 +1,224 @@
1
+ Metadata-Version: 2.4
2
+ Name: re-plugin-pack
3
+ Version: 2025.6.1b1
4
+ Summary: Plugin pack for render-engine static site generator
5
+ Author: Dan Shernicoff
6
+ Author-email: Dan Shernicoff <dan@brassnet.biz>
7
+ License-Expression: MIT
8
+ License-File: LICENSE.md
9
+ Requires-Dist: render-engine>=2025.6.1b1
10
+ Requires-Python: >=3.10
11
+ Project-URL: Repository, https://github.com/brass75/re-plugin-pack
12
+ Project-URL: homepage, https://github.com/brass75/re-plugin-pack
13
+ Description-Content-Type: text/markdown
14
+
15
+ # re-plugin-pack
16
+
17
+ This is a plugin pack for the `render-engine` static site generator. It currently includes the
18
+ following plugins:
19
+
20
+ - [`LatestEntries`](#latestentries)
21
+ - [`NextPrevPlugin`](#nextprevplugin)
22
+
23
+ ## `LatestEntries`
24
+
25
+ This plugin will add a list of the latest entries for one or more `Collection`s to a given `Page`.
26
+ It can be configured at the Page or `Site` levels and can be configured to provide the latest entries
27
+ for any number of `Collection`s. The entries used are in the sort order as defined in the `Collection`
28
+ object.
29
+
30
+ ### Settings
31
+
32
+ The plugin has the following default settings:
33
+
34
+ ```python
35
+ {
36
+ "collection": ["url"],
37
+ "entries": ["title", "url"],
38
+ "pages": ["index"],
39
+ "max_entries": 3,
40
+ }
41
+ ```
42
+ - `collection` - a list of attributes to include for the collection.
43
+ - `entries` - a list of attributes to include for a given entry.
44
+ - `pages` - a list of pages to add the `COLLECTIONS` entry to it's `template_vars` (Only needed when running as a
45
+ `Site` plugin)
46
+ - `max_entries` - The maximum number of entries to include for a collection. The default is 3. `-1` indicates
47
+ that all entries should be populated.
48
+
49
+ In addition to the default settings entries can be added for each `Collection` defining how many
50
+ entries it should include:
51
+
52
+ - Positive integer - Include up to the number specified entries. For example: `'Collection1': 5`
53
+ will include the 5 latest entries in the `template_vars`.
54
+ - `0` - Exclude this collection. For example: `'Collection2': 0` will not include `Collection2`
55
+ in the `template_vars`.
56
+ - Negative integer - Include all entries. For example: `'Collection3': -1` will include all
57
+ entries for `Collection3` in the `template_vars`
58
+
59
+ ### `Page` level configuration
60
+
61
+ To configure at the `Page` level just include `(LatestEntris, <settings_dict)` in the `plugins`
62
+ attribute when declaring the `Page`. If no settings overrides are needed, include `LatestEntries`
63
+ by itself in the `plugin` attribute.
64
+
65
+ Example:
66
+ ```python
67
+ from render_engine import Site, Page
68
+ from re-plugin-pack import LatestEntries
69
+
70
+ app = Site()
71
+ @app.page
72
+ class MyPage(Page):
73
+ plugins = [
74
+ (
75
+ LatestEntries,
76
+ {
77
+ "Collection1": 5, # Include the 5 most recent entries
78
+ "Collection2": 0, # Exclude this collection
79
+ "Collection3": -1, # Include all entries in the collection
80
+ },
81
+ )
82
+ ]
83
+ ...
84
+ ```
85
+
86
+ ### `Site` level configuration
87
+
88
+ To configure at the `Site` level call `app.register_plugins(LatestEntries, LatestEntries=<settings>)`
89
+ if settings overrides are being used. To configure without additional settings, call
90
+ `app.register_plugin(LatestEntries)`.
91
+
92
+ Example:
93
+ ```python
94
+ from render_engine import Site, Page
95
+ from re-plugin-pack import LatestEntries
96
+
97
+ app = Site()
98
+
99
+ # The following will use the default settings overriding the pages to run on to be page1 and page2
100
+ app.register_plugins(LatestEntries, LatestEntries={'pages': ['page1', 'page2']})
101
+
102
+ # The following will only enable for the Blog collection:
103
+ app.register_plugins(LatestEntries, LatestEntries={'max_entries': 0, 'Blog': 3})
104
+ ```
105
+
106
+ NOTE: If configuring at the `Site` level the registration should be done _after_ adding all
107
+ `Page` entries to the `Site`. When adding a `Page` to a `Site` all plugins registered to the
108
+ `Site` are automatically registered to the new `Page` object.
109
+
110
+ ### Including in the `Page` template
111
+
112
+ The latest entries will be added to the `COLLECTIONS` key of the `template_vars` for the `Page`
113
+ and can be accessed in the template as `COLLECTIONS`.
114
+
115
+ Example template implementation:
116
+ ```
117
+ {% for collection, collection_data in COLLECTIONS.items() %}
118
+ Most recent <a href="{{ collection_data['url'] }}">{{ collection }}</a> entries:
119
+ <ul>
120
+ {% for entry in collection_data['entries'] %}
121
+ <li><a href="{{ entry['url'] }}">{{ entry['title'] }}</a></li>
122
+ {% endfor %}
123
+ </ul>
124
+ {% endfor %}
125
+ ```
126
+
127
+ ## `NextPrevPlugin`
128
+
129
+ This plugin will give each page in a `Collection` access to certain attributes of the next and
130
+ previous pages in the collection. By default, only the URL and title of those pages will be
131
+ made available, however additional attributes may also be requested via the settings. If an
132
+ attributes is in the list to include but does not exist in the page(s) `None` will be used.
133
+ This plugin runs at the `Collection` level and can be registered at the `Site` or `Collection`
134
+ level.
135
+
136
+ ### Settings
137
+
138
+ This plugin has no default settings. If you wish to add additional attributes, include in the
139
+ registration a settings dictionary with a key of `additional_attributes` having a list of
140
+ attributes as its value.
141
+
142
+ ### `Site` level configuration
143
+
144
+ To configure at the `Site` level call `app.register_plugins(NextPrevPlugin, NextPrevPlugin=<settings>)`
145
+ if settings overrides are being used. To configure without additional settings, call
146
+ `app.register_plugin(NextPrevPlugin)`.
147
+
148
+ Example:
149
+ ```python
150
+ from render_engine import Site, Page
151
+ from re-plugin-pack import NextPrevPlugin
152
+
153
+ app = Site()
154
+
155
+ # The following will include the date attribute in in the data made available.
156
+ app.register_plugins(NextPrevPlugin, NextPrevPlugin={'additional_attributes': ['date']})
157
+
158
+ # The following will not include any additional attributes
159
+ app.register_plugins(NextPrevPlugin)
160
+ ```
161
+
162
+ NOTE: If configuring at the `Site` level the registration should be done _after_ adding all
163
+ `Collection` entries to the `Site`. When adding a `Collection` to a `Site` all plugins
164
+ registered to the `Site` are automatically registered to the new `Collection` object.
165
+
166
+ ### `Collection` level configuration
167
+
168
+ To configure at the `Page` level just include `(NextPrevPlugin, <settings_dict)` in the `plugins`
169
+ attribute when declaring the `Collection`. If no settings overrides are needed, include
170
+ `NextPrevPlugin` by itself in the `plugin` attribute.
171
+
172
+ Example:
173
+ ```python
174
+ from render_engine import Site, Page
175
+ from re-plugin-pack import NextPrevPlugin
176
+
177
+ app = Site()
178
+ @app.page
179
+ class MyPage(Page):
180
+ plugins = [
181
+ (
182
+ NextPrevPlugin,
183
+ {
184
+ 'additional_attributes': [ # This will make the date and description attributes available
185
+ 'date',
186
+ 'description',
187
+ ]
188
+ },
189
+ )
190
+ ]
191
+ ...
192
+ ```
193
+
194
+ ### Including in the `Collection` template
195
+
196
+ When run this plugin will add a dictionary with the requested data to the `template_vars` of
197
+ each page in the `Collection`. The dictionary added looks like:
198
+
199
+ ```python
200
+ {
201
+ 'collection_url': <url>,
202
+ 'collection_title': <title>,
203
+ 'next_url': <url>,
204
+ 'next_title': <title>,
205
+ 'prev_url': <url>,
206
+ 'prev_title': <title>,
207
+ }
208
+ ```
209
+
210
+ If `additional_attributes` are included in the settings, they will be in the dictionary as:
211
+ `prev_<attr>: <value>` and `next_<attr>: <value>`.
212
+
213
+ ```
214
+ {% if prev_url %}
215
+ <span class="prev_data">
216
+ Previous: <a href="{{ prev_url }}">{{ prev_title }}</a>
217
+ </span>
218
+ {% endif %}
219
+ {% if next_url %}
220
+ <span class="next_data">
221
+ Next: <a href="{{ next_url }}">{{ next_title }}</a>
222
+ </span>
223
+ {% endif %}
224
+ ```
@@ -0,0 +1,7 @@
1
+ re_plugin_pack/__init__.py,sha256=51dc1f625d36228c56d90e435f91ed5b63d989878f57a128b9fe3c507573ec7e,139
2
+ re_plugin_pack/plugins/latest_entries.py,sha256=9f0f4e75724a20c7c6217d19a5c1c0b14289ca5e3ddccfd85af9a4671df28713,5137
3
+ re_plugin_pack/plugins/next_prev.py,sha256=feeb42c98c358dd186462174a4332228016de15840004066ff9815ef7a0d51db,2469
4
+ re_plugin_pack-2025.6.1b1.dist-info/licenses/LICENSE.md,sha256=96b1a938d839ee7740846ef97e81bcced9ca178c8058dce405d2032484e48c41,1071
5
+ re_plugin_pack-2025.6.1b1.dist-info/WHEEL,sha256=c133ef911c90b05f7e14d8679ba99146f9154fcd271b7398cf8f672283b94e05,79
6
+ re_plugin_pack-2025.6.1b1.dist-info/METADATA,sha256=cc004d07fc3872361dc8dd746c48e6442ab3e4c053839bac966fe2848e007293,7510
7
+ re_plugin_pack-2025.6.1b1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.7.13
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Dan Shernicoff
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.