Skip to content

Commit 3d6e7b6

Browse files
authored
Add block previews (wagtail#521)
1 parent 5e261b5 commit 3d6e7b6

File tree

5 files changed

+167
-2
lines changed

5 files changed

+167
-2
lines changed

bakerydemo/base/blocks.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.utils.functional import cached_property
12
from wagtail.blocks import (
23
CharBlock,
34
ChoiceBlock,
@@ -7,6 +8,7 @@
78
TextBlock,
89
)
910
from wagtail.embeds.blocks import EmbedBlock
11+
from wagtail.images import get_image_model
1012
from wagtail.images.blocks import ImageChooserBlock
1113

1214

@@ -20,9 +22,23 @@ class ImageBlock(StructBlock):
2022
caption = CharBlock(required=False)
2123
attribution = CharBlock(required=False)
2224

25+
@cached_property
26+
def preview_image(self):
27+
# Cache the image object for previews to avoid repeated queries
28+
return get_image_model().objects.last()
29+
30+
def get_preview_value(self):
31+
return {
32+
**self.meta.preview_value,
33+
"image": self.preview_image,
34+
"caption": self.preview_image.description,
35+
}
36+
2337
class Meta:
2438
icon = "image"
2539
template = "blocks/image_block.html"
40+
preview_value = {"attribution": "The Wagtail Bakery"}
41+
description = "An image with optional caption and attribution"
2642

2743

2844
class HeadingBlock(StructBlock):
@@ -45,6 +61,8 @@ class HeadingBlock(StructBlock):
4561
class Meta:
4662
icon = "title"
4763
template = "blocks/heading_block.html"
64+
preview_value = {"heading_text": "Healthy bread types", "size": "h2"}
65+
description = "A heading with level two, three, or four"
4866

4967

5068
class BlockQuote(StructBlock):
@@ -58,6 +76,14 @@ class BlockQuote(StructBlock):
5876
class Meta:
5977
icon = "openquote"
6078
template = "blocks/blockquote.html"
79+
preview_value = {
80+
"text": (
81+
"If you read a lot you're well read / "
82+
"If you eat a lot you're well bread."
83+
),
84+
"attribute_name": "Willie Wagtail",
85+
}
86+
description = "A quote with an optional attribution"
6187

6288

6389
# StreamBlocks
@@ -68,12 +94,27 @@ class BaseStreamBlock(StreamBlock):
6894

6995
heading_block = HeadingBlock()
7096
paragraph_block = RichTextBlock(
71-
icon="pilcrow", template="blocks/paragraph_block.html"
97+
icon="pilcrow",
98+
template="blocks/paragraph_block.html",
99+
preview_value=(
100+
"""
101+
<h2>Our bread pledge</h2>
102+
<p>As a bakery, <b>breads</b> have <i>always</i> been in our hearts.
103+
<a href="https://en.wikipedia.org/wiki/Staple_food">Staple foods</a>
104+
are essential for society, and – bread is the tastiest of all.
105+
We love to transform batters and doughs into baked goods with a firm
106+
dry crust and fluffy center.</p>
107+
"""
108+
),
109+
description="A rich text paragraph",
72110
)
73111
image_block = ImageBlock()
74112
block_quote = BlockQuote()
75113
embed_block = EmbedBlock(
76114
help_text="Insert an embed URL e.g https://www.youtube.com/watch?v=SGJFWirQ3ks",
77115
icon="media",
78116
template="blocks/embed_block.html",
117+
preview_template="base/preview/static_embed_block.html",
118+
preview_value="https://www.youtube.com/watch?v=mwrGSfiB1Mg",
119+
description="An embedded video or other media",
79120
)

bakerydemo/recipes/blocks.py

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@ class RecipeStreamBlock(StreamBlock):
3939
icon="pilcrow", template="blocks/paragraph_block.html", group="Content"
4040
)
4141
block_quote = BlockQuote(group="Content")
42-
table_block = TableBlock(group="Content")
42+
table_block = TableBlock(
43+
group="Content",
44+
description="A table of data with plain text cells",
45+
preview_value={
46+
"first_row_is_table_header": "True",
47+
"data": [
48+
["Bread type", "Origin"],
49+
["Anpan", "Japan"],
50+
["Crumpet", "United Kingdom"],
51+
["Roti buaya", "Indonesia"],
52+
],
53+
},
54+
)
4355
typed_table_block = TypedTableBlock(
4456
[
4557
("text", CharBlock()),
@@ -48,6 +60,48 @@ class RecipeStreamBlock(StreamBlock):
4860
("image", ImageChooserBlock()),
4961
],
5062
group="Content",
63+
description=(
64+
"A table of data with cells that can include "
65+
"text, numbers, rich text, and images"
66+
),
67+
preview_value={
68+
"caption": "Nutritional information for 100g of bread",
69+
"columns": [
70+
{"type": "rich_text", "heading": "Nutrient"},
71+
{"type": "numeric", "heading": "White bread"},
72+
{"type": "numeric", "heading": "Brown bread"},
73+
{"type": "numeric", "heading": "Wholemeal bread"},
74+
],
75+
"rows": [
76+
{
77+
"values": [
78+
'<p><a href="https://en.wikipedia.org/wiki/Protein">'
79+
"Protein</a> <b>(g)</b></p>",
80+
7.9,
81+
7.9,
82+
9.4,
83+
]
84+
},
85+
{
86+
"values": [
87+
'<p><a href="https://en.wikipedia.org/wiki/Carbohydrate">'
88+
"Carbohydrate</a> <b>(g)</b></p>",
89+
46.1,
90+
42.1,
91+
42,
92+
]
93+
},
94+
{
95+
"values": [
96+
'<p><a href="https://en.wikipedia.org/wiki/Sugar">'
97+
"Total sugars</a> <b>(g)</b></p>",
98+
3.4,
99+
3.4,
100+
2.8,
101+
]
102+
},
103+
],
104+
},
51105
)
52106

