Browse Source

Add block previews (#521)

sag​e 2 months ago
parent
commit
3d6e7b6b2e

+ 42 - 1
bakerydemo/base/blocks.py

@@ -1,3 +1,4 @@
+from django.utils.functional import cached_property
 from wagtail.blocks import (
     CharBlock,
     ChoiceBlock,
@@ -7,6 +8,7 @@ from wagtail.blocks import (
     TextBlock,
 )
 from wagtail.embeds.blocks import EmbedBlock
+from wagtail.images import get_image_model
 from wagtail.images.blocks import ImageChooserBlock
 
 
@@ -20,9 +22,23 @@ class ImageBlock(StructBlock):
     caption = CharBlock(required=False)
     attribution = CharBlock(required=False)
 
+    @cached_property
+    def preview_image(self):
+        # Cache the image object for previews to avoid repeated queries
+        return get_image_model().objects.last()
+
+    def get_preview_value(self):
+        return {
+            **self.meta.preview_value,
+            "image": self.preview_image,
+            "caption": self.preview_image.description,
+        }
+
     class Meta:
         icon = "image"
         template = "blocks/image_block.html"
+        preview_value = {"attribution": "The Wagtail Bakery"}
+        description = "An image with optional caption and attribution"
 
 
 class HeadingBlock(StructBlock):
@@ -45,6 +61,8 @@ class HeadingBlock(StructBlock):
     class Meta:
         icon = "title"
         template = "blocks/heading_block.html"
+        preview_value = {"heading_text": "Healthy bread types", "size": "h2"}
+        description = "A heading with level two, three, or four"
 
 
 class BlockQuote(StructBlock):
@@ -58,6 +76,14 @@ class BlockQuote(StructBlock):
     class Meta:
         icon = "openquote"
         template = "blocks/blockquote.html"
+        preview_value = {
+            "text": (
+                "If you read a lot you're well read / "
+                "If you eat a lot you're well bread."
+            ),
+            "attribute_name": "Willie Wagtail",
+        }
+        description = "A quote with an optional attribution"
 
 
 # StreamBlocks
@@ -68,7 +94,19 @@ class BaseStreamBlock(StreamBlock):
 
     heading_block = HeadingBlock()
     paragraph_block = RichTextBlock(
-        icon="pilcrow", template="blocks/paragraph_block.html"
+        icon="pilcrow",
+        template="blocks/paragraph_block.html",
+        preview_value=(
+            """
+            <h2>Our bread pledge</h2>
+            <p>As a bakery, <b>breads</b> have <i>always</i> been in our hearts.
+            <a href="https://en.wikipedia.org/wiki/Staple_food">Staple foods</a>
+            are essential for society, and – bread is the tastiest of all.
+            We love to transform batters and doughs into baked goods with a firm
+            dry crust and fluffy center.</p>
+            """
+        ),
+        description="A rich text paragraph",
     )
     image_block = ImageBlock()
     block_quote = BlockQuote()
@@ -76,4 +114,7 @@ class BaseStreamBlock(StreamBlock):
         help_text="Insert an embed URL e.g https://www.youtube.com/watch?v=SGJFWirQ3ks",
         icon="media",
         template="blocks/embed_block.html",
+        preview_template="base/preview/static_embed_block.html",
+        preview_value="https://www.youtube.com/watch?v=mwrGSfiB1Mg",
+        description="An embedded video or other media",
     )

+ 71 - 1
bakerydemo/recipes/blocks.py

@@ -39,7 +39,19 @@ class RecipeStreamBlock(StreamBlock):
         icon="pilcrow", template="blocks/paragraph_block.html", group="Content"
     )
     block_quote = BlockQuote(group="Content")
