re-plugin-pack 2025.6.1b1__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.
- re_plugin_pack-2025.6.1b1/LICENSE.md +21 -0
- re_plugin_pack-2025.6.1b1/PKG-INFO +224 -0
- re_plugin_pack-2025.6.1b1/README.md +210 -0
- re_plugin_pack-2025.6.1b1/pyproject.toml +57 -0
- re_plugin_pack-2025.6.1b1/src/re_plugin_pack/__init__.py +4 -0
- re_plugin_pack-2025.6.1b1/src/re_plugin_pack/plugins/latest_entries.py +133 -0
- re_plugin_pack-2025.6.1b1/src/re_plugin_pack/plugins/next_prev.py +57 -0
|
@@ -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.
|
|
@@ -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,210 @@
|
|
|
1
|
+
# re-plugin-pack
|
|
2
|
+
|
|
3
|
+
This is a plugin pack for the `render-engine` static site generator. It currently includes the
|
|
4
|
+
following plugins:
|
|
5
|
+
|
|
6
|
+
- [`LatestEntries`](#latestentries)
|
|
7
|
+
- [`NextPrevPlugin`](#nextprevplugin)
|
|
8
|
+
|
|
9
|
+
## `LatestEntries`
|
|
10
|
+
|
|
11
|
+
This plugin will add a list of the latest entries for one or more `Collection`s to a given `Page`.
|
|
12
|
+
It can be configured at the Page or `Site` levels and can be configured to provide the latest entries
|
|
13
|
+
for any number of `Collection`s. The entries used are in the sort order as defined in the `Collection`
|
|
14
|
+
object.
|
|
15
|
+
|
|
16
|
+
### Settings
|
|
17
|
+
|
|
18
|
+
The plugin has the following default settings:
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
{
|
|
22
|
+
"collection": ["url"],
|
|
23
|
+
"entries": ["title", "url"],
|
|
24
|
+
"pages": ["index"],
|
|
25
|
+
"max_entries": 3,
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
- `collection` - a list of attributes to include for the collection.
|
|
29
|
+
- `entries` - a list of attributes to include for a given entry.
|
|
30
|
+
- `pages` - a list of pages to add the `COLLECTIONS` entry to it's `template_vars` (Only needed when running as a
|
|
31
|
+
`Site` plugin)
|
|
32
|
+
- `max_entries` - The maximum number of entries to include for a collection. The default is 3. `-1` indicates
|
|
33
|
+
that all entries should be populated.
|
|
34
|
+
|
|
35
|
+
In addition to the default settings entries can be added for each `Collection` defining how many
|
|
36
|
+
entries it should include:
|
|
37
|
+
|
|
38
|
+
- Positive integer - Include up to the number specified entries. For example: `'Collection1': 5`
|
|
39
|
+
will include the 5 latest entries in the `template_vars`.
|
|
40
|
+
- `0` - Exclude this collection. For example: `'Collection2': 0` will not include `Collection2`
|
|
41
|
+
in the `template_vars`.
|
|
42
|
+
- Negative integer - Include all entries. For example: `'Collection3': -1` will include all
|
|
43
|
+
entries for `Collection3` in the `template_vars`
|
|
44
|
+
|
|
45
|
+
### `Page` level configuration
|
|
46
|
+
|
|
47
|
+
To configure at the `Page` level just include `(LatestEntris, <settings_dict)` in the `plugins`
|
|
48
|
+
attribute when declaring the `Page`. If no settings overrides are needed, include `LatestEntries`
|
|
49
|
+
by itself in the `plugin` attribute.
|
|
50
|
+
|
|
51
|
+
Example:
|
|
52
|
+
```python
|
|
53
|
+
from render_engine import Site, Page
|
|
54
|
+
from re-plugin-pack import LatestEntries
|
|
55
|
+
|
|
56
|
+
app = Site()
|
|
57
|
+
@app.page
|
|
58
|
+
class MyPage(Page):
|
|
59
|
+
plugins = [
|
|
60
|
+
(
|
|
61
|
+
LatestEntries,
|
|
62
|
+
{
|
|
63
|
+
"Collection1": 5, # Include the 5 most recent entries
|
|
64
|
+
"Collection2": 0, # Exclude this collection
|
|
65
|
+
"Collection3": -1, # Include all entries in the collection
|
|
66
|
+
},
|
|
67
|
+
)
|
|
68
|
+
]
|
|
69
|
+
...
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `Site` level configuration
|
|
73
|
+
|
|
74
|
+
To configure at the `Site` level call `app.register_plugins(LatestEntries, LatestEntries=<settings>)`
|
|
75
|
+
if settings overrides are being used. To configure without additional settings, call
|
|
76
|
+
`app.register_plugin(LatestEntries)`.
|
|
77
|
+
|
|
78
|
+
Example:
|
|
79
|
+
```python
|
|
80
|
+
from render_engine import Site, Page
|
|
81
|
+
from re-plugin-pack import LatestEntries
|
|
82
|
+
|
|
83
|
+
app = Site()
|
|
84
|
+
|
|
85
|
+
# The following will use the default settings overriding the pages to run on to be page1 and page2
|
|
86
|
+
app.register_plugins(LatestEntries, LatestEntries={'pages': ['page1', 'page2']})
|
|
87
|
+
|
|
88
|
+
# The following will only enable for the Blog collection:
|
|
89
|
+
app.register_plugins(LatestEntries, LatestEntries={'max_entries': 0, 'Blog': 3})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
NOTE: If configuring at the `Site` level the registration should be done _after_ adding all
|
|
93
|
+
`Page` entries to the `Site`. When adding a `Page` to a `Site` all plugins registered to the
|
|
94
|
+
`Site` are automatically registered to the new `Page` object.
|
|
95
|
+
|
|
96
|
+
### Including in the `Page` template
|
|
97
|
+
|
|
98
|
+
The latest entries will be added to the `COLLECTIONS` key of the `template_vars` for the `Page`
|
|
99
|
+
and can be accessed in the template as `COLLECTIONS`.
|
|
100
|
+
|
|
101
|
+
Example template implementation:
|
|
102
|
+
```
|
|
103
|
+
{% for collection, collection_data in COLLECTIONS.items() %}
|
|
104
|
+
Most recent <a href="{{ collection_data['url'] }}">{{ collection }}</a> entries:
|
|
105
|
+
<ul>
|
|
106
|
+
{% for entry in collection_data['entries'] %}
|
|
107
|
+
<li><a href="{{ entry['url'] }}">{{ entry['title'] }}</a></li>
|
|
108
|
+
{% endfor %}
|
|
109
|
+
</ul>
|
|
110
|
+
{% endfor %}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## `NextPrevPlugin`
|
|
114
|
+
|
|
115
|
+
This plugin will give each page in a `Collection` access to certain attributes of the next and
|
|
116
|
+
previous pages in the collection. By default, only the URL and title of those pages will be
|
|
117
|
+
made available, however additional attributes may also be requested via the settings. If an
|
|
118
|
+
attributes is in the list to include but does not exist in the page(s) `None` will be used.
|
|
119
|
+
This plugin runs at the `Collection` level and can be registered at the `Site` or `Collection`
|
|
120
|
+
level.
|
|
121
|
+
|
|
122
|
+
### Settings
|
|
123
|
+
|
|
124
|
+
This plugin has no default settings. If you wish to add additional attributes, include in the
|
|
125
|
+
registration a settings dictionary with a key of `additional_attributes` having a list of
|
|
126
|
+
attributes as its value.
|
|
127
|
+
|
|
128
|
+
### `Site` level configuration
|
|
129
|
+
|
|
130
|
+
To configure at the `Site` level call `app.register_plugins(NextPrevPlugin, NextPrevPlugin=<settings>)`
|
|
131
|
+
if settings overrides are being used. To configure without additional settings, call
|
|
132
|
+
`app.register_plugin(NextPrevPlugin)`.
|
|
133
|
+
|
|
134
|
+
Example:
|
|
135
|
+
```python
|
|
136
|
+
from render_engine import Site, Page
|
|
137
|
+
from re-plugin-pack import NextPrevPlugin
|
|
138
|
+
|
|
139
|
+
app = Site()
|
|
140
|
+
|
|
141
|
+
# The following will include the date attribute in in the data made available.
|
|
142
|
+
app.register_plugins(NextPrevPlugin, NextPrevPlugin={'additional_attributes': ['date']})
|
|
143
|
+
|
|
144
|
+
# The following will not include any additional attributes
|
|
145
|
+
app.register_plugins(NextPrevPlugin)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
NOTE: If configuring at the `Site` level the registration should be done _after_ adding all
|
|
149
|
+
`Collection` entries to the `Site`. When adding a `Collection` to a `Site` all plugins
|
|
150
|
+
registered to the `Site` are automatically registered to the new `Collection` object.
|
|
151
|
+
|
|
152
|
+
### `Collection` level configuration
|
|
153
|
+
|
|
154
|
+
To configure at the `Page` level just include `(NextPrevPlugin, <settings_dict)` in the `plugins`
|
|
155
|
+
attribute when declaring the `Collection`. If no settings overrides are needed, include
|
|
156
|
+
`NextPrevPlugin` by itself in the `plugin` attribute.
|
|
157
|
+
|
|
158
|
+
Example:
|
|
159
|
+
```python
|
|
160
|
+
from render_engine import Site, Page
|
|
161
|
+
from re-plugin-pack import NextPrevPlugin
|
|
162
|
+
|
|
163
|
+
app = Site()
|
|
164
|
+
@app.page
|
|
165
|
+
class MyPage(Page):
|
|
166
|
+
plugins = [
|
|
167
|
+
(
|
|
168
|
+
NextPrevPlugin,
|
|
169
|
+
{
|
|
170
|
+
'additional_attributes': [ # This will make the date and description attributes available
|
|
171
|
+
'date',
|
|
172
|
+
'description',
|
|
173
|
+
]
|
|
174
|
+
},
|
|
175
|
+
)
|
|
176
|
+
]
|
|
177
|
+
...
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Including in the `Collection` template
|
|
181
|
+
|
|
182
|
+
When run this plugin will add a dictionary with the requested data to the `template_vars` of
|
|
183
|
+
each page in the `Collection`. The dictionary added looks like:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
{
|
|
187
|
+
'collection_url': <url>,
|
|
188
|
+
'collection_title': <title>,
|
|
189
|
+
'next_url': <url>,
|
|
190
|
+
'next_title': <title>,
|
|
191
|
+
'prev_url': <url>,
|
|
192
|
+
'prev_title': <title>,
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If `additional_attributes` are included in the settings, they will be in the dictionary as:
|
|
197
|
+
`prev_<attr>: <value>` and `next_<attr>: <value>`.
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
{% if prev_url %}
|
|
201
|
+
<span class="prev_data">
|
|
202
|
+
Previous: <a href="{{ prev_url }}">{{ prev_title }}</a>
|
|
203
|
+
</span>
|
|
204
|
+
{% endif %}
|
|
205
|
+
{% if next_url %}
|
|
206
|
+
<span class="next_data">
|
|
207
|
+
Next: <a href="{{ next_url }}">{{ next_title }}</a>
|
|
208
|
+
</span>
|
|
209
|
+
{% endif %}
|
|
210
|
+
```
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "re_plugin_pack"
|
|
3
|
+
version = "2025.6.1b1"
|
|
4
|
+
description = "Plugin pack for render-engine static site generator"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [{name = "Dan Shernicoff", email = "dan@brassnet.biz"}]
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE.md"]
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"render-engine>=2025.6.1b1",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
[dependency-groups]
|
|
15
|
+
dev = [
|
|
16
|
+
"coverage>=7.8.0",
|
|
17
|
+
"freezegun>=1.5.2",
|
|
18
|
+
"pytest>=8.4.0",
|
|
19
|
+
"uv-build>=0.7.12,<0.8.0",
|
|
20
|
+
"ruff"
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
homepage = "https://github.com/brass75/re-plugin-pack"
|
|
25
|
+
Repository = "https://github.com/brass75/re-plugin-pack"
|
|
26
|
+
|
|
27
|
+
[tool.ruff]
|
|
28
|
+
target-version = "py312"
|
|
29
|
+
# Allow lines to be as long as 120 characters.
|
|
30
|
+
line-length = 120
|
|
31
|
+
lint.select = [
|
|
32
|
+
"E", # pycodestyle
|
|
33
|
+
"F", # pyflakes
|
|
34
|
+
"UP", # pyupgrade
|
|
35
|
+
"I", # imports
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
lint.ignore = [
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
# Allow fix for all enabled rules (when `--fix`) is provided.
|
|
43
|
+
lint.fixable = ["ALL"]
|
|
44
|
+
lint.unfixable = []
|
|
45
|
+
|
|
46
|
+
exclude = [
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[tool.ruff.format]
|
|
50
|
+
quote-style = "single"
|
|
51
|
+
indent-style = "space"
|
|
52
|
+
docstring-code-format = true
|
|
53
|
+
|
|
54
|
+
[build-system]
|
|
55
|
+
requires = ["uv_build>=0.7.12,<0.8.0"]
|
|
56
|
+
build-backend = "uv_build"
|
|
57
|
+
|
|
@@ -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>
|
|
27
|
+
{% endif %}
|
|
28
|
+
{% if next_url %}
|
|
29
|
+
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
|