53107
image_block = ImageBlock(group="Media")
@@ -56,6 +110,8 @@ class RecipeStreamBlock(StreamBlock):
56110
icon="media",
57111
template="blocks/embed_block.html",
58112
group="Media",
113+
preview_value="https://www.youtube.com/watch?v=mwrGSfiB1Mg",
114+
description="An embedded video or other media",
59115
)
60116

61117
ingredients_list = ListBlock(
@@ -64,11 +120,25 @@ class RecipeStreamBlock(StreamBlock):
64120
max_num=10,
65121
icon="list-ol",
66122
group="Cooking",
123+
preview_value=["<p>200g flour</p>", "<p>1 egg</p>", "<p>1 cup of sugar</p>"],
124+
description=(
125+
"A list of ingredients to use in the recipe "
126+
"with optional bold, italic, and link options"
127+
),
67128
)
68129
steps_list = ListBlock(
69130
RecipeStepBlock(),
70131
min_num=2,
71132
max_num=10,
72133
icon="tasks",
73134
group="Cooking",
135+
preview_value=[
136+
{"text": "<p>An easy step</p>", "difficulty": "S"},
137+
{"text": "<p>A difficult step</p>", "difficulty": "L"},
138+
{"text": "<p>A medium step</p>", "difficulty": "M"},
139+
],
140+
description=(
141+
"A list of steps to follow in the recipe, "
142+
"with a difficulty rating for each step"
143+
),
74144
)

bakerydemo/static/css/main.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,3 +2092,16 @@ input[type='radio'] {
20922092
white-space: nowrap;
20932093
border: 0;
20942094
}
2095+
2096+
/* Block previews */
2097+
2098+
.block-preview {
2099+
padding: 1rem;
2100+
}
2101+
2102+
.static-block-preview {
2103+
width: initial;
2104+
max-width: 100vw;
2105+
max-height: 100vh;
2106+
margin-inline: auto;
2107+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{% extends "wagtailcore/shared/block_preview.html" %}
2+
{% load static %}
3+
4+
{% block content %}
5+
<svg class="static-block-preview" viewBox="0 0 360 246">
6+
<title>Preview of an embedded video</title>
7+
<rect fill="light-dark(#fff, #1d1d1d)" height="245.5" rx="10" width="360" y=".5" />
8+
<rect fill="light-dark(#e0e0e0, #464646)" height="211.5" rx="7" width="340" x="10" y="10.5" />
9+
<path
10+
d="m203.412 113.029c1.732 1.193 1.732 3.749 0 4.942l-44.71 30.791c-1.991 1.371-4.702-.054-4.702-2.471v-61.5824c0-2.4166 2.711-3.8414 4.702-2.4707z"
11+
fill="light-dark(#fff, #1d1d1d)"
12+
/>
13+
<g fill="light-dark(#e0e0e0, #464646)">
14+
<rect height="4" rx="2" width="24" x="13" y="232" />
15+
<rect height="4" rx="2" width="33" x="41" y="232" />
16+
<rect height="4" rx="2" width="57" x="78" y="232" />
17+
<rect height="4" rx="2" width="33" x="139" y="232" />
18+
</g>
19+
</svg>
20+
{% endblock %}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{% extends "wagtailcore/shared/block_preview.html" %}
2+
{% load static %}
3+
4+
{% block content %}
5+
{# Add a wrapper so we can add padding with our own CSS class #}
6+
<div class="block-preview">
7+
{{ block.super }}
8+
</div>
9+
{% endblock %}
10+
11+
{% block css %}
12+
{{ block.super }}
13+
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
14+
<link rel="stylesheet" href="{% static 'css/font-marcellus.css' %}">
15+
<link rel="stylesheet" href="{% static 'css/main.css' %}">
16+
{% endblock %}
17+
18+
{% block js %}
19+
{# None of our blocks need JavaScript at the moment. #}
20+
{{ block.super }}
21+
{% endblock %}

0 commit comments

Comments
 (0)