diff --git a/books/models.py b/books/models.py index c5c4f375..c0991832 100644 --- a/books/models.py +++ b/books/models.py @@ -74,6 +74,7 @@ def get_book_data(book): 'has_faculty_resources': has_faculty_resources, 'has_student_resources': has_student_resources, 'assignable_book': book.assignable_book, + 'promote_snippet': book.promote_snippet.stream_block.get_api_representation(book.promote_snippet), 'promote_tags': [snippet.value.name for snippet in book.promote_snippet], } except Exception as e: diff --git a/pages/custom_blocks.py b/pages/custom_blocks.py index d00d81a5..61c439b4 100644 --- a/pages/custom_blocks.py +++ b/pages/custom_blocks.py @@ -326,13 +326,13 @@ def get_api_representation(self, value, context=None): 'title': value['title'], } -class BookListBlock(blocks.StreamBlock): +class BookListBlock(blocks.StructBlock): books = blocks.PageChooserBlock(page_type=['books.Book'], required=False) class Meta: icon = 'placeholder' - label = "Book List" + label = "Books" def get_api_representation(self, value, context=None): - # value is a StreamValue of blocks, each with .value as a Book page - return [book_data for book in value if (book_data := get_book_data(book.value))] + if value: + return get_book_data(value['books']) diff --git a/pages/migrations/0157_alter_rootpage_body.py b/pages/migrations/0157_alter_rootpage_body.py new file mode 100644 index 00000000..005f113c --- /dev/null +++ b/pages/migrations/0157_alter_rootpage_body.py @@ -0,0 +1,414 @@ +# Generated by Django 5.0.14 on 2025-05-21 14:46 + +import wagtail.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("pages", "0156_alter_rootpage_body"), + ] + + operations = [ + migrations.AlterField( + model_name="rootpage", + name="body", + field=wagtail.fields.StreamField( + [("hero", 55), ("section", 57), ("divider", 64), ("html", 18)], + block_lookup={ + 0: ("pages.custom_blocks.APIRichTextBlock", (), {}), + 1: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "Visible text of the link or button.", "required": True}, + ), + 2: ( + "wagtail.blocks.CharBlock", + (), + { + "help_text": "Accessible label for the link or button. if provided, must begin with the visible text.", + "required": False, + }, + ), + 3: ( + "wagtail.blocks.URLBlock", + (), + {"help_text": "External links are full urls that can go anywhere", "required": False}, + ), + 4: ("wagtail.blocks.PageChooserBlock", (), {"required": False}), + 5: ("wagtail.documents.blocks.DocumentChooserBlock", (), {"required": False}), + 6: ( + "wagtail.blocks.CharBlock", + (), + { + "help_text": "Anchor links reference the ID of an element on the page, and scroll the page there.", + "required": False, + }, + ), + 7: ( + "wagtail.blocks.StreamBlock", + [[("external", 3), ("internal", 4), ("document", 5), ("anchor", 6)]], + {"required": True}, + ), + 8: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [ + ("orange", "Orange"), + ("white", "White"), + ("blue_outline", "Blue Outline"), + ("deep_green_outline", "Deep Green Outline"), + ], + "help_text": "Specifies the button style. Default unspecified, meaning the first button in the block is orange and the second is white.", + }, + ), + 9: ( + "wagtail.blocks.StreamBlock", + [[("style", 8)]], + {"block_counts": {"style": {"max_num": 1}}, "required": False}, + ), + 10: ( + "wagtail.blocks.StructBlock", + [[("text", 1), ("aria_label", 2), ("target", 7), ("config", 9)]], + {"label": "Link", "required": False}, + ), + 11: ("wagtail.blocks.ListBlock", (10,), {"default": [], "label": "Call To Action", "max_num": 1}), + 12: ("wagtail.blocks.StructBlock", [[("text", 0), ("cta_block", 11)]], {}), + 13: ("wagtail.blocks.ListBlock", (12,), {}), + 14: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Sets the width of the individual cards. default 27.", "min_value": 0}, + ), + 15: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [("rounded", "Rounded"), ("square", "Square")], + "help_text": "The border style of the cards. default borderless.", + }, + ), + 16: ( + "wagtail.blocks.StreamBlock", + [[("card_size", 14), ("card_style", 15)]], + { + "block_counts": {"card_size": {"max_num": 1}, "card_style": {"max_num": 1}}, + "required": False, + }, + ), + 17: ("wagtail.blocks.StructBlock", [[("cards", 13), ("config", 16)]], {"label": "Cards Block"}), + 18: ("wagtail.blocks.RawHTMLBlock", (), {}), + 19: ( + "wagtail.blocks.StructBlock", + [[("text", 1), ("aria_label", 2), ("target", 7), ("config", 9)]], + {"label": "Button", "required": False}, + ), + 20: ("wagtail.blocks.ListBlock", (19,), {"default": [], "label": "Actions", "max_num": 2}), + 21: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": 'Sets the "analytics nav" field for links within this group.', "required": False}, + ), + 22: ( + "wagtail.blocks.StreamBlock", + [[("analytics_label", 21)]], + {"block_counts": {"analytics_label": {"max_num": 1}}, "required": False}, + ), + 23: ("wagtail.blocks.StructBlock", [[("actions", 20), ("config", 22)]], {}), + 24: ( + "wagtail.blocks.StructBlock", + [[("text", 1), ("aria_label", 2), ("target", 7)]], + {"label": "Link", "required": False}, + ), + 25: ("wagtail.blocks.ListBlock", (24,), {"default": [], "label": "Links"}), + 26: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [("white", "White"), ("blue", "Blue"), ("deep-green", "Deep Green")], + "help_text": "The color of the link buttons. Default white.", + }, + ), + 27: ( + "wagtail.blocks.StreamBlock", + [[("color", 26), ("analytics_label", 21)]], + { + "block_counts": {"analytics_label": {"max_num": 1}, "color": {"max_num": 1}}, + "required": False, + }, + ), + 28: ("wagtail.blocks.StructBlock", [[("links", 25), ("config", 27)]], {}), + 29: ("pages.custom_blocks.APIImageChooserBlock", (), {}), + 30: ("wagtail.blocks.RichTextBlock", (), {"help_text": "The quote content."}), + 31: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "The name of the person or entity to attribute the quote to."}, + ), + 32: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "Additional title or label about the quotee.", "requred": False}, + ), + 33: ( + "wagtail.blocks.StructBlock", + [[("image", 29), ("content", 30), ("name", 31), ("title", 32)]], + {}, + ), + 34: ( + "wagtail.blocks.RichTextBlock", + (), + {"help_text": "The visible text of the question (does not collapse).", "required": True}, + ), + 35: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "Not visible to user, must be unique in this FAQ.", "required": True}, + ), + 36: ( + "wagtail.blocks.RichTextBlock", + (), + { + "help_text": "The answer to the question, is hidden until the question is expanded.", + "required": True, + }, + ), + 37: ( + "wagtail.documents.blocks.DocumentChooserBlock", + (), + {"help_text": "Not sure this does anything.", "required": False}, + ), + 38: ( + "wagtail.blocks.StructBlock", + [[("question", 34), ("slug", 35), ("answer", 36), ("document", 37)]], + {}, + ), + 39: ("wagtail.blocks.StreamBlock", [[("faq", 38)]], {}), + 40: ("wagtail.blocks.PageChooserBlock", (), {"page_type": ["books.Book"], "required": False}), + 41: ("wagtail.blocks.StreamBlock", [[("books", 40)]], {}), + 42: ("wagtail.blocks.StructBlock", [[("books", 41)]], {"label": "Book List"}), + 43: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("cards_block", 17), + ("text", 0), + ("html", 18), + ("cta_block", 23), + ("links_group", 28), + ("quote", 33), + ("faq", 39), + ("book_list", 42), + ] + ], + {}, + ), + 44: ("pages.custom_blocks.APIImageChooserBlock", (), {"required": False}), + 45: ("wagtail.blocks.CharBlock", (), {"required": False}), + 46: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [ + ("left", "Left"), + ("right", "Right"), + ("top_left", "Top Left"), + ("top_right", "Top Right"), + ("bottom_left", "Bottom Left"), + ("bottom_right", "Bottom Right"), + ], + "help_text": "Controls if the image is on the left or right side of the content, and if it prefers to be at the top, center, or bottom of the available space.", + }, + ), + 47: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid id."}, + "help_text": "HTML id of this element. not visible to users, but is visible in urls and is used to link to a certain part of the page with an anchor link. eg: cool_section", + "regex": "[a-zA-Z0-9\\-_]", + }, + ), + 48: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid hex color."}, + "help_text": "Sets the background color of the section. value must be hex eg: #ff0000. Default grey.", + "regex": "#[a-zA-Z0-9]{6}", + }, + ), + 49: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Creates space above and below this section. default 0.", "min_value": 0}, + ), + 50: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Creates space above this section. default 0.", "min_value": 0}, + ), + 51: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Creates space below this section. default 0.", "min_value": 0}, + ), + 52: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [("center", "Center"), ("left", "Left"), ("right", "Right")], + "help_text": "Configures text alignment within the container. Default Left.", + }, + ), + 53: ( + "wagtail.blocks.CharBlock", + (), + { + "help_text": 'Sets the "analytics nav" field for links within this section.', + "required": False, + }, + ), + 54: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("image_alignment", 46), + ("id", 47), + ("background_color", 48), + ("padding", 49), + ("padding_top", 50), + ("padding_bottom", 51), + ("text_alignment", 52), + ("analytics_label", 53), + ] + ], + { + "block_counts": { + "analytics_label": {"max_num": 1}, + "background_color": {"max_num": 1}, + "id": {"max_num": 1}, + "image_alignment": {"max_num": 1}, + "padding": {"max_num": 1}, + "padding_bottom": {"max_num": 1}, + "padding_top": {"max_num": 1}, + "text_alignment": {"max_num": 1}, + }, + "required": False, + }, + ), + 55: ( + "wagtail.blocks.StructBlock", + [[("content", 43), ("image", 44), ("image_alt", 45), ("config", 54)]], + {}, + ), + 56: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("id", 47), + ("background_color", 48), + ("padding", 49), + ("padding_top", 50), + ("padding_bottom", 51), + ("text_alignment", 52), + ("analytics_label", 53), + ] + ], + { + "block_counts": { + "analytics_label": {"max_num": 1}, + "background_color": {"max_num": 1}, + "id": {"max_num": 1}, + "padding": {"max_num": 1}, + "padding_bottom": {"max_num": 1}, + "padding_top": {"max_num": 1}, + "text_alignment": {"max_num": 1}, + }, + "required": False, + }, + ), + 57: ("wagtail.blocks.StructBlock", [[("content", 43), ("config", 56)]], {}), + 58: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [ + ("center", "Center"), + ("content_left", "Left side of content."), + ("content_right", "Right side of content."), + ("body_left", "Left side of window."), + ("body_right", "Right side of window."), + ], + "help_text": 'Sets the horizontal alignment of the image. can be further customized with the "Offset..." configurations. Default is Left side of window.', + }, + ), + 59: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Specifies the width of the image. Percentages are relative to the container (body or content, depending on alignment option). Must be valid css measurement. eg: 30px, 50%, 10rem. Default is the size of the image.", + "regex": "^[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 60: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Specifies the height of the image. Percentages are relative to the container (body or content, depending on alignment option). Must be valid css measurement. eg: 30px, 50%, 10rem. Default is the size of the image.", + "regex": "^[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 61: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Moves the image up or down. Percentages are relative to the image size. Must be valid css measurement. eg: 30px, 50%, 10rem. Default is -50%, which moves the image up by half its width (centering it vertically on the divider).", + "regex": "^\\-?[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 62: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Moves the image left or right. Percentages are relative to the image size. Must be valid css measurement. eg: 30px, 50%, 10rem. Default is no offset, which means the image's outer edge will align with the container's edge for left and right alignment. or it'll be perfectly centered for centered alignment.", + "regex": "^\\-?[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 63: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("alignment", 58), + ("width", 59), + ("height", 60), + ("offset_vertical", 61), + ("offset_horizontal", 62), + ] + ], + { + "block_counts": { + "alignment": {"max_num": 1}, + "height": {"max_num": 1}, + "offset_horizontal": {"max_num": 1}, + "offset_vertical": {"max_num": 1}, + "width": {"max_num": 1}, + }, + "required": False, + }, + ), + 64: ("wagtail.blocks.StructBlock", [[("image", 29), ("config", 63)]], {}), + }, + ), + ), + ] diff --git a/pages/migrations/0158_alter_rootpage_body.py b/pages/migrations/0158_alter_rootpage_body.py new file mode 100644 index 00000000..7660e4f2 --- /dev/null +++ b/pages/migrations/0158_alter_rootpage_body.py @@ -0,0 +1,415 @@ +# Generated by Django 5.0.14 on 2025-05-23 16:12 + +import wagtail.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("pages", "0157_alter_rootpage_body"), + ] + + operations = [ + migrations.AlterField( + model_name="rootpage", + name="body", + field=wagtail.fields.StreamField( + [("hero", 56), ("section", 58), ("divider", 65), ("html", 18)], + block_lookup={ + 0: ("pages.custom_blocks.APIRichTextBlock", (), {}), + 1: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "Visible text of the link or button.", "required": True}, + ), + 2: ( + "wagtail.blocks.CharBlock", + (), + { + "help_text": "Accessible label for the link or button. if provided, must begin with the visible text.", + "required": False, + }, + ), + 3: ( + "wagtail.blocks.URLBlock", + (), + {"help_text": "External links are full urls that can go anywhere", "required": False}, + ), + 4: ("wagtail.blocks.PageChooserBlock", (), {"required": False}), + 5: ("wagtail.documents.blocks.DocumentChooserBlock", (), {"required": False}), + 6: ( + "wagtail.blocks.CharBlock", + (), + { + "help_text": "Anchor links reference the ID of an element on the page, and scroll the page there.", + "required": False, + }, + ), + 7: ( + "wagtail.blocks.StreamBlock", + [[("external", 3), ("internal", 4), ("document", 5), ("anchor", 6)]], + {"required": True}, + ), + 8: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [ + ("orange", "Orange"), + ("white", "White"), + ("blue_outline", "Blue Outline"), + ("deep_green_outline", "Deep Green Outline"), + ], + "help_text": "Specifies the button style. Default unspecified, meaning the first button in the block is orange and the second is white.", + }, + ), + 9: ( + "wagtail.blocks.StreamBlock", + [[("style", 8)]], + {"block_counts": {"style": {"max_num": 1}}, "required": False}, + ), + 10: ( + "wagtail.blocks.StructBlock", + [[("text", 1), ("aria_label", 2), ("target", 7), ("config", 9)]], + {"label": "Link", "required": False}, + ), + 11: ("wagtail.blocks.ListBlock", (10,), {"default": [], "label": "Call To Action", "max_num": 1}), + 12: ("wagtail.blocks.StructBlock", [[("text", 0), ("cta_block", 11)]], {}), + 13: ("wagtail.blocks.ListBlock", (12,), {}), + 14: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Sets the width of the individual cards. default 27.", "min_value": 0}, + ), + 15: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [("rounded", "Rounded"), ("square", "Square")], + "help_text": "The border style of the cards. default borderless.", + }, + ), + 16: ( + "wagtail.blocks.StreamBlock", + [[("card_size", 14), ("card_style", 15)]], + { + "block_counts": {"card_size": {"max_num": 1}, "card_style": {"max_num": 1}}, + "required": False, + }, + ), + 17: ("wagtail.blocks.StructBlock", [[("cards", 13), ("config", 16)]], {"label": "Cards Block"}), + 18: ("wagtail.blocks.RawHTMLBlock", (), {}), + 19: ( + "wagtail.blocks.StructBlock", + [[("text", 1), ("aria_label", 2), ("target", 7), ("config", 9)]], + {"label": "Button", "required": False}, + ), + 20: ("wagtail.blocks.ListBlock", (19,), {"default": [], "label": "Actions", "max_num": 2}), + 21: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": 'Sets the "analytics nav" field for links within this group.', "required": False}, + ), + 22: ( + "wagtail.blocks.StreamBlock", + [[("analytics_label", 21)]], + {"block_counts": {"analytics_label": {"max_num": 1}}, "required": False}, + ), + 23: ("wagtail.blocks.StructBlock", [[("actions", 20), ("config", 22)]], {}), + 24: ( + "wagtail.blocks.StructBlock", + [[("text", 1), ("aria_label", 2), ("target", 7)]], + {"label": "Link", "required": False}, + ), + 25: ("wagtail.blocks.ListBlock", (24,), {"default": [], "label": "Links"}), + 26: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [("white", "White"), ("blue", "Blue"), ("deep-green", "Deep Green")], + "help_text": "The color of the link buttons. Default white.", + }, + ), + 27: ( + "wagtail.blocks.StreamBlock", + [[("color", 26), ("analytics_label", 21)]], + { + "block_counts": {"analytics_label": {"max_num": 1}, "color": {"max_num": 1}}, + "required": False, + }, + ), + 28: ("wagtail.blocks.StructBlock", [[("links", 25), ("config", 27)]], {}), + 29: ("pages.custom_blocks.APIImageChooserBlock", (), {}), + 30: ("wagtail.blocks.RichTextBlock", (), {"help_text": "The quote content."}), + 31: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "The name of the person or entity to attribute the quote to."}, + ), + 32: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "Additional title or label about the quotee.", "requred": False}, + ), + 33: ( + "wagtail.blocks.StructBlock", + [[("image", 29), ("content", 30), ("name", 31), ("title", 32)]], + {}, + ), + 34: ( + "wagtail.blocks.RichTextBlock", + (), + {"help_text": "The visible text of the question (does not collapse).", "required": True}, + ), + 35: ( + "wagtail.blocks.CharBlock", + (), + {"help_text": "Not visible to user, must be unique in this FAQ.", "required": True}, + ), + 36: ( + "wagtail.blocks.RichTextBlock", + (), + { + "help_text": "The answer to the question, is hidden until the question is expanded.", + "required": True, + }, + ), + 37: ( + "wagtail.documents.blocks.DocumentChooserBlock", + (), + {"help_text": "Not sure this does anything.", "required": False}, + ), + 38: ( + "wagtail.blocks.StructBlock", + [[("question", 34), ("slug", 35), ("answer", 36), ("document", 37)]], + {}, + ), + 39: ("wagtail.blocks.StreamBlock", [[("faq", 38)]], {}), + 40: ("wagtail.blocks.PageChooserBlock", (), {"page_type": ["books.Book"], "required": False}), + 41: ("wagtail.blocks.StructBlock", [[("books", 40)]], {"required": False}), + 42: ("wagtail.blocks.ListBlock", (41,), {}), + 43: ("wagtail.blocks.StructBlock", [[("books", 42)]], {"label": "Book List"}), + 44: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("cards_block", 17), + ("text", 0), + ("html", 18), + ("cta_block", 23), + ("links_group", 28), + ("quote", 33), + ("faq", 39), + ("book_list", 43), + ] + ], + {}, + ), + 45: ("pages.custom_blocks.APIImageChooserBlock", (), {"required": False}), + 46: ("wagtail.blocks.CharBlock", (), {"required": False}), + 47: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [ + ("left", "Left"), + ("right", "Right"), + ("top_left", "Top Left"), + ("top_right", "Top Right"), + ("bottom_left", "Bottom Left"), + ("bottom_right", "Bottom Right"), + ], + "help_text": "Controls if the image is on the left or right side of the content, and if it prefers to be at the top, center, or bottom of the available space.", + }, + ), + 48: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid id."}, + "help_text": "HTML id of this element. not visible to users, but is visible in urls and is used to link to a certain part of the page with an anchor link. eg: cool_section", + "regex": "[a-zA-Z0-9\\-_]", + }, + ), + 49: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid hex color."}, + "help_text": "Sets the background color of the section. value must be hex eg: #ff0000. Default grey.", + "regex": "#[a-zA-Z0-9]{6}", + }, + ), + 50: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Creates space above and below this section. default 0.", "min_value": 0}, + ), + 51: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Creates space above this section. default 0.", "min_value": 0}, + ), + 52: ( + "wagtail.blocks.IntegerBlock", + (), + {"help_text": "Creates space below this section. default 0.", "min_value": 0}, + ), + 53: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [("center", "Center"), ("left", "Left"), ("right", "Right")], + "help_text": "Configures text alignment within the container. Default Left.", + }, + ), + 54: ( + "wagtail.blocks.CharBlock", + (), + { + "help_text": 'Sets the "analytics nav" field for links within this section.', + "required": False, + }, + ), + 55: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("image_alignment", 47), + ("id", 48), + ("background_color", 49), + ("padding", 50), + ("padding_top", 51), + ("padding_bottom", 52), + ("text_alignment", 53), + ("analytics_label", 54), + ] + ], + { + "block_counts": { + "analytics_label": {"max_num": 1}, + "background_color": {"max_num": 1}, + "id": {"max_num": 1}, + "image_alignment": {"max_num": 1}, + "padding": {"max_num": 1}, + "padding_bottom": {"max_num": 1}, + "padding_top": {"max_num": 1}, + "text_alignment": {"max_num": 1}, + }, + "required": False, + }, + ), + 56: ( + "wagtail.blocks.StructBlock", + [[("content", 44), ("image", 45), ("image_alt", 46), ("config", 55)]], + {}, + ), + 57: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("id", 48), + ("background_color", 49), + ("padding", 50), + ("padding_top", 51), + ("padding_bottom", 52), + ("text_alignment", 53), + ("analytics_label", 54), + ] + ], + { + "block_counts": { + "analytics_label": {"max_num": 1}, + "background_color": {"max_num": 1}, + "id": {"max_num": 1}, + "padding": {"max_num": 1}, + "padding_bottom": {"max_num": 1}, + "padding_top": {"max_num": 1}, + "text_alignment": {"max_num": 1}, + }, + "required": False, + }, + ), + 58: ("wagtail.blocks.StructBlock", [[("content", 44), ("config", 57)]], {}), + 59: ( + "wagtail.blocks.ChoiceBlock", + [], + { + "choices": [ + ("center", "Center"), + ("content_left", "Left side of content."), + ("content_right", "Right side of content."), + ("body_left", "Left side of window."), + ("body_right", "Right side of window."), + ], + "help_text": 'Sets the horizontal alignment of the image. can be further customized with the "Offset..." configurations. Default is Left side of window.', + }, + ), + 60: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Specifies the width of the image. Percentages are relative to the container (body or content, depending on alignment option). Must be valid css measurement. eg: 30px, 50%, 10rem. Default is the size of the image.", + "regex": "^[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 61: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Specifies the height of the image. Percentages are relative to the container (body or content, depending on alignment option). Must be valid css measurement. eg: 30px, 50%, 10rem. Default is the size of the image.", + "regex": "^[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 62: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Moves the image up or down. Percentages are relative to the image size. Must be valid css measurement. eg: 30px, 50%, 10rem. Default is -50%, which moves the image up by half its width (centering it vertically on the divider).", + "regex": "^\\-?[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 63: ( + "wagtail.blocks.RegexBlock", + (), + { + "error_mssages": {"invalid": "not a valid size."}, + "help_text": "Moves the image left or right. Percentages are relative to the image size. Must be valid css measurement. eg: 30px, 50%, 10rem. Default is no offset, which means the image's outer edge will align with the container's edge for left and right alignment. or it'll be perfectly centered for centered alignment.", + "regex": "^\\-?[0-9]+(px|%|rem)$", + "required": False, + }, + ), + 64: ( + "wagtail.blocks.StreamBlock", + [ + [ + ("alignment", 59), + ("width", 60), + ("height", 61), + ("offset_vertical", 62), + ("offset_horizontal", 63), + ] + ], + { + "block_counts": { + "alignment": {"max_num": 1}, + "height": {"max_num": 1}, + "offset_horizontal": {"max_num": 1}, + "offset_vertical": {"max_num": 1}, + "width": {"max_num": 1}, + }, + "required": False, + }, + ), + 65: ("wagtail.blocks.StructBlock", [[("image", 29), ("config", 64)]], {}), + }, + ), + ), + ] diff --git a/pages/models.py b/pages/models.py index 46895130..e923936d 100644 --- a/pages/models.py +++ b/pages/models.py @@ -86,7 +86,9 @@ ('faq', blocks.StreamBlock([ ('faq', FAQBlock()), ])), - ('book_list', BookListBlock()), + ('book_list', blocks.StructBlock([ + ('books', blocks.ListBlock(BookListBlock(required=False))), + ], label="Book List")), ] # we have one RootPage, which is the parent of all other pages