blocks.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. from django.utils.functional import cached_property
  2. from wagtail.blocks import (
  3. CharBlock,
  4. ChoiceBlock,
  5. RichTextBlock,
  6. StreamBlock,
  7. StructBlock,
  8. TextBlock,
  9. )
  10. from wagtail.embeds.blocks import EmbedBlock
  11. from wagtail.images import get_image_model
  12. from wagtail.images.blocks import ImageChooserBlock
  13. def get_image_api_representation(image):
  14. return {
  15. "id": image.pk,
  16. "title": image.title,
  17. "meta": {
  18. "type": type(image)._meta.label,
  19. "download_url": image.file.url,
  20. },
  21. }
  22. class CaptionedImageBlock(StructBlock):
  23. """
  24. Custom `StructBlock` for utilizing images with associated caption and
  25. attribution data
  26. """
  27. image = ImageChooserBlock(required=True)
  28. caption = CharBlock(required=False)
  29. attribution = CharBlock(required=False)
  30. @cached_property
  31. def preview_image(self):
  32. # Cache the image object for previews to avoid repeated queries
  33. return get_image_model().objects.last()
  34. def get_preview_value(self):
  35. return {
  36. **self.meta.preview_value,
  37. "image": self.preview_image,
  38. "caption": self.preview_image.description,
  39. }
  40. def get_api_representation(self, value, context=None):
  41. data = super().get_api_representation(value, context)
  42. data["image"] = get_image_api_representation(value["image"])
  43. return data
  44. class Meta:
  45. icon = "image"
  46. template = "blocks/captioned_image_block.html"
  47. preview_value = {"attribution": "The Wagtail Bakery"}
  48. description = "An image with optional caption and attribution"
  49. class HeadingBlock(StructBlock):
  50. """
  51. Custom `StructBlock` that allows the user to select h2 - h4 sizes for headers
  52. """
  53. heading_text = CharBlock(classname="title", required=True)
  54. size = ChoiceBlock(
  55. choices=[
  56. ("", "Select a header size"),
  57. ("h2", "H2"),
  58. ("h3", "H3"),
  59. ("h4", "H4"),
  60. ],
  61. blank=True,
  62. required=False,
  63. )
  64. class Meta:
  65. icon = "title"
  66. template = "blocks/heading_block.html"
  67. preview_value = {"heading_text": "Healthy bread types", "size": "h2"}
  68. description = "A heading with level two, three, or four"
  69. class ThemeSettingsBlock(StructBlock):
  70. theme = ChoiceBlock(
  71. choices=[
  72. ("default", "Default"),
  73. ("highlight", "Highlight"),
  74. ],
  75. required=False,
  76. default="default",
  77. )
  78. text_size = ChoiceBlock(
  79. choices=[
  80. ("default", "Default"),
  81. ("large", "Large"),
  82. ],
  83. required=False,
  84. default="default",
  85. )
  86. class Meta:
  87. icon = "cog"
  88. label_format = "Theme: {theme}, Text size: {text_size}"
  89. class BlockQuote(StructBlock):
  90. """
  91. Custom `StructBlock` that allows the user to attribute a quote to the author
  92. """
  93. text = TextBlock()
  94. attribute_name = CharBlock(blank=True, required=False, label="e.g. Mary Berry")
  95. settings = ThemeSettingsBlock(collapsed=True)
  96. class Meta:
  97. icon = "openquote"
  98. template = "blocks/blockquote.html"
  99. preview_value = {
  100. "text": (
  101. "If you read a lot you're well read / "
  102. "If you eat a lot you're well bread."
  103. ),
  104. "attribute_name": "Willie Wagtail",
  105. }
  106. description = "A quote with an optional attribution"
  107. # StreamBlocks
  108. class BaseStreamBlock(StreamBlock):
  109. """
  110. Define the custom blocks that `StreamField` will utilize
  111. """
  112. heading_block = HeadingBlock()
  113. paragraph_block = RichTextBlock(
  114. icon="pilcrow",
  115. template="blocks/paragraph_block.html",
  116. preview_value=(
  117. """
  118. <h2>Our bread pledge</h2>
  119. <p>As a bakery, <b>breads</b> have <i>always</i> been in our hearts.
  120. <a href="https://en.wikipedia.org/wiki/Staple_food">Staple foods</a>
  121. are essential for society, and – bread is the tastiest of all.
  122. We love to transform batters and doughs into baked goods with a firm
  123. dry crust and fluffy center.</p>
  124. """
  125. ),
  126. description="A rich text paragraph",
  127. )
  128. image_block = CaptionedImageBlock()
  129. block_quote = BlockQuote()
  130. embed_block = EmbedBlock(
  131. help_text="Insert an embed URL e.g https://www.youtube.com/watch?v=SGJFWirQ3ks",
  132. icon="media",
  133. template="blocks/embed_block.html",
  134. preview_template="base/preview/static_embed_block.html",
  135. preview_value="https://www.youtube.com/watch?v=mwrGSfiB1Mg",
  136. description="An embedded video or other media",
  137. )