-    table_block = TableBlock(group="Content")
+    table_block = TableBlock(
+        group="Content",
+        description="A table of data with plain text cells",
+        preview_value={
+            "first_row_is_table_header": "True",
+            "data": [
+                ["Bread type", "Origin"],
+                ["Anpan", "Japan"],
+                ["Crumpet", "United Kingdom"],
+                ["Roti buaya", "Indonesia"],
+            ],
+        },
+    )
     typed_table_block = TypedTableBlock(
         [
             ("text", CharBlock()),
@@ -48,6 +60,48 @@ class RecipeStreamBlock(StreamBlock):
             ("image", ImageChooserBlock()),
         ],
         group="Content",
+        description=(
+            "A table of data with cells that can include "
+            "text, numbers, rich text, and images"
+        ),
+        preview_value={
+            "caption": "Nutritional information for 100g of bread",
+            "columns": [
+                {"type": "rich_text", "heading": "Nutrient"},
+                {"type": "numeric", "heading": "White bread"},
+                {"type": "numeric", "heading": "Brown bread"},
+                {"type": "numeric", "heading": "Wholemeal bread"},
+            ],
+            "rows": [
+                {
+                    "values": [
+                        '<p><a href="https://en.wikipedia.org/wiki/Protein">'
+                        "Protein</a> <b>(g)</b></p>",
+                        7.9,
+                        7.9,
+                        9.4,
+                    ]
+                },
+                {
+                    "values": [
+                        '<p><a href="https://en.wikipedia.org/wiki/Carbohydrate">'
+                        "Carbohydrate</a> <b>(g)</b></p>",
+                        46.1,
+                        42.1,
+                        42,
+                    ]
+                },
+                {
+                    "values": [
+                        '<p><a href="https://en.wikipedia.org/wiki/Sugar">'
+                        "Total sugars</a> <b>(g)</b></p>",
+                        3.4,
+                        3.4,
+                        2.8,
+                    ]
+                },
+            ],
+        },
     )
 
     image_block = ImageBlock(group="Media")
@@ -56,6 +110,8 @@ class RecipeStreamBlock(StreamBlock):
         icon="media",
         template="blocks/embed_block.html",
         group="Media",
+        preview_value="https://www.youtube.com/watch?v=mwrGSfiB1Mg",
+        description="An embedded video or other media",
     )
 
     ingredients_list = ListBlock(
@@ -64,6 +120,11 @@ class RecipeStreamBlock(StreamBlock):
         max_num=10,
         icon="list-ol",
         group="Cooking",
+        preview_value=["<p>200g flour</p>", "<p>1 egg</p>", "<p>1 cup of sugar</p>"],
+        description=(
+            "A list of ingredients to use in the recipe "
+            "with optional bold, italic, and link options"
+        ),
     )
     steps_list = ListBlock(
         RecipeStepBlock(),
@@ -71,4 +132,13 @@ class RecipeStreamBlock(StreamBlock):
         max_num=10,
         icon="tasks",
         group="Cooking",
+        preview_value=[
+            {"text": "<p>An easy step</p>", "difficulty": "S"},
+            {"text": "<p>A difficult step</p>", "difficulty": "L"},
+            {"text": "<p>A medium step</p>", "difficulty": "M"},
+        ],
+        description=(
+            "A list of steps to follow in the recipe, "
+            "with a difficulty rating for each step"
+        ),
     )

+ 13 - 0
bakerydemo/static/css/main.css

@@ -2092,3 +2092,16 @@ input[type='radio'] {
   white-space: nowrap;
   border: 0;
 }
+
+/* Block previews */
+
+.block-preview {
+  padding: 1rem;
+}
+
+.static-block-preview {
+  width: initial;
+  max-width: 100vw;
+  max-height: 100vh;
+  margin-inline: auto;
+}

+ 20 - 0
bakerydemo/templates/base/preview/static_embed_block.html

@@ -0,0 +1,20 @@
+{% extends "wagtailcore/shared/block_preview.html" %}
+{% load static %}
+
+{% block content %}
+    <svg class="static-block-preview" viewBox="0 0 360 246">
+        <title>Preview of an embedded video</title>
+        <rect fill="light-dark(#fff, #1d1d1d)" height="245.5" rx="10" width="360" y=".5" />
+        <rect fill="light-dark(#e0e0e0, #464646)" height="211.5" rx="7" width="340" x="10" y="10.5" />
+        <path
+            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"
+            fill="light-dark(#fff, #1d1d1d)"
+        />
+        <g fill="light-dark(#e0e0e0, #464646)">
+            <rect height="4" rx="2" width="24" x="13" y="232" />
+            <rect height="4" rx="2" width="33" x="41" y="232" />
+            <rect height="4" rx="2" width="57" x="78" y="232" />
+            <rect height="4" rx="2" width="33" x="139" y="232" />
+        </g>
+    </svg>
+{% endblock %}

+ 21 - 0
bakerydemo/templates/wagtailcore/shared/block_preview.html

@@ -0,0 +1,21 @@
+{% extends "wagtailcore/shared/block_preview.html" %}
+{% load static %}
+
+{% block content %}
+    {# Add a wrapper so we can add padding with our own CSS class #}
+    <div class="block-preview">
+        {{ block.super }}
+    </div>
+{% endblock %}
+
+{% block css %}
+    {{ block.super }}
+    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
+    <link rel="stylesheet" href="{% static 'css/font-marcellus.css' %}">
+    <link rel="stylesheet" href="{% static 'css/main.css' %}">
+{% endblock %}
+
+{% block js %}
+    {# None of our blocks need JavaScript at the moment. #}
+    {{ block.super }}
+{% endblock %}