wagtail-tw-blocks 0.3.1__py3-none-any.whl → 1.0.0__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.
- wagtail_blocks/__init__.py +6 -70
- wagtail_blocks/blocks.py +157 -536
- wagtail_blocks/constants.py +60 -0
- wagtail_blocks/static/wagtail_blocks/css/app.css +18 -2
- wagtail_blocks/static/wagtail_blocks/css/styles.css +2 -2
- wagtail_blocks/static/wagtail_blocks/package-lock.json +251 -420
- wagtail_blocks/static/wagtail_blocks/package.json +3 -3
- wagtail_blocks/templates/wagtail/blocks/accordion.html +21 -0
- wagtail_blocks/templates/wagtail/blocks/alert.html +12 -0
- wagtail_blocks/templates/wagtail/blocks/carousel.html +19 -0
- wagtail_blocks/templates/wagtail/blocks/code.html +32 -0
- wagtail_blocks/templates/{wagtail_blocks → wagtail}/blocks/diff.html +3 -3
- wagtail_blocks/templates/wagtail/blocks/document.html +65 -0
- wagtail_blocks/templates/wagtail/blocks/hover_gallery.html +11 -0
- wagtail_blocks/templates/wagtail/blocks/tabs.html +20 -0
- wagtail_blocks/templates/wagtail/components/breadcrumbs.html +12 -0
- wagtail_blocks/templates/wagtail/components/form.html +116 -0
- wagtail_blocks/templates/wagtail/components/languages.html +77 -0
- wagtail_blocks/templates/wagtail/components/messages.html +56 -0
- wagtail_blocks/templates/wagtail/components/next.html +22 -0
- wagtail_blocks/templates/wagtail/components/pagination.html +59 -0
- wagtail_blocks/templates/wagtail/components/prev.html +25 -0
- wagtail_blocks/templates/wagtail/components/prev_next.html +5 -0
- wagtail_blocks/templates/wagtail/components/themes.html +366 -0
- wagtail_blocks/templates/wagtail/components/tree.html +28 -0
- wagtail_blocks/templates/wagtail/styles.html +29 -0
- wagtail_tw_blocks-1.0.0.dist-info/METADATA +451 -0
- wagtail_tw_blocks-1.0.0.dist-info/RECORD +39 -0
- {wagtail_tw_blocks-0.3.1.dist-info → wagtail_tw_blocks-1.0.0.dist-info}/WHEEL +1 -1
- wagtail_blocks/templates/wagtail_blocks/blocks/accordion.html +0 -49
- wagtail_blocks/templates/wagtail_blocks/blocks/alert.html +0 -24
- wagtail_blocks/templates/wagtail_blocks/blocks/browser.html +0 -15
- wagtail_blocks/templates/wagtail_blocks/blocks/carousel.html +0 -64
- wagtail_blocks/templates/wagtail_blocks/blocks/code.html +0 -66
- wagtail_blocks/templates/wagtail_blocks/blocks/code_mockup.html +0 -20
- wagtail_blocks/templates/wagtail_blocks/blocks/fab.html +0 -43
- wagtail_blocks/templates/wagtail_blocks/blocks/hover_gallery.html +0 -18
- wagtail_blocks/templates/wagtail_blocks/blocks/image.html +0 -19
- wagtail_blocks/templates/wagtail_blocks/blocks/list.html +0 -56
- wagtail_blocks/templates/wagtail_blocks/blocks/phone.html +0 -11
- wagtail_blocks/templates/wagtail_blocks/blocks/steps.html +0 -12
- wagtail_blocks/templates/wagtail_blocks/blocks/tabs.html +0 -24
- wagtail_blocks/templates/wagtail_blocks/blocks/timeline.html +0 -30
- wagtail_blocks/templates/wagtail_blocks/blocks/toast.html +0 -9
- wagtail_blocks/templates/wagtail_blocks/blocks/window.html +0 -9
- wagtail_blocks/templates/wagtail_blocks/styles.html +0 -92
- wagtail_tw_blocks-0.3.1.dist-info/METADATA +0 -237
- wagtail_tw_blocks-0.3.1.dist-info/RECORD +0 -37
- {wagtail_tw_blocks-0.3.1.dist-info → wagtail_tw_blocks-1.0.0.dist-info}/licenses/LICENSE +0 -0
wagtail_blocks/blocks.py
CHANGED
|
@@ -1,127 +1,26 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Block definitions"""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
import math
|
|
4
|
+
from typing import Any, Dict, Literal, Optional
|
|
5
|
+
|
|
6
|
+
from django.utils.crypto import get_random_string
|
|
4
7
|
from django.utils.translation import gettext_lazy as _
|
|
5
8
|
from wagtail import blocks
|
|
9
|
+
from wagtail.documents.blocks import DocumentChooserBlock
|
|
6
10
|
from wagtail.embeds.blocks import EmbedBlock
|
|
7
|
-
from wagtail.images.blocks import ImageBlock
|
|
8
|
-
|
|
9
|
-
from wagtail_blocks import (
|
|
10
|
-
ACCORDION_STYLES,
|
|
11
|
-
ALERT_LEVELS,
|
|
12
|
-
ALERT_STYLES,
|
|
13
|
-
COLOR_CHOICES,
|
|
14
|
-
PROGRAMMING_LANGUAGES,
|
|
15
|
-
TAB_STYLES,
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
# Settings
|
|
19
|
-
PROGRAMMING_LANGUAGES = getattr(
|
|
20
|
-
settings,
|
|
21
|
-
"WB_CODE_BLOCK_PROGRAMMING_LANGUAGES",
|
|
22
|
-
PROGRAMMING_LANGUAGES,
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
SHOW_HEADER = getattr(
|
|
26
|
-
settings,
|
|
27
|
-
"WB_CODE_BLOCK_SHOW_HEADER",
|
|
28
|
-
True,
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
SHOW_PROGRAMMING_LANGUAGE = getattr(
|
|
32
|
-
settings,
|
|
33
|
-
"WB_CODE_BLOCK_SHOW_PROGRAMMING_LANGUAGE",
|
|
34
|
-
True,
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
SHOW_COPY_BUTTON = getattr(
|
|
38
|
-
settings,
|
|
39
|
-
"WB_CODE_BLOCK_SHOW_COPY_BUTTON",
|
|
40
|
-
True,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
SHOW_WINDOW_CONTROLS = getattr(
|
|
44
|
-
settings,
|
|
45
|
-
"WB_CODE_BLOCK_SHOW_WINDOW_CONTROLS",
|
|
46
|
-
True,
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class ImageBlock(blocks.StructBlock):
|
|
51
|
-
"""Image block with caption"""
|
|
52
|
-
|
|
53
|
-
image = WImageBlock(
|
|
54
|
-
required=True,
|
|
55
|
-
help_text=_("Image"),
|
|
56
|
-
)
|
|
57
|
-
caption = blocks.CharBlock(
|
|
58
|
-
max_length=128,
|
|
59
|
-
required=False,
|
|
60
|
-
help_text=_("Image caption"),
|
|
61
|
-
)
|
|
62
|
-
attribution = blocks.CharBlock(
|
|
63
|
-
max_length=128,
|
|
64
|
-
required=False,
|
|
65
|
-
help_text=_("Image attribution"),
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
class Meta:
|
|
69
|
-
"""Meta data"""
|
|
70
|
-
|
|
71
|
-
icon = "image"
|
|
72
|
-
template = "wagtail_blocks/blocks/image.html"
|
|
11
|
+
from wagtail.images.blocks import ImageBlock
|
|
73
12
|
|
|
74
|
-
|
|
75
|
-
class ButtonBlock(blocks.StructBlock):
|
|
76
|
-
"""Action block (link)"""
|
|
77
|
-
|
|
78
|
-
icon = blocks.CharBlock(
|
|
79
|
-
max_length=32,
|
|
80
|
-
required=False,
|
|
81
|
-
default="check-circle2",
|
|
82
|
-
help_text=_("Icon name (lucide icons)"),
|
|
83
|
-
)
|
|
84
|
-
label = blocks.CharBlock(
|
|
85
|
-
max_length=32,
|
|
86
|
-
required=False,
|
|
87
|
-
help_text=_("Action label"),
|
|
88
|
-
)
|
|
89
|
-
page = blocks.PageChooserBlock(
|
|
90
|
-
required=False,
|
|
91
|
-
help_text=_("Action internal link"),
|
|
92
|
-
)
|
|
93
|
-
url = blocks.URLBlock(
|
|
94
|
-
required=False,
|
|
95
|
-
help_text=_("Action external link"),
|
|
96
|
-
)
|
|
97
|
-
color = blocks.ChoiceBlock(
|
|
98
|
-
choices=COLOR_CHOICES,
|
|
99
|
-
required=False,
|
|
100
|
-
help_text=_("Action button color"),
|
|
101
|
-
)
|
|
13
|
+
from wagtail_blocks import constants
|
|
102
14
|
|
|
103
15
|
|
|
104
16
|
class AccordionItem(blocks.StructBlock):
|
|
105
17
|
"""Accordion Item"""
|
|
106
18
|
|
|
107
|
-
icon = blocks.CharBlock(
|
|
108
|
-
max_length=32,
|
|
109
|
-
required=False,
|
|
110
|
-
default="check-circle2",
|
|
111
|
-
help_text=_("Icon name (lucide icons)"),
|
|
112
|
-
)
|
|
113
|
-
is_expanded = blocks.BooleanBlock(
|
|
114
|
-
default=False,
|
|
115
|
-
required=False,
|
|
116
|
-
help_text=_("Whether to show or hide item content"),
|
|
117
|
-
)
|
|
118
19
|
title = blocks.CharBlock(
|
|
119
20
|
max_length=64,
|
|
120
|
-
required=True,
|
|
121
21
|
help_text=_("Item title"),
|
|
122
22
|
)
|
|
123
23
|
content = blocks.RichTextBlock(
|
|
124
|
-
required=True,
|
|
125
24
|
help_text=_("Item content"),
|
|
126
25
|
)
|
|
127
26
|
|
|
@@ -132,24 +31,12 @@ class AccordionBlock(blocks.StructBlock):
|
|
|
132
31
|
but only one item can stay open at a time.
|
|
133
32
|
"""
|
|
134
33
|
|
|
135
|
-
name = blocks.CharBlock(
|
|
136
|
-
max_length=64,
|
|
137
|
-
required=True,
|
|
138
|
-
help_text=_("Accordion name"),
|
|
139
|
-
)
|
|
140
34
|
style = blocks.ChoiceBlock(
|
|
141
|
-
choices=ACCORDION_STYLES,
|
|
142
|
-
required=False,
|
|
35
|
+
choices=constants.ACCORDION_STYLES,
|
|
143
36
|
help_text=_("Accordion style"),
|
|
144
37
|
)
|
|
145
|
-
is_joined = blocks.BooleanBlock(
|
|
146
|
-
default=False,
|
|
147
|
-
required=False,
|
|
148
|
-
help_text=_("Designates if accordion is joined"),
|
|
149
|
-
)
|
|
150
38
|
items = blocks.ListBlock(
|
|
151
39
|
AccordionItem(),
|
|
152
|
-
required=True,
|
|
153
40
|
help_text=_("Accordion items"),
|
|
154
41
|
)
|
|
155
42
|
|
|
@@ -157,89 +44,93 @@ class AccordionBlock(blocks.StructBlock):
|
|
|
157
44
|
"""Meta data"""
|
|
158
45
|
|
|
159
46
|
icon = "collapse-down"
|
|
160
|
-
template = "
|
|
47
|
+
template = "wagtail/blocks/accordion.html"
|
|
48
|
+
|
|
49
|
+
def get_context(
|
|
50
|
+
self,
|
|
51
|
+
value: Dict[str, Any],
|
|
52
|
+
parent_context: Optional[Dict[str, Any]] = None,
|
|
53
|
+
) -> Dict[str, Any]:
|
|
54
|
+
return {
|
|
55
|
+
**super().get_context(value, parent_context),
|
|
56
|
+
"name": get_random_string(5),
|
|
57
|
+
}
|
|
161
58
|
|
|
162
59
|
|
|
163
60
|
class AlertBlock(blocks.StructBlock):
|
|
164
61
|
"""Alert informs users about important events."""
|
|
165
62
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
default="alert-triangle",
|
|
170
|
-
help_text=_("Icon name (lucide icons)"),
|
|
171
|
-
)
|
|
172
|
-
is_vertical = blocks.BooleanBlock(
|
|
173
|
-
default=False,
|
|
174
|
-
required=False,
|
|
175
|
-
help_text=_("Designates if alert is vertical or horizontal (default)"),
|
|
63
|
+
level = blocks.ChoiceBlock(
|
|
64
|
+
choices=constants.ALERT_LEVELS,
|
|
65
|
+
help_text=_("Alert level"),
|
|
176
66
|
)
|
|
177
67
|
style = blocks.ChoiceBlock(
|
|
178
|
-
choices=ALERT_STYLES,
|
|
68
|
+
choices=constants.ALERT_STYLES,
|
|
179
69
|
required=False,
|
|
180
70
|
help_text=_("Alert style"),
|
|
181
71
|
)
|
|
182
|
-
level = blocks.ChoiceBlock(
|
|
183
|
-
choices=ALERT_LEVELS,
|
|
184
|
-
required=True,
|
|
185
|
-
help_text=_("Alert level"),
|
|
186
|
-
)
|
|
187
72
|
message = blocks.RichTextBlock(
|
|
188
|
-
required=True,
|
|
189
73
|
help_text=_("Alert message"),
|
|
190
|
-
features=[
|
|
191
|
-
"bold",
|
|
192
|
-
"italic",
|
|
193
|
-
"link",
|
|
194
|
-
"document-link",
|
|
195
|
-
"code",
|
|
196
|
-
"superscript",
|
|
197
|
-
"subscript",
|
|
198
|
-
"strikethrough",
|
|
199
|
-
],
|
|
200
|
-
)
|
|
201
|
-
actions = blocks.ListBlock(
|
|
202
|
-
ButtonBlock(),
|
|
203
|
-
required=False,
|
|
204
|
-
help_text=_("Alert actions"),
|
|
205
74
|
)
|
|
206
75
|
|
|
207
76
|
class Meta:
|
|
208
77
|
"""Meta data"""
|
|
209
78
|
|
|
210
79
|
icon = "warning"
|
|
211
|
-
template = "
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
80
|
+
template = "wagtail/blocks/alert.html"
|
|
81
|
+
|
|
82
|
+
def get_icon(
|
|
83
|
+
self,
|
|
84
|
+
level: Optional[Literal["info", "success", "warning", "error"]],
|
|
85
|
+
) -> Literal[
|
|
86
|
+
"info",
|
|
87
|
+
"circle-check",
|
|
88
|
+
"alert-triangle",
|
|
89
|
+
"x-circle",
|
|
90
|
+
"question-mark-circle",
|
|
91
|
+
]:
|
|
92
|
+
"""
|
|
93
|
+
Get alert icon based on alert level.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
level (str): Alert level
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
str: Alert icon
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
match level:
|
|
103
|
+
case "info":
|
|
104
|
+
return level
|
|
105
|
+
|
|
106
|
+
case "success":
|
|
107
|
+
return "circle-check"
|
|
108
|
+
|
|
109
|
+
case "warning":
|
|
110
|
+
return "alert-triangle"
|
|
111
|
+
|
|
112
|
+
case "error":
|
|
113
|
+
return "x-circle"
|
|
114
|
+
|
|
115
|
+
case None:
|
|
116
|
+
return "question-mark-circle"
|
|
117
|
+
|
|
118
|
+
def get_context(
|
|
119
|
+
self,
|
|
120
|
+
value: Dict[str, Any],
|
|
121
|
+
parent_context: Optional[Dict[str, Any]] = None,
|
|
122
|
+
) -> Dict[str, Any]:
|
|
123
|
+
return {
|
|
124
|
+
**super().get_context(value, parent_context),
|
|
125
|
+
"icon": self.get_icon(value.get("level")),
|
|
126
|
+
}
|
|
230
127
|
|
|
231
128
|
|
|
232
129
|
class CarouselBlock(blocks.StructBlock):
|
|
233
130
|
"""Carousel show images or content in a scrollable area."""
|
|
234
131
|
|
|
235
|
-
is_vertical = blocks.BooleanBlock(
|
|
236
|
-
default=False,
|
|
237
|
-
required=False,
|
|
238
|
-
help_text=_("Designates if carousel is vertical or horizontal (default)"),
|
|
239
|
-
)
|
|
240
132
|
items = blocks.ListBlock(
|
|
241
|
-
|
|
242
|
-
required=True,
|
|
133
|
+
ImageBlock(),
|
|
243
134
|
help_text=_("Carousel items"),
|
|
244
135
|
)
|
|
245
136
|
|
|
@@ -247,46 +138,27 @@ class CarouselBlock(blocks.StructBlock):
|
|
|
247
138
|
"""Meta data"""
|
|
248
139
|
|
|
249
140
|
icon = "media"
|
|
250
|
-
template = "
|
|
141
|
+
template = "wagtail/blocks/carousel.html"
|
|
142
|
+
|
|
143
|
+
def get_context(
|
|
144
|
+
self,
|
|
145
|
+
value: Dict[str, Any],
|
|
146
|
+
parent_context: Optional[Dict[str, Any]] = None,
|
|
147
|
+
) -> Dict[str, Any]:
|
|
148
|
+
return {
|
|
149
|
+
**super().get_context(value, parent_context),
|
|
150
|
+
"item_count": len(value.get("items", 0)),
|
|
151
|
+
}
|
|
251
152
|
|
|
252
153
|
|
|
253
154
|
class CodeBlock(blocks.StructBlock):
|
|
254
155
|
"""Code block is used to show a block of code in a box that looks like a code editor."""
|
|
255
156
|
|
|
256
|
-
show_header = blocks.BooleanBlock(
|
|
257
|
-
default=SHOW_PROGRAMMING_LANGUAGE,
|
|
258
|
-
required=False,
|
|
259
|
-
help_text=_("Whether to show or hide the header"),
|
|
260
|
-
)
|
|
261
|
-
show_language = blocks.BooleanBlock(
|
|
262
|
-
default=SHOW_PROGRAMMING_LANGUAGE,
|
|
263
|
-
required=False,
|
|
264
|
-
help_text=_("Whether to show or hide which programming language is used"),
|
|
265
|
-
)
|
|
266
|
-
show_copy_btn = blocks.BooleanBlock(
|
|
267
|
-
default=SHOW_COPY_BUTTON,
|
|
268
|
-
required=False,
|
|
269
|
-
help_text=_("Whether to show or hide copy buttons"),
|
|
270
|
-
)
|
|
271
|
-
show_window_btns = blocks.BooleanBlock(
|
|
272
|
-
default=SHOW_WINDOW_CONTROLS,
|
|
273
|
-
required=False,
|
|
274
|
-
help_text=_("Whether to show or hide window buttons"),
|
|
275
|
-
)
|
|
276
|
-
file_name = blocks.CharBlock(
|
|
277
|
-
max_length=64,
|
|
278
|
-
default="Untitled",
|
|
279
|
-
required=True,
|
|
280
|
-
help_text=_("File name"),
|
|
281
|
-
)
|
|
282
157
|
language = blocks.ChoiceBlock(
|
|
283
|
-
choices=PROGRAMMING_LANGUAGES,
|
|
284
|
-
default="auto",
|
|
285
|
-
required=True,
|
|
158
|
+
choices=constants.PROGRAMMING_LANGUAGES,
|
|
286
159
|
help_text=_("Programming language"),
|
|
287
160
|
)
|
|
288
161
|
code = blocks.TextBlock(
|
|
289
|
-
required=True,
|
|
290
162
|
help_text=_("Code content"),
|
|
291
163
|
)
|
|
292
164
|
|
|
@@ -294,76 +166,78 @@ class CodeBlock(blocks.StructBlock):
|
|
|
294
166
|
"""Meta data"""
|
|
295
167
|
|
|
296
168
|
icon = "code"
|
|
297
|
-
template = "
|
|
169
|
+
template = "wagtail/blocks/code.html"
|
|
298
170
|
|
|
299
171
|
|
|
300
172
|
class DiffBlock(blocks.StructBlock):
|
|
301
|
-
"""Diff
|
|
173
|
+
"""Diff block shows a side-by-side comparison of two items."""
|
|
302
174
|
|
|
303
|
-
item_1 =
|
|
304
|
-
|
|
305
|
-
help_text=_("Diff Item 1"),
|
|
306
|
-
)
|
|
307
|
-
item_2 = WImageBlock(
|
|
308
|
-
required=True,
|
|
309
|
-
help_text=_("Diff Item 2"),
|
|
310
|
-
)
|
|
175
|
+
item_1 = ImageBlock(help_text=_("Diff Item 1"))
|
|
176
|
+
item_2 = ImageBlock(help_text=_("Diff Item 2"))
|
|
311
177
|
|
|
312
178
|
class Meta:
|
|
313
179
|
"""Meta data"""
|
|
314
180
|
|
|
315
181
|
icon = "image"
|
|
316
|
-
template = "
|
|
182
|
+
template = "wagtail/blocks/diff.html"
|
|
317
183
|
|
|
318
184
|
|
|
319
|
-
class
|
|
320
|
-
"""
|
|
321
|
-
FAB (Floating Action Button) stays in the bottom corner of screen. It includes a
|
|
322
|
-
focusable and accessible element with button role. Clicking or focusing it shows
|
|
323
|
-
additional buttons (known as Speed Dial buttons) in a vertical arrangement or a
|
|
324
|
-
flower shape (quarter circle).
|
|
325
|
-
"""
|
|
185
|
+
class DocumentBlock(blocks.StructBlock):
|
|
186
|
+
"""Document block shows a document card with a download button"""
|
|
326
187
|
|
|
327
|
-
|
|
328
|
-
default=False,
|
|
329
|
-
required=False,
|
|
330
|
-
help_text=_("Designates if FAB is vertical or flower shaped (quarter circle)"),
|
|
331
|
-
)
|
|
332
|
-
toggle = ButtonBlock(
|
|
333
|
-
required=True,
|
|
334
|
-
help_text=_("FAB toggle btn"),
|
|
335
|
-
)
|
|
336
|
-
main = ButtonBlock(
|
|
337
|
-
required=False,
|
|
338
|
-
help_text=_("FAB main action"),
|
|
339
|
-
)
|
|
340
|
-
items = blocks.ListBlock(
|
|
341
|
-
ButtonBlock(),
|
|
342
|
-
max_num=4,
|
|
343
|
-
min_num=1,
|
|
344
|
-
required=True,
|
|
345
|
-
help_text=_("FAB items"),
|
|
346
|
-
)
|
|
188
|
+
document = DocumentChooserBlock()
|
|
347
189
|
|
|
348
190
|
class Meta:
|
|
349
191
|
"""Meta data"""
|
|
350
192
|
|
|
351
|
-
icon = "
|
|
352
|
-
template = "
|
|
193
|
+
icon = "doc-full"
|
|
194
|
+
template = "wagtail/blocks/document.html"
|
|
353
195
|
|
|
196
|
+
def get_doc_size(self, size_bytes: int) -> str:
|
|
197
|
+
"""
|
|
198
|
+
Converts a file size in bytes into a human-readable string (e.g., "1.43 MB").
|
|
354
199
|
|
|
355
|
-
|
|
356
|
-
|
|
200
|
+
This method uses the binary prefix system (base 1024) and scales the
|
|
201
|
+
unit dynamically based on the magnitude of the file size.
|
|
357
202
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
203
|
+
Args:
|
|
204
|
+
size_bytes (int): The total size of the document in bytes.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
str: A formatted string containing the scaled size and its unit.
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
if size_bytes <= 0:
|
|
211
|
+
return "0 B"
|
|
212
|
+
|
|
213
|
+
# Define the sequence of data units supported
|
|
214
|
+
DATA_UNITS = ("B", "KB", "MB", "GB", "TB", "PB", "EB")
|
|
215
|
+
|
|
216
|
+
# Determine the power of 1024 to which the size corresponds
|
|
217
|
+
# log(size, 1024) returns the index of the unit in our DATA_UNITS tuple
|
|
218
|
+
unit_index = int(math.floor(math.log(size_bytes, 1024)))
|
|
219
|
+
|
|
220
|
+
# Safety check: ensure the index does not exceed our defined units
|
|
221
|
+
unit_index = min(unit_index, len(DATA_UNITS) - 1)
|
|
222
|
+
|
|
223
|
+
# Calculate the divisor: 1024 raised to the power of the unit index
|
|
224
|
+
divisor = math.pow(1024, unit_index)
|
|
225
|
+
|
|
226
|
+
# Scale the size and round to two decimal places for UI clarity
|
|
227
|
+
scaled_size = round(size_bytes / divisor, 2)
|
|
228
|
+
unit_label = DATA_UNITS[unit_index]
|
|
229
|
+
|
|
230
|
+
return f"{scaled_size} {unit_label}"
|
|
231
|
+
|
|
232
|
+
def get_context(
|
|
233
|
+
self,
|
|
234
|
+
value: Dict[str, Any],
|
|
235
|
+
parent_context: Optional[Dict[str, Any]] = None,
|
|
236
|
+
) -> Dict[str, Any]:
|
|
237
|
+
return {
|
|
238
|
+
**super().get_context(value, parent_context),
|
|
239
|
+
"size": self.get_doc_size(value.get("document").file_size),
|
|
240
|
+
}
|
|
367
241
|
|
|
368
242
|
|
|
369
243
|
class HoverGalleryBlock(blocks.StructBlock):
|
|
@@ -375,10 +249,9 @@ class HoverGalleryBlock(blocks.StructBlock):
|
|
|
375
249
|
"""
|
|
376
250
|
|
|
377
251
|
items = blocks.ListBlock(
|
|
378
|
-
|
|
252
|
+
ImageBlock(),
|
|
379
253
|
max_num=10,
|
|
380
254
|
min_num=2,
|
|
381
|
-
required=True,
|
|
382
255
|
help_text=_("Gallery items"),
|
|
383
256
|
)
|
|
384
257
|
|
|
@@ -386,100 +259,7 @@ class HoverGalleryBlock(blocks.StructBlock):
|
|
|
386
259
|
"""Meta data"""
|
|
387
260
|
|
|
388
261
|
icon = "image"
|
|
389
|
-
template = "
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
class TimelineItem(blocks.StructBlock):
|
|
393
|
-
"""Timeline item"""
|
|
394
|
-
|
|
395
|
-
date = blocks.DateBlock(
|
|
396
|
-
required=True,
|
|
397
|
-
help_text=_("Item date"),
|
|
398
|
-
)
|
|
399
|
-
icon = blocks.CharBlock(
|
|
400
|
-
max_length=32,
|
|
401
|
-
required=False,
|
|
402
|
-
default="check-circle2",
|
|
403
|
-
help_text=_("Icon name (lucide icons)"),
|
|
404
|
-
)
|
|
405
|
-
content = blocks.CharBlock(
|
|
406
|
-
max_length=128,
|
|
407
|
-
required=True,
|
|
408
|
-
help_text=_("Item content"),
|
|
409
|
-
)
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
class TimelineBlock(blocks.StructBlock):
|
|
413
|
-
"""Timeline component shows a list of events in chronological order."""
|
|
414
|
-
|
|
415
|
-
is_compact = blocks.BooleanBlock(
|
|
416
|
-
default=False,
|
|
417
|
-
required=False,
|
|
418
|
-
help_text=_("Designates if timeline is compact"),
|
|
419
|
-
)
|
|
420
|
-
is_vertical = blocks.BooleanBlock(
|
|
421
|
-
default=False,
|
|
422
|
-
required=False,
|
|
423
|
-
help_text=_("Designates if timeline is vertical or horizontal (default)"),
|
|
424
|
-
)
|
|
425
|
-
snap_to_icon = blocks.BooleanBlock(
|
|
426
|
-
default=False,
|
|
427
|
-
required=False,
|
|
428
|
-
help_text=_("Designates if dates should snap to icons"),
|
|
429
|
-
)
|
|
430
|
-
items = blocks.ListBlock(
|
|
431
|
-
TimelineItem(),
|
|
432
|
-
required=True,
|
|
433
|
-
help_text=_("Timeline items"),
|
|
434
|
-
)
|
|
435
|
-
|
|
436
|
-
class Meta:
|
|
437
|
-
"""Meta data"""
|
|
438
|
-
|
|
439
|
-
icon = "calendar-alt"
|
|
440
|
-
template = "wagtail_blocks/blocks/timeline.html"
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
class StepItem(blocks.StructBlock):
|
|
444
|
-
"""Step item"""
|
|
445
|
-
|
|
446
|
-
name = blocks.CharBlock(
|
|
447
|
-
max_length=64,
|
|
448
|
-
required=True,
|
|
449
|
-
help_text=_("Item name"),
|
|
450
|
-
)
|
|
451
|
-
icon = blocks.CharBlock(
|
|
452
|
-
max_length=32,
|
|
453
|
-
required=False,
|
|
454
|
-
default="check-circle2",
|
|
455
|
-
help_text=_("Icon name (lucide icons)"),
|
|
456
|
-
)
|
|
457
|
-
color = blocks.ChoiceBlock(
|
|
458
|
-
choices=COLOR_CHOICES,
|
|
459
|
-
required=False,
|
|
460
|
-
help_text=_("Item color"),
|
|
461
|
-
)
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
class StepsBlock(blocks.StructBlock):
|
|
465
|
-
"""Steps can be used to show a list of steps in a process."""
|
|
466
|
-
|
|
467
|
-
is_vertical = blocks.BooleanBlock(
|
|
468
|
-
default=False,
|
|
469
|
-
required=False,
|
|
470
|
-
help_text=_("Designates if Steps is vertical or horizontal (default)"),
|
|
471
|
-
)
|
|
472
|
-
items = blocks.ListBlock(
|
|
473
|
-
StepItem(),
|
|
474
|
-
required=True,
|
|
475
|
-
help_text=_("Steps items"),
|
|
476
|
-
)
|
|
477
|
-
|
|
478
|
-
class Meta:
|
|
479
|
-
"""Meta data"""
|
|
480
|
-
|
|
481
|
-
icon = "breadcrumb-expand"
|
|
482
|
-
template = "wagtail_blocks/blocks/steps.html"
|
|
262
|
+
template = "wagtail/blocks/hover_gallery.html"
|
|
483
263
|
|
|
484
264
|
|
|
485
265
|
class TabItem(blocks.StructBlock):
|
|
@@ -487,23 +267,16 @@ class TabItem(blocks.StructBlock):
|
|
|
487
267
|
|
|
488
268
|
title = blocks.CharBlock(
|
|
489
269
|
max_length=64,
|
|
490
|
-
|
|
491
|
-
help_text=_("Item title"),
|
|
492
|
-
)
|
|
493
|
-
is_selected = blocks.BooleanBlock(
|
|
494
|
-
default=False,
|
|
495
|
-
required=False,
|
|
496
|
-
help_text=_("Designates if tab is selected"),
|
|
270
|
+
help_text=_("Tab title"),
|
|
497
271
|
)
|
|
498
272
|
content = blocks.StreamBlock(
|
|
499
273
|
[
|
|
500
|
-
("alert", AlertBlock(
|
|
501
|
-
("code", CodeBlock(
|
|
502
|
-
("image", ImageBlock(
|
|
503
|
-
("video", EmbedBlock(
|
|
504
|
-
("text", blocks.RichTextBlock(
|
|
274
|
+
("alert", AlertBlock(help_text=_("Alert"))),
|
|
275
|
+
("code", CodeBlock(help_text=_("Code"))),
|
|
276
|
+
("image", ImageBlock(help_text=_("Image"))),
|
|
277
|
+
("video", EmbedBlock(help_text=_("Video"))),
|
|
278
|
+
("text", blocks.RichTextBlock(help_text=_("Text"))),
|
|
505
279
|
],
|
|
506
|
-
required=True,
|
|
507
280
|
help_text=_("Tab Content"),
|
|
508
281
|
)
|
|
509
282
|
|
|
@@ -511,25 +284,12 @@ class TabItem(blocks.StructBlock):
|
|
|
511
284
|
class TabsBlock(blocks.StructBlock):
|
|
512
285
|
"""Tabs can be used to show a list of links in a tabbed format."""
|
|
513
286
|
|
|
514
|
-
name = blocks.CharBlock(
|
|
515
|
-
max_length=64,
|
|
516
|
-
required=True,
|
|
517
|
-
help_text=_("Tab name"),
|
|
518
|
-
)
|
|
519
|
-
is_reversed = blocks.BooleanBlock(
|
|
520
|
-
default=False,
|
|
521
|
-
required=False,
|
|
522
|
-
help_text=_("Designates if tab buttons position is reversed"),
|
|
523
|
-
)
|
|
524
287
|
style = blocks.ChoiceBlock(
|
|
525
|
-
choices=TAB_STYLES,
|
|
526
|
-
default="border",
|
|
527
|
-
required=True,
|
|
288
|
+
choices=constants.TAB_STYLES,
|
|
528
289
|
help_text=_("Tab style"),
|
|
529
290
|
)
|
|
530
291
|
items = blocks.ListBlock(
|
|
531
292
|
TabItem(),
|
|
532
|
-
required=True,
|
|
533
293
|
help_text=_("Tab items"),
|
|
534
294
|
)
|
|
535
295
|
|
|
@@ -537,153 +297,14 @@ class TabsBlock(blocks.StructBlock):
|
|
|
537
297
|
"""Meta data"""
|
|
538
298
|
|
|
539
299
|
icon = "dots-horizontal"
|
|
540
|
-
template = "
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
class Meta:
|
|
553
|
-
"""Meta data"""
|
|
554
|
-
|
|
555
|
-
icon = "mail"
|
|
556
|
-
template = "wagtail_blocks/blocks/toast.html"
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
class ListItem(blocks.StructBlock):
|
|
560
|
-
"""List item"""
|
|
561
|
-
|
|
562
|
-
image = WImageBlock(
|
|
563
|
-
required=False,
|
|
564
|
-
help_text=_("Item image"),
|
|
565
|
-
)
|
|
566
|
-
title = blocks.CharBlock(
|
|
567
|
-
max_length=64,
|
|
568
|
-
required=True,
|
|
569
|
-
help_text=_("Item title"),
|
|
570
|
-
)
|
|
571
|
-
description = blocks.CharBlock(
|
|
572
|
-
max_length=128,
|
|
573
|
-
required=False,
|
|
574
|
-
help_text=_("Item description"),
|
|
575
|
-
)
|
|
576
|
-
page = blocks.PageChooserBlock(
|
|
577
|
-
required=False,
|
|
578
|
-
help_text=_("Item internal link"),
|
|
579
|
-
)
|
|
580
|
-
url = blocks.URLBlock(
|
|
581
|
-
required=False,
|
|
582
|
-
help_text=_("Item external link"),
|
|
583
|
-
)
|
|
584
|
-
actions = blocks.ListBlock(
|
|
585
|
-
ButtonBlock(),
|
|
586
|
-
required=False,
|
|
587
|
-
help_text=_("Actions"),
|
|
588
|
-
)
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
class ListBlock(blocks.StructBlock):
|
|
592
|
-
"""List is a vertical layout to display information in rows."""
|
|
593
|
-
|
|
594
|
-
title = blocks.CharBlock(
|
|
595
|
-
max_length=64,
|
|
596
|
-
required=True,
|
|
597
|
-
help_text=_("List title"),
|
|
598
|
-
)
|
|
599
|
-
items = blocks.ListBlock(
|
|
600
|
-
ListItem(),
|
|
601
|
-
required=True,
|
|
602
|
-
help_text=_("List items"),
|
|
603
|
-
)
|
|
604
|
-
|
|
605
|
-
class Meta:
|
|
606
|
-
"""Meta data"""
|
|
607
|
-
|
|
608
|
-
icon = "list-ol"
|
|
609
|
-
template = "wagtail_blocks/blocks/list.html"
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
class PhoneMockupBlock(blocks.StructBlock):
|
|
613
|
-
"""Phone mockup shows a mockup of an iPhone."""
|
|
614
|
-
|
|
615
|
-
show_camera = blocks.BooleanBlock(
|
|
616
|
-
default=True,
|
|
617
|
-
required=False,
|
|
618
|
-
help_text=_("Whether to show or hide camera"),
|
|
619
|
-
)
|
|
620
|
-
wallpaper = WImageBlock(
|
|
621
|
-
required=True,
|
|
622
|
-
help_text=_("Phone wallpaper"),
|
|
623
|
-
)
|
|
624
|
-
|
|
625
|
-
class Meta:
|
|
626
|
-
"""Meta data"""
|
|
627
|
-
|
|
628
|
-
icon = "mobile-alt"
|
|
629
|
-
template = "wagtail_blocks/blocks/phone.html"
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
class BrowserMockupBlock(blocks.StructBlock):
|
|
633
|
-
"""Browser mockup shows a box that looks like a browser window."""
|
|
634
|
-
|
|
635
|
-
show_url = blocks.BooleanBlock(
|
|
636
|
-
default=True,
|
|
637
|
-
required=False,
|
|
638
|
-
help_text=_("Whether to show or hide toolbar"),
|
|
639
|
-
)
|
|
640
|
-
url = blocks.URLBlock(
|
|
641
|
-
required=True,
|
|
642
|
-
help_text=_("Browser URL"),
|
|
643
|
-
)
|
|
644
|
-
wallpaper = WImageBlock(
|
|
645
|
-
required=True,
|
|
646
|
-
help_text=_("Browser wallpaper"),
|
|
647
|
-
)
|
|
648
|
-
|
|
649
|
-
class Meta:
|
|
650
|
-
"""Meta data"""
|
|
651
|
-
|
|
652
|
-
icon = "desktop"
|
|
653
|
-
template = "wagtail_blocks/blocks/browser.html"
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
class WindowMockupBlock(blocks.StructBlock):
|
|
657
|
-
"""Window mockup shows a box that looks like an operating system window."""
|
|
658
|
-
|
|
659
|
-
wallpaper = WImageBlock(
|
|
660
|
-
required=True,
|
|
661
|
-
help_text=_("Window wallpaper"),
|
|
662
|
-
)
|
|
663
|
-
|
|
664
|
-
class Meta:
|
|
665
|
-
"""Meta data"""
|
|
666
|
-
|
|
667
|
-
icon = "desktop"
|
|
668
|
-
template = "wagtail_blocks/blocks/window.html"
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
class CodeMockupBlock(blocks.StructBlock):
|
|
672
|
-
"""Code mockup is used to show a block of code in a box that looks like a code editor."""
|
|
673
|
-
|
|
674
|
-
language = blocks.ChoiceBlock(
|
|
675
|
-
choices=PROGRAMMING_LANGUAGES,
|
|
676
|
-
default="auto",
|
|
677
|
-
required=True,
|
|
678
|
-
help_text=_("Programming language"),
|
|
679
|
-
)
|
|
680
|
-
code = blocks.TextBlock(
|
|
681
|
-
required=True,
|
|
682
|
-
help_text=_("Code content"),
|
|
683
|
-
)
|
|
684
|
-
|
|
685
|
-
class Meta:
|
|
686
|
-
"""Meta data"""
|
|
687
|
-
|
|
688
|
-
icon = "code"
|
|
689
|
-
template = "wagtail_blocks/blocks/code_mockup.html"
|
|
300
|
+
template = "wagtail/blocks/tabs.html"
|
|
301
|
+
|
|
302
|
+
def get_context(
|
|
303
|
+
self,
|
|
304
|
+
value: Dict[str, Any],
|
|
305
|
+
parent_context: Optional[Dict[str, Any]] = None,
|
|
306
|
+
) -> Dict[str, Any]:
|
|
307
|
+
return {
|
|
308
|
+
**super().get_context(value, parent_context),
|
|
309
|
+
"name": get_random_string(5),
|
|
310
|
+
}
|