blocks.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. from django import forms
  2. from wagtail.blocks import (
  3. CharBlock,
  4. ChoiceBlock,
  5. FloatBlock,
  6. ListBlock,
  7. RichTextBlock,
  8. StreamBlock,
  9. StructBlock,
  10. )
  11. from wagtail.contrib.table_block.blocks import TableBlock
  12. from wagtail.contrib.typed_table_block.blocks import TypedTableBlock
  13. from wagtail.embeds.blocks import EmbedBlock
  14. from wagtail.images.blocks import ImageBlock
  15. from bakerydemo.base.blocks import (
  16. BlockQuote,
  17. HeadingBlock,
  18. get_image_api_representation,
  19. )
  20. class CustomImageBlock(ImageBlock):
  21. def get_api_representation(self, value, context=None):
  22. data = super().get_api_representation(value, context)
  23. data["image"] = get_image_api_representation(value)
  24. return data
  25. class Meta:
  26. form_attrs = {
  27. "data-controller": "alt-text",
  28. "data-alt-text-image-input-value": "[data-contentpath='image'] input[type='hidden']",
  29. "data-alt-text-caption-input-value": "[data-contentpath='alt_text'] input[type='text']",
  30. "data-action": "change->alt-text#toggleSuggestTarget",
  31. # Change the following to true if you want the form context to be
  32. # used when generating alt text. Note that the model is not very
  33. # accurate at the moment, so it may not be useful.
  34. "data-alt-text-contextual-value": "false",
  35. }
  36. class RecipeStepBlock(StructBlock):
  37. text = RichTextBlock(features=["bold", "italic", "link"])
  38. difficulty = ChoiceBlock(
  39. widget=forms.RadioSelect,
  40. choices=[("S", "Small"), ("M", "Medium"), ("L", "Large")],
  41. default="S",
  42. )
  43. class Meta:
  44. template = "blocks/recipe_step_block.html"
  45. icon = "tick"
  46. class RecipeStreamBlock(StreamBlock):
  47. """
  48. Define the custom blocks that `StreamField` will utilize
  49. """
  50. heading_block = HeadingBlock(group="Content")
  51. paragraph_block = RichTextBlock(
  52. icon="pilcrow", template="blocks/paragraph_block.html", group="Content"
  53. )
  54. block_quote = BlockQuote(group="Content")
  55. table_block = TableBlock(
  56. group="Content",
  57. description="A table of data with plain text cells",
  58. preview_value={
  59. "first_row_is_table_header": "True",
  60. "data": [
  61. ["Bread type", "Origin"],
  62. ["Anpan", "Japan"],
  63. ["Crumpet", "United Kingdom"],
  64. ["Roti buaya", "Indonesia"],
  65. ],
  66. },
  67. )
  68. typed_table_block = TypedTableBlock(
  69. [
  70. ("text", CharBlock()),
  71. ("numeric", FloatBlock()),
  72. ("rich_text", RichTextBlock()),
  73. ("image", CustomImageBlock()),
  74. ],
  75. group="Content",
  76. description=(
  77. "A table of data with cells that can include "
  78. "text, numbers, rich text, and images"
  79. ),
  80. preview_value={
  81. "caption": "Nutritional information for 100g of bread",
  82. "columns": [
  83. {"type": "rich_text", "heading": "Nutrient"},
  84. {"type": "numeric", "heading": "White bread"},
  85. {"type": "numeric", "heading": "Brown bread"},
  86. {"type": "numeric", "heading": "Wholemeal bread"},
  87. ],
  88. "rows": [
  89. {
  90. "values": [
  91. '<p><a href="https://en.wikipedia.org/wiki/Protein">'
  92. "Protein</a> <b>(g)</b></p>",
  93. 7.9,
  94. 7.9,
  95. 9.4,
  96. ]
  97. },
  98. {
  99. "values": [
  100. '<p><a href="https://en.wikipedia.org/wiki/Carbohydrate">'
  101. "Carbohydrate</a> <b>(g)</b></p>",
  102. 46.1,
  103. 42.1,
  104. 42,
  105. ]
  106. },
  107. {
  108. "values": [
  109. '<p><a href="https://en.wikipedia.org/wiki/Sugar">'
  110. "Total sugars</a> <b>(g)</b></p>",
  111. 3.4,
  112. 3.4,
  113. 2.8,
  114. ]
  115. },
  116. ],
  117. },
  118. )
  119. image_block = CustomImageBlock(group="Media")
  120. embed_block = EmbedBlock(
  121. help_text="Insert an embed URL e.g https://www.youtube.com/watch?v=SGJFWirQ3ks",
  122. icon="media",
  123. template="blocks/embed_block.html",
  124. group="Media",
  125. preview_value="https://www.youtube.com/watch?v=mwrGSfiB1Mg",
  126. description="An embedded video or other media",
  127. )
  128. ingredients_list = ListBlock(
  129. RichTextBlock(features=["bold", "italic", "link"]),
  130. min_num=2,
  131. max_num=10,
  132. icon="list-ol",
  133. group="Cooking",
  134. preview_value=["<p>200g flour</p>", "<p>1 egg</p>", "<p>1 cup of sugar</p>"],
  135. description=(
  136. "A list of ingredients to use in the recipe "
  137. "with optional bold, italic, and link options"
  138. ),
  139. )
  140. steps_list = ListBlock(
  141. RecipeStepBlock(),
  142. min_num=2,
  143. max_num=10,
  144. icon="tasks",
  145. group="Cooking",
  146. preview_value=[
  147. {"text": "<p>An easy step</p>", "difficulty": "S"},
  148. {"text": "<p>A difficult step</p>", "difficulty": "L"},
  149. {"text": "<p>A medium step</p>", "difficulty": "M"},
  150. ],
  151. description=(
  152. "A list of steps to follow in the recipe, "
  153. "with a difficulty rating for each step"
  154. ),
  155. )