From 96ef159f7117cbbada2b4e208495d4b9201193a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Valenta?= <tomas@imaniti.org>
Date: Mon, 1 Jul 2024 13:53:22 +0200
Subject: [PATCH] wip - move blocks around

---
 ..._districthomepage_footer_links_and_more.py |   4 +-
 ...ter_districthomepage_footer_other_links.py |   4 +-
 ...ile_photo_districtpersonpage_main_image.py |   4 +-
 .../0166_alter_districthomepage_content.py    |   4 +-
 .../0220_alter_districthomepage_content.py    |   4 +-
 ...alter_districthomepage_content_and_more.py |   4 +-
 elections/migrations/0001_initial.py          |   4 +-
 ...er_electionshomepage_footer_other_links.py |   4 +-
 main/blocks.py                                |   4 +-
 ...age_remove_mainhomepage_footer_and_more.py |   3 +-
 ..._maincontactpage_contact_boxes_and_more.py |   3 +-
 ..._alter_mainarticlepage_content_and_more.py |   3 +-
 .../0020_alter_mainhomepage_content.py        |   5 +-
 ...ems_alter_mainhomepage_content_and_more.py |   5 +-
 ..._remove_mainhomepage_max_items_and_more.py |   5 +-
 ..._alter_mainarticlepage_content_and_more.py |   5 +-
 ...mainhomepage_twitter_usernames_and_more.py |   5 +-
 ..._mainhomepage_instagram_access_and_more.py |   5 +-
 ...e_mainarticlepage_article_type_and_more.py |   4 +-
 .../0064_alter_mainhomepage_content.py        |   5 +-
 ..._alter_mainarticlepage_content_and_more.py |   8 +-
 .../0066_alter_mainhomepage_content.py        |   5 +-
 .../0067_alter_mainhomepage_content.py        |   5 +-
 .../0068_alter_mainhomepage_content.py        |   5 +-
 .../0069_alter_mainhomepage_content.py        |   5 +-
 .../0073_alter_mainhomepage_content.py        |   6 +-
 .../0082_alter_mainhomepage_content.py        |   5 +-
 ...3_alter_mainhomepage_footer_other_links.py |   4 +-
 shared/blocks/__init__.py                     |   5 +-
 shared/blocks/base.py                         |  87 ----
 shared/blocks/children/__init__.py            |   4 +
 shared/blocks/children/candidates.py          |  53 +++
 .../blocks/{children.py => children/misc.py}  |  40 +-
 shared/blocks/children/mixins.py              |  68 +++
 shared/blocks/children/programs.py            | 130 ++++++
 shared/blocks/main.py                         | 421 ------------------
 shared/blocks/parents.py                      | 202 +++------
 ...webhomepage_footer_other_links_and_more.py |   4 +-
 38 files changed, 392 insertions(+), 749 deletions(-)
 create mode 100644 shared/blocks/children/__init__.py
 create mode 100644 shared/blocks/children/candidates.py
 rename shared/blocks/{children.py => children/misc.py} (64%)
 create mode 100644 shared/blocks/children/mixins.py
 create mode 100644 shared/blocks/children/programs.py
 delete mode 100644 shared/blocks/main.py

diff --git a/district/migrations/0150_remove_districthomepage_footer_links_and_more.py b/district/migrations/0150_remove_districthomepage_footer_links_and_more.py
index 2de7b299..e6a295fe 100644
--- a/district/migrations/0150_remove_districthomepage_footer_links_and_more.py
+++ b/district/migrations/0150_remove_districthomepage_footer_links_and_more.py
@@ -4,7 +4,7 @@ import wagtail.blocks
 import wagtail.fields
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -30,7 +30,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.LinkBlock,
+                                        shared.blocks.LinkBlock,
                                         label="Seznam odkazů s titulkem",
                                     ),
                                 ),
diff --git a/district/migrations/0151_alter_districthomepage_footer_other_links.py b/district/migrations/0151_alter_districthomepage_footer_other_links.py
index e04c2365..452816de 100644
--- a/district/migrations/0151_alter_districthomepage_footer_other_links.py
+++ b/district/migrations/0151_alter_districthomepage_footer_other_links.py
@@ -4,7 +4,7 @@ import wagtail.blocks
 import wagtail.fields
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -26,7 +26,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.LinkBlock,
+                                        shared.blocks.LinkBlock,
                                         label="Seznam odkazů",
                                     ),
                                 ),
diff --git a/district/migrations/0158_rename_profile_photo_districtpersonpage_main_image.py b/district/migrations/0158_rename_profile_photo_districtpersonpage_main_image.py
index 9ef93f80..b26058c4 100644
--- a/district/migrations/0158_rename_profile_photo_districtpersonpage_main_image.py
+++ b/district/migrations/0158_rename_profile_photo_districtpersonpage_main_image.py
@@ -5,7 +5,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -208,7 +208,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
diff --git a/district/migrations/0166_alter_districthomepage_content.py b/district/migrations/0166_alter_districthomepage_content.py
index 83985a25..ee1802af 100644
--- a/district/migrations/0166_alter_districthomepage_content.py
+++ b/district/migrations/0166_alter_districthomepage_content.py
@@ -5,7 +5,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -203,7 +203,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ],
diff --git a/district/migrations/0220_alter_districthomepage_content.py b/district/migrations/0220_alter_districthomepage_content.py
index 525c87e8..40a65a05 100644
--- a/district/migrations/0220_alter_districthomepage_content.py
+++ b/district/migrations/0220_alter_districthomepage_content.py
@@ -5,7 +5,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -204,7 +204,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ],
diff --git a/district/migrations/0221_alter_districthomepage_content_and_more.py b/district/migrations/0221_alter_districthomepage_content_and_more.py
index ad639bb7..7d067038 100644
--- a/district/migrations/0221_alter_districthomepage_content_and_more.py
+++ b/district/migrations/0221_alter_districthomepage_content_and_more.py
@@ -5,7 +5,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -204,7 +204,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ],
diff --git a/elections/migrations/0001_initial.py b/elections/migrations/0001_initial.py
index 61501b11..eb13a88b 100644
--- a/elections/migrations/0001_initial.py
+++ b/elections/migrations/0001_initial.py
@@ -11,7 +11,7 @@ import wagtail.images.blocks
 import wagtailmetadata.models
 from django.db import migrations, models
 
-import shared.blocks.main
+import shared.blocks
 import shared.models.legacy
 
 
@@ -276,7 +276,7 @@ class Migration(migrations.Migration):
                                         (
                                             "list",
                                             wagtail.blocks.ListBlock(
-                                                shared.blocks.main.LinkBlock,
+                                                shared.blocks.LinkBlock,
                                                 label="Seznam odkazů s titulkem",
                                             ),
                                         ),
diff --git a/elections/migrations/0028_alter_electionshomepage_footer_other_links.py b/elections/migrations/0028_alter_electionshomepage_footer_other_links.py
index b0f25d60..abb45785 100644
--- a/elections/migrations/0028_alter_electionshomepage_footer_other_links.py
+++ b/elections/migrations/0028_alter_electionshomepage_footer_other_links.py
@@ -4,7 +4,7 @@ import wagtail.blocks
 import wagtail.fields
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -26,7 +26,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.LinkBlock,
+                                        shared.blocks.LinkBlock,
                                         label="Seznam odkazů",
                                     ),
                                 ),
diff --git a/main/blocks.py b/main/blocks.py
index d295932a..ec85aa5c 100644
--- a/main/blocks.py
+++ b/main/blocks.py
@@ -11,7 +11,7 @@ from wagtail.blocks import (
 from wagtail.images.blocks import ImageChooserBlock
 
 from shared.blocks import (
-    BoxBlock,
+    PersonBoxBlock,
     CardLinkBlockMixin,
     CardLinkWithHeadlineBlockMixin,
     PersonContactBlockMixin,
@@ -44,7 +44,7 @@ class CardLinkBlock(CardLinkBlockMixin):
 
 class BoxesBlock(StructBlock):
     title = CharBlock(label="Nadpis")
-    list = ListBlock(BoxBlock, label="Boxíky")
+    list = ListBlock(PersonBoxBlock(), label="Boxíky")
     image = ImageChooserBlock(label="Obrázek pozadí", required=False)
 
     class Meta:
diff --git a/main/migrations/0002_mainarticlepage_remove_mainhomepage_footer_and_more.py b/main/migrations/0002_mainarticlepage_remove_mainhomepage_footer_and_more.py
index 0db8f34d..89464021 100644
--- a/main/migrations/0002_mainarticlepage_remove_mainhomepage_footer_and_more.py
+++ b/main/migrations/0002_mainarticlepage_remove_mainhomepage_footer_and_more.py
@@ -12,6 +12,7 @@ import wagtailmetadata.models
 from django.db import migrations, models
 
 import main.blocks
+import shared.blocks
 import shared.models
 
 
@@ -6099,7 +6100,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
diff --git a/main/migrations/0004_alter_maincontactpage_contact_boxes_and_more.py b/main/migrations/0004_alter_maincontactpage_contact_boxes_and_more.py
index 952bfc00..af93102a 100644
--- a/main/migrations/0004_alter_maincontactpage_contact_boxes_and_more.py
+++ b/main/migrations/0004_alter_maincontactpage_contact_boxes_and_more.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -101,7 +102,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
diff --git a/main/migrations/0011_alter_mainarticlepage_content_and_more.py b/main/migrations/0011_alter_mainarticlepage_content_and_more.py
index a2990580..f673f76e 100644
--- a/main/migrations/0011_alter_mainarticlepage_content_and_more.py
+++ b/main/migrations/0011_alter_mainarticlepage_content_and_more.py
@@ -6,6 +6,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
+import shared.blocks
 import main.blocks
 
 
@@ -145,7 +146,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
diff --git a/main/migrations/0020_alter_mainhomepage_content.py b/main/migrations/0020_alter_mainhomepage_content.py
index 783e2175..44b871c9 100644
--- a/main/migrations/0020_alter_mainhomepage_content.py
+++ b/main/migrations/0020_alter_mainhomepage_content.py
@@ -5,6 +5,7 @@ import wagtail.fields
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -57,7 +58,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -99,7 +100,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
diff --git a/main/migrations/0024_mainhomepage_max_items_alter_mainhomepage_content_and_more.py b/main/migrations/0024_mainhomepage_max_items_alter_mainhomepage_content_and_more.py
index 3fa96e0d..34033884 100644
--- a/main/migrations/0024_mainhomepage_max_items_alter_mainhomepage_content_and_more.py
+++ b/main/migrations/0024_mainhomepage_max_items_alter_mainhomepage_content_and_more.py
@@ -5,6 +5,7 @@ import wagtail.fields
 from django.db import migrations, models
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -64,7 +65,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -106,7 +107,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
diff --git a/main/migrations/0026_remove_mainhomepage_max_items_and_more.py b/main/migrations/0026_remove_mainhomepage_max_items_and_more.py
index ecbc3668..729265a5 100644
--- a/main/migrations/0026_remove_mainhomepage_max_items_and_more.py
+++ b/main/migrations/0026_remove_mainhomepage_max_items_and_more.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -68,7 +69,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -116,7 +117,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0042_alter_mainarticlepage_content_and_more.py b/main/migrations/0042_alter_mainarticlepage_content_and_more.py
index 7b5ed242..d179a13c 100644
--- a/main/migrations/0042_alter_mainarticlepage_content_and_more.py
+++ b/main/migrations/0042_alter_mainarticlepage_content_and_more.py
@@ -7,6 +7,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -357,7 +358,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -405,7 +406,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0051_remove_mainhomepage_twitter_usernames_and_more.py b/main/migrations/0051_remove_mainhomepage_twitter_usernames_and_more.py
index 6d9c0209..61cc172b 100644
--- a/main/migrations/0051_remove_mainhomepage_twitter_usernames_and_more.py
+++ b/main/migrations/0051_remove_mainhomepage_twitter_usernames_and_more.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -68,7 +69,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -116,7 +117,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0058_remove_mainhomepage_instagram_access_and_more.py b/main/migrations/0058_remove_mainhomepage_instagram_access_and_more.py
index 4af4213b..fc5c5371 100644
--- a/main/migrations/0058_remove_mainhomepage_instagram_access_and_more.py
+++ b/main/migrations/0058_remove_mainhomepage_instagram_access_and_more.py
@@ -5,6 +5,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
+import shared.blocks
 import main.blocks
 
 
@@ -72,7 +73,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -106,7 +107,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0063_remove_mainarticlepage_article_type_and_more.py b/main/migrations/0063_remove_mainarticlepage_article_type_and_more.py
index b66a71ec..bf786547 100644
--- a/main/migrations/0063_remove_mainarticlepage_article_type_and_more.py
+++ b/main/migrations/0063_remove_mainarticlepage_article_type_and_more.py
@@ -374,7 +374,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -402,7 +402,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0064_alter_mainhomepage_content.py b/main/migrations/0064_alter_mainhomepage_content.py
index fb232156..fa63f3fd 100644
--- a/main/migrations/0064_alter_mainhomepage_content.py
+++ b/main/migrations/0064_alter_mainhomepage_content.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -98,7 +99,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -126,7 +127,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0065_alter_mainarticlepage_content_and_more.py b/main/migrations/0065_alter_mainarticlepage_content_and_more.py
index c32b2191..49a05a4f 100644
--- a/main/migrations/0065_alter_mainarticlepage_content_and_more.py
+++ b/main/migrations/0065_alter_mainarticlepage_content_and_more.py
@@ -9,7 +9,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -231,7 +231,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -259,7 +259,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
@@ -290,7 +290,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.LinkBlock,
+                                        shared.blocks.LinkBlock,
                                         label="Seznam odkazů s titulkem",
                                     ),
                                 ),
diff --git a/main/migrations/0066_alter_mainhomepage_content.py b/main/migrations/0066_alter_mainhomepage_content.py
index 3f3f034c..00ea4128 100644
--- a/main/migrations/0066_alter_mainhomepage_content.py
+++ b/main/migrations/0066_alter_mainhomepage_content.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -106,7 +107,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -134,7 +135,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0067_alter_mainhomepage_content.py b/main/migrations/0067_alter_mainhomepage_content.py
index a6ae9762..9f1fbbfd 100644
--- a/main/migrations/0067_alter_mainhomepage_content.py
+++ b/main/migrations/0067_alter_mainhomepage_content.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -106,7 +107,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -134,7 +135,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0068_alter_mainhomepage_content.py b/main/migrations/0068_alter_mainhomepage_content.py
index 480603f2..35ceaf3c 100644
--- a/main/migrations/0068_alter_mainhomepage_content.py
+++ b/main/migrations/0068_alter_mainhomepage_content.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -120,7 +121,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -148,7 +149,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0069_alter_mainhomepage_content.py b/main/migrations/0069_alter_mainhomepage_content.py
index 163db4b7..84191b00 100644
--- a/main/migrations/0069_alter_mainhomepage_content.py
+++ b/main/migrations/0069_alter_mainhomepage_content.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -127,7 +128,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -155,7 +156,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0073_alter_mainhomepage_content.py b/main/migrations/0073_alter_mainhomepage_content.py
index e38ae81e..d018bf38 100644
--- a/main/migrations/0073_alter_mainhomepage_content.py
+++ b/main/migrations/0073_alter_mainhomepage_content.py
@@ -5,7 +5,7 @@ import wagtail.fields
 import wagtail.images.blocks
 from django.db import migrations
 
-import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -126,7 +126,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -154,7 +154,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0082_alter_mainhomepage_content.py b/main/migrations/0082_alter_mainhomepage_content.py
index e74c2bec..d148a696 100644
--- a/main/migrations/0082_alter_mainhomepage_content.py
+++ b/main/migrations/0082_alter_mainhomepage_content.py
@@ -6,6 +6,7 @@ import wagtail.images.blocks
 from django.db import migrations
 
 import main.blocks
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -128,7 +129,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                             ]
@@ -156,7 +157,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        main.blocks.BoxBlock, label="Boxíky"
+                                        shared.blocks.PersonBoxBlock, label="Boxíky"
                                     ),
                                 ),
                                 (
diff --git a/main/migrations/0083_alter_mainhomepage_footer_other_links.py b/main/migrations/0083_alter_mainhomepage_footer_other_links.py
index 5112a6db..012db5d6 100644
--- a/main/migrations/0083_alter_mainhomepage_footer_other_links.py
+++ b/main/migrations/0083_alter_mainhomepage_footer_other_links.py
@@ -4,7 +4,7 @@ import wagtail.blocks
 import wagtail.fields
 from django.db import migrations
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -26,7 +26,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.LinkBlock,
+                                        shared.blocks.LinkBlock,
                                         label="Seznam odkazů",
                                     ),
                                 ),
diff --git a/shared/blocks/__init__.py b/shared/blocks/__init__.py
index f4c0ba1a..d1bcf291 100644
--- a/shared/blocks/__init__.py
+++ b/shared/blocks/__init__.py
@@ -1,2 +1,3 @@
-from .base import *  # noqa
-from .main import *  # noqa
+from .parents import *  # noqa
+from .children import *  # noqa
+from .base import *  # noqa
\ No newline at end of file
diff --git a/shared/blocks/base.py b/shared/blocks/base.py
index 570ac839..7728ad4a 100644
--- a/shared/blocks/base.py
+++ b/shared/blocks/base.py
@@ -1,90 +1,3 @@
-import datetime
-import json
-import logging
-import re
-import typing
-import urllib
-
-import requests
-from django.core.cache import cache
-from django.core.exceptions import ValidationError
-from django.core.files.images import ImageFile
-from django.forms.utils import ErrorList
-from wagtail import blocks
-from wagtail.blocks.struct_block import StructBlockValidationError
-from wagtail.contrib.table_block.blocks import TableBlock
-from wagtail.images.blocks import ImageChooserBlock
-from wagtail.images.models import Image
-from wagtail.models import Collection
-
-from maps_utils.blocks import MapFeatureCollectionBlock, MapPointBlock
-from shared.const import (
-    ALIGN_CHOICES,
-    ALIGN_CSS,
-    BLACK_ON_WHITE,
-    COLOR_CHOICES,
-    COLOR_CSS,
-    LEFT,
-    RICH_TEXT_DEFAULT_FEATURES,
-)
-
-logger = logging.getLogger(__name__)
-
-
-class ColorBlock(blocks.StructBlock):
-    """
-    Intended as parent class for blocks with color option.
-    """
-
-    color = blocks.ChoiceBlock(COLOR_CHOICES, label="barva", default=BLACK_ON_WHITE)
-
-    def get_context(self, value, parent_context=None):
-        context = super().get_context(value, parent_context=parent_context)
-        if "css_class" not in context:
-            context["css_class"] = []
-        context["css_class"] += COLOR_CSS[value["color"]]
-        return context
-
-
-class AlignBlock(blocks.StructBlock):
-    """
-    Intended as parent class for blocks with align option.
-    """
-
-    align = blocks.ChoiceBlock(ALIGN_CHOICES, label="zarovnání", default=LEFT)
-
-    def get_context(self, value, parent_context=None):
-        context = super().get_context(value, parent_context=parent_context)
-        if "css_class" not in context:
-            context["css_class"] = []
-        context["css_class"] += ALIGN_CSS[value["align"]]
-        return context
-
-
-class GalleryBlock(blocks.StructBlock):
-    gallery_items = blocks.ListBlock(
-        ImageChooserBlock(label="obrázek", required=True),
-        label="Galerie",
-        icon="image",
-        group="ostatní",
-    )
-
-    class Meta:
-        label = "Galerie"
-        icon = "image"
-        template = "styleguide2/includes/molecules/gallery/gallery.html"
-
-
-class FigureBlock(blocks.StructBlock):
-    img = ImageChooserBlock(label="Obrázek", required=True)
-    caption = blocks.TextBlock(label="Popisek", required=False)
-
-    class Meta:
-        label = "Obrázek"
-        icon = "image"
-        template = "styleguide2/includes/atoms/figure/figure.html"
-
-
 class MenuItemBlock(blocks.StructBlock):
     title = blocks.CharBlock(
         label="Titulek",
diff --git a/shared/blocks/children/__init__.py b/shared/blocks/children/__init__.py
new file mode 100644
index 00000000..829cb54a
--- /dev/null
+++ b/shared/blocks/children/__init__.py
@@ -0,0 +1,4 @@
+from .candidates import *  # noqa
+from .misc import *  # noqa
+from .programs import *  # noqa
+from .mixins import *  # noqa
\ No newline at end of file
diff --git a/shared/blocks/children/candidates.py b/shared/blocks/children/candidates.py
new file mode 100644
index 00000000..4329633d
--- /dev/null
+++ b/shared/blocks/children/candidates.py
@@ -0,0 +1,53 @@
+from django.utils.text import slugify
+from wagtail.blocks import (
+    CharBlock,
+    IntegerBlock,
+    ListBlock,
+    PageChooserBlock,
+    RichTextBlock,
+    StructBlock,
+    TextBlock,
+    URLBlock,
+)
+from wagtail.documents.blocks import DocumentChooserBlock
+from wagtail.images.blocks import ImageChooserBlock
+
+
+class CandidateBlock(StructBlock):
+    # NOTE: Page type should be restricted in mixed-in classes
+    page = PageChooserBlock(label="Stránka")
+
+    image = ImageChooserBlock(
+        label="Obrázek",
+        help_text="Pokud není vybrán, použije se obrázek ze stránky kandidáta",
+        required=False,
+    )
+
+    description = TextBlock(label="Popis", required=False)
+
+    class Meta:
+        template = (
+            "styleguide2/includes/molecules/candidates/candidate_primary_box.html"
+        )
+        icon = "form"
+        label = "Kandidát"
+
+
+class SecondaryCandidateBlock(StructBlock):
+    number = CharBlock(label="Číslo")
+
+    # NOTE: Page type should be restricted in mixed-in classes
+    page = PageChooserBlock(label="Stránka")
+
+    image = ImageChooserBlock(
+        label="Obrázek",
+        help_text="Pokud není vybrán, použije se obrázek ze stránky kandidáta",
+        required=False,
+    )
+
+    class Meta:
+        template = (
+            "styleguide2/includes/molecules/candidates/candidate_secondary_box.html"
+        )
+        icon = "form"
+        label = "Kandidát"
\ No newline at end of file
diff --git a/shared/blocks/children.py b/shared/blocks/children/misc.py
similarity index 64%
rename from shared/blocks/children.py
rename to shared/blocks/children/misc.py
index b950742f..905e8fca 100644
--- a/shared/blocks/children.py
+++ b/shared/blocks/children/misc.py
@@ -11,15 +11,7 @@ from wagtail.blocks import (
 )
 from wagtail.documents.blocks import DocumentChooserBlock
 from wagtail.images.blocks import ImageChooserBlock
-
-
-class CTAMixin(StructBlock):
-    button_link = URLBlock(label="Odkaz tlačítka")
-    button_text = CharBlock(label="Text tlačítka")
-
-    class Meta:
-        icon = "doc-empty"
-        label = "Tlačítko s odkazem"
+from .mixins import CTAMixin
 
 
 class LinkBlock(StructBlock):
@@ -54,36 +46,6 @@ class PersonContactBlockMixin(StructBlock):
         label = "Osoba s volitelnou pozicí"
 
 
-class ProgramBlockPopout(StructBlock):
-    title = CharBlock(label="Titulek vyskakovacího bloku")
-    content = RichTextBlock(
-        label="Obsah",
-        features=PROGRAM_RICH_TEXT_FEATURES,
-    )
-
-    # TODO: Change in mixed-in blocks
-    guarantor = PageChooserBlock(
-        label="Garant", page_type=["district.DistrictPersonPage"], required=False
-    )
-
-    class Meta:
-        icon = "date"
-        label = "Blok programu"
-
-
-class ProgramPopoutCategory(StructBlock):
-    name = CharBlock(label="Název")
-    icon = ImageChooserBlock(label="Ikona", required=False)
-
-    description = RichTextBlock(label="Popis", required=False)
-
-    point_list = ListBlock(ProgramBlockPopout(), label="Jednotlivé bloky programu")
-
-    class Meta:
-        icon = "date"
-        label = "Kategorie programu"
-
-
 class FlipCardBlock(StructBlock):
     bg_color = CharBlock(label="Barva pozadí", default="FEC900")
 
diff --git a/shared/blocks/children/mixins.py b/shared/blocks/children/mixins.py
new file mode 100644
index 00000000..03fde805
--- /dev/null
+++ b/shared/blocks/children/mixins.py
@@ -0,0 +1,68 @@
+import datetime
+import json
+import logging
+import re
+import typing
+import urllib
+
+import requests
+from django.core.cache import cache
+from django.core.exceptions import ValidationError
+from django.core.files.images import ImageFile
+from django.forms.utils import ErrorList
+from wagtail import blocks
+from wagtail.blocks.struct_block import StructBlockValidationError
+from wagtail.contrib.table_block.blocks import TableBlock
+from wagtail.images.blocks import ImageChooserBlock
+from wagtail.images.models import Image
+from wagtail.models import Collection
+
+from maps_utils.blocks import MapFeatureCollectionBlock, MapPointBlock
+from shared.const import (
+    ALIGN_CHOICES,
+    ALIGN_CSS,
+    BLACK_ON_WHITE,
+    COLOR_CHOICES,
+    COLOR_CSS,
+    LEFT,
+    RICH_TEXT_DEFAULT_FEATURES,
+)
+
+
+class ColorBlock(blocks.StructBlock):
+    """
+    Intended as parent class for blocks with color option.
+    """
+
+    color = blocks.ChoiceBlock(COLOR_CHOICES, label="barva", default=BLACK_ON_WHITE)
+
+    def get_context(self, value, parent_context=None):
+        context = super().get_context(value, parent_context=parent_context)
+        if "css_class" not in context:
+            context["css_class"] = []
+        context["css_class"] += COLOR_CSS[value["color"]]
+        return context
+
+
+class AlignBlock(blocks.StructBlock):
+    """
+    Intended as parent class for blocks with align option.
+    """
+
+    align = blocks.ChoiceBlock(ALIGN_CHOICES, label="zarovnání", default=LEFT)
+
+    def get_context(self, value, parent_context=None):
+        context = super().get_context(value, parent_context=parent_context)
+        if "css_class" not in context:
+            context["css_class"] = []
+        context["css_class"] += ALIGN_CSS[value["align"]]
+        return context
+
+
+class CTAMixin(blocks.StructBlock):
+    button_link = blocks.URLBlock(label="Odkaz tlačítka")
+    button_text = blocks.CharBlock(label="Text tlačítka")
+
+    class Meta:
+        icon = "doc-empty"
+        label = "Tlačítko s odkazem"
\ No newline at end of file
diff --git a/shared/blocks/children/programs.py b/shared/blocks/children/programs.py
new file mode 100644
index 00000000..a86e8a7d
--- /dev/null
+++ b/shared/blocks/children/programs.py
@@ -0,0 +1,130 @@
+from django.utils.text import slugify
+from wagtail.blocks import (
+    CharBlock,
+    IntegerBlock,
+    ListBlock,
+    PageChooserBlock,
+    RichTextBlock,
+    StructBlock,
+    TextBlock,
+    URLBlock,
+)
+from wagtail.documents.blocks import DocumentChooserBlock
+from wagtail.images.blocks import ImageChooserBlock
+
+
+PROGRAM_RICH_TEXT_FEATURES = [
+    "h3",
+    "h4",
+    "h5",
+    "bold",
+    "italic",
+    "ol",
+    "ul",
+    "hr",
+    "link",
+    "document-link",
+    "image",
+    "superscript",
+    "subscript",
+    "strikethrough",
+    "blockquote",
+    "embed",
+]
+
+
+class CTAMixin(StructBlock):
+    button_link = URLBlock(label="Odkaz tlačítka")
+    button_text = CharBlock(label="Text tlačítka")
+
+    class Meta:
+        icon = "doc-empty"
+        label = "Tlačítko s odkazem"
+
+
+class ProgramBlockPopout(StructBlock):
+    title = CharBlock(label="Titulek vyskakovacího bloku")
+    content = RichTextBlock(
+        label="Obsah",
+        features=PROGRAM_RICH_TEXT_FEATURES,
+    )
+
+    # TODO: Change in mixed-in blocks
+    guarantor = PageChooserBlock(
+        label="Garant", page_type=["district.DistrictPersonPage"], required=False
+    )
+
+    class Meta:
+        icon = "date"
+        label = "Blok programu"
+
+
+class ProgramPopoutCategory(StructBlock):
+    name = CharBlock(label="Název")
+    icon = ImageChooserBlock(label="Ikona", required=False)
+
+    description = RichTextBlock(label="Popis", required=False)
+
+    point_list = ListBlock(ProgramBlockPopout(), label="Jednotlivé bloky programu")
+
+    class Meta:
+        icon = "date"
+        label = "Kategorie programu"
+
+
+class ProgramGroupBlockMixin(StructBlock):
+    title = CharBlock(
+        label="Název programu",
+        help_text="Např. 'Krajské volby 2024', 'Evropské volby 2024', ...",
+    )
+    # point_list = ListBlock(ProgramBlock(), label="Jednotlivé články programu")
+
+    class Meta:
+        icon = "date"
+        template = "styleguide2/includes/molecules/program/program_block.html"
+        # label = "Skupina programů"
+
+    def get_prep_value(self, value):
+        value = super().get_prep_value(value)
+        value["slug"] = slugify(value["title"])
+        return value
+
+
+class ProgramPointBlock(StructBlock):
+    url = URLBlock(
+        label="Odkaz pokrývající celou tuto část",
+        required=False,
+    )
+    icon = ImageChooserBlock(
+        label="Ikona",
+        required=False,
+    )
+    title = CharBlock(label="Titulek článku programu")
+    text = RichTextBlock(
+        label="Obsah",
+        features=PROGRAM_RICH_TEXT_FEATURES,
+    )
+
+    class Meta:
+        icon = "date"
+        label = "Článek programu"
+
+
+class CarouselProgramCategoryItemBlock(StructBlock):
+    content = TextBlock(label="Obsah")
+
+    class Meta:
+        icon = "form"
+        label = "Bod"
+
+
+class CarouselProgramCategoryBlock(StructBlock):
+    number = IntegerBlock(label="Číslo")
+
+    name = CharBlock(label="Název")
+
+    points = ListBlock(CarouselProgramCategoryItemBlock(), label="Body")
+
+    class Meta:
+        icon = "form"
+        label = "Kategorie"
\ No newline at end of file
diff --git a/shared/blocks/main.py b/shared/blocks/main.py
deleted file mode 100644
index 24a4338f..00000000
--- a/shared/blocks/main.py
+++ /dev/null
@@ -1,421 +0,0 @@
-from django.utils.text import slugify
-from wagtail.blocks import (
-    CharBlock,
-    IntegerBlock,
-    ListBlock,
-    PageChooserBlock,
-    RichTextBlock,
-    StructBlock,
-    TextBlock,
-    URLBlock,
-)
-from wagtail.documents.blocks import DocumentChooserBlock
-from wagtail.images.blocks import ImageChooserBlock
-
-# Mixins (or used as such)
-
-
-PROGRAM_RICH_TEXT_FEATURES = [
-    "h3",
-    "h4",
-    "h5",
-    "bold",
-    "italic",
-    "ol",
-    "ul",
-    "hr",
-    "link",
-    "document-link",
-    "image",
-    "superscript",
-    "subscript",
-    "strikethrough",
-    "blockquote",
-    "embed",
-]
-
-
-class CTAMixin(StructBlock):
-    button_link = URLBlock(label="Odkaz tlačítka")
-    button_text = CharBlock(label="Text tlačítka")
-
-    class Meta:
-        icon = "doc-empty"
-        label = "Tlačítko s odkazem"
-
-
-class LinkBlock(StructBlock):
-    text = CharBlock(label="Název")
-    link = URLBlock(label="Odkaz")
-
-    class Meta:
-        icon = "link"
-        label = "Odkaz"
-
-
-# Navbar
-
-
-class NavbarMenuItemBlock(CTAMixin):
-    class Meta:
-        label = "Tlačítko"
-        template = "styleguide2/includes/molecules/navbar/additional_button.html"
-
-
-class SocialLinkBlock(LinkBlock):
-    icon = CharBlock(
-        label="Ikona",
-        help_text="Seznam ikon - https://styleguide.pirati.cz/latest/?p=viewall-atoms-icons <br/>"
-        "Název ikony zadejte bez tečky na začátku",
-    )  # TODO CSS class name or somthing better?
-
-    class Meta:
-        icon = "link"
-        label = "Odkaz"
-
-
-# Articles
-
-
-class NewsBlock(StructBlock):
-    title = CharBlock(
-        label="Titulek",
-        help_text="Nejnovější články se načtou automaticky",
-    )
-    description = TextBlock(label="Popis", required=False)
-
-    class Meta:
-        icon = "doc-full-inverse"
-        label = "Novinky"
-
-
-class ArticleQuoteBlock(StructBlock):
-    quote = CharBlock(label="Citace")
-    autor_name = CharBlock(label="Jméno autora")
-
-    class Meta:
-        icon = "user"
-        label = "Blok citace"
-        template = "styleguide2/includes/legacy/article_quote_block.html"
-
-
-class ArticleDownloadBlock(StructBlock):
-    file = DocumentChooserBlock(label="Stáhnutelný soubor")
-
-    class Meta:
-        icon = "user"
-        label = "Blok stáhnutelného dokumentu"
-        template = "styleguide2/includes/molecules/blocks/download_block.html"
-
-
-# People
-
-
-class TwoTextColumnBlock(StructBlock):
-    text_column_1 = RichTextBlock(label="První sloupec textu")
-    text_column_2 = RichTextBlock(label="Druhý sloupec textu")
-
-    class Meta:
-        icon = "doc-full"
-        label = "Text ve dvou sloupcích"
-
-
-class PersonContactBoxBlock(StructBlock):
-    title = CharBlock(label="Titulek")
-    image = ImageChooserBlock(label="Ikona")
-    subtitle = CharBlock(label="Podtitulek")
-
-    class Meta:
-        icon = "mail"
-        label = "Kontakty"
-
-
-class PersonContactBlockMixin(StructBlock):
-    position = CharBlock(label="Název pozice", required=False)
-
-    @property
-    def person(self):
-        # NOTE: Needs to be implemented
-
-        raise NotImplementedError
-
-    # email, phone?
-
-    class Meta:
-        abstract = True
-        icon = "user"
-        label = "Osoba s volitelnou pozicí"
-
-
-# Footer
-
-
-class OtherLinksBlock(StructBlock):
-    title = CharBlock(label="Titulek")
-    list = ListBlock(LinkBlock, label="Seznam odkazů")
-
-    class Meta:
-        icon = "link"
-        label = "Odkazy"
-        template = "main/blocks/article_quote_block.html"
-
-
-class ProgramBlockPopout(StructBlock):
-    title = CharBlock(label="Titulek vyskakovacího bloku")
-    content = RichTextBlock(
-        label="Obsah",
-        features=PROGRAM_RICH_TEXT_FEATURES,
-    )
-
-    # TODO: Change in mixed-in blocks
-    guarantor = PageChooserBlock(
-        label="Garant", page_type=["district.DistrictPersonPage"], required=False
-    )
-
-    class Meta:
-        icon = "date"
-        label = "Blok programu"
-
-
-class ProgramPopoutCategory(StructBlock):
-    name = CharBlock(label="Název")
-    icon = ImageChooserBlock(label="Ikona", required=False)
-
-    description = RichTextBlock(label="Popis", required=False)
-
-    point_list = ListBlock(ProgramBlockPopout(), label="Jednotlivé bloky programu")
-
-    class Meta:
-        icon = "date"
-        label = "Kategorie programu"
-
-
-class ProgramGroupBlockPopout(StructBlock):
-    categories = ListBlock(ProgramPopoutCategory(), label="Kategorie programu")
-
-    class Meta:
-        icon = "date"
-        label = "Vyskakovací program"
-
-
-class FlipCardBlock(StructBlock):
-    bg_color = CharBlock(label="Barva pozadí", default="FEC900")
-
-    image = ImageChooserBlock(label="Obrázek", required=False)
-
-    title = TextBlock(label="Nadpis", help_text="Řádkování je manuální.")
-
-    content = RichTextBlock(label="Obsah")
-
-    button_text = CharBlock(
-        label="Nadpis tlačítka",
-        help_text="Pokud není vyplněn, tlačítko se neukáže.",
-        required=False,
-    )
-    button_url = CharBlock(label="Odkaz tlačítka", required=False)
-
-    class Meta:
-        icon = "view"
-        label = "Obracecí karta"
-        template = "styleguide2/includes/molecules/boxes/flip_card_box.html"
-
-
-class FlipCardsBlock(StructBlock):
-    cards = ListBlock(
-        FlipCardBlock(label="Karta"),
-        label="Karty",
-    )
-
-    class Meta:
-        icon = "group"
-        label = "Seznam obracecích karet"
-        template = "styleguide2/includes/organisms/cards/flip_card_list.html"
-
-
-class BoxBlock(CTAMixin, StructBlock):
-    title = CharBlock(label="Nadpis")
-    image = ImageChooserBlock(label="Logo/obrázek")
-
-    class Meta:
-        icon = "form"
-        label = "Box"
-
-
-class PeopleOverviewBlock(StructBlock):
-    title_line_1 = CharBlock(label="První řádek titulku")
-    title_line_2 = CharBlock(label="Druhý řádek titulku")
-
-    description = TextBlock(label="Popis")
-
-    list = ListBlock(BoxBlock, label="Boxíky")
-
-    class Meta:
-        template = (
-            "styleguide2/includes/organisms/main_section/representatives_section.html"
-        )
-        icon = "group"
-        label = "Skupina osob"
-
-
-# Program
-
-
-class ProgramGroupBlockMixin(StructBlock):
-    title = CharBlock(
-        label="Název programu",
-        help_text="Např. 'Krajské volby 2024', 'Evropské volby 2024', ...",
-    )
-    # point_list = ListBlock(ProgramBlock(), label="Jednotlivé články programu")
-
-    class Meta:
-        icon = "date"
-        template = "styleguide2/includes/molecules/program/program_block.html"
-        # label = "Skupina programů"
-
-    def get_prep_value(self, value):
-        value = super().get_prep_value(value)
-        value["slug"] = slugify(value["title"])
-        return value
-
-
-class ProgramBlock(StructBlock):
-    url = URLBlock(
-        label="Odkaz pokrývající celou tuto část",
-        required=False,
-    )
-    icon = ImageChooserBlock(
-        label="Ikona",
-        required=False,
-    )
-    title = CharBlock(label="Titulek článku programu")
-    text = RichTextBlock(
-        label="Obsah",
-        features=PROGRAM_RICH_TEXT_FEATURES,
-    )
-
-    class Meta:
-        icon = "date"
-        label = "Článek programu"
-
-
-class ProgramGroupBlock(ProgramGroupBlockMixin):
-    point_list = ListBlock(ProgramBlock(), label="Jednotlivé články programu")
-
-    class Meta:
-        icon = "date"
-        label = "Běžný program"
-
-
-# Candidates
-
-
-class CandidateBlock(StructBlock):
-    # NOTE: Page type should be restricted in mixed-in classes
-    page = PageChooserBlock(label="Stránka")
-
-    image = ImageChooserBlock(
-        label="Obrázek",
-        help_text="Pokud není vybrán, použije se obrázek ze stránky kandidáta",
-        required=False,
-    )
-
-    description = TextBlock(label="Popis", required=False)
-
-    class Meta:
-        template = (
-            "styleguide2/includes/molecules/candidates/candidate_primary_box.html"
-        )
-        icon = "form"
-        label = "Kandidát"
-
-
-class SecondaryCandidateBlock(StructBlock):
-    number = CharBlock(label="Číslo")
-
-    # NOTE: Page type should be restricted in mixed-in classes
-    page = PageChooserBlock(label="Stránka")
-
-    image = ImageChooserBlock(
-        label="Obrázek",
-        help_text="Pokud není vybrán, použije se obrázek ze stránky kandidáta",
-        required=False,
-    )
-
-    class Meta:
-        template = (
-            "styleguide2/includes/molecules/candidates/candidate_secondary_box.html"
-        )
-        icon = "form"
-        label = "Kandidát"
-
-
-class CandidateListBlock(StructBlock):
-    # NOTE: should be changed in mixed-in blocks.
-    candidates = ListBlock(
-        CandidateBlock(),
-        label="Kandidáti",
-    )
-
-    class Meta:
-        template = (
-            "styleguide2/includes/organisms/candidates/candidate_primary_list.html"
-        )
-        icon = "form"
-        label = "Seznam kandidátů"
-
-
-class CandidateSecondaryListBlock(StructBlock):
-    heading = CharBlock(label="Nadpis zbytku kandidátky", default="Ostatní kandidátky")
-
-    # NOTE: should be changed in mixed-in blocks.
-    candidates = ListBlock(
-        SecondaryCandidateBlock(),
-        label="Zbylí kandidáti na listině",
-    )
-
-    class Meta:
-        template = (
-            "styleguide2/includes/organisms/candidates/candidate_secondary_list.html"
-        )
-        icon = "form"
-        label = "Sekundární seznam kandidátů"
-
-
-class CarouselProgramCategoryItemBlock(StructBlock):
-    content = TextBlock(label="Obsah")
-
-    class Meta:
-        icon = "form"
-        label = "Bod"
-
-
-class CarouselProgramCategoryBlock(StructBlock):
-    number = IntegerBlock(label="Číslo")
-
-    name = CharBlock(label="Název")
-
-    points = ListBlock(CarouselProgramCategoryItemBlock(), label="Body")
-
-    class Meta:
-        icon = "form"
-        label = "Kategorie"
-
-
-class CarouselProgramBlock(StructBlock):
-    label = CharBlock(label="Nadpis", help_text="Např. 'Program'", default="Program")
-
-    categories = ListBlock(CarouselProgramCategoryBlock(), label="Kategorie")
-
-    long_version_url = URLBlock(
-        label="Odkaz na celou verzi programu",
-        help_text="Pro zobrazení odkazu na celou verzi programu musí být obě následující pole vyplněná.",
-        required=False,
-    )
-    long_version_text = CharBlock(
-        label="Nadpis odkazu na celou verzi programu", required=False
-    )
-
-    class Meta:
-        icon = "form"
-        label = "Priority programu, carousel"
-        template = "styleguide2/includes/molecules/program/card_program.html"
diff --git a/shared/blocks/parents.py b/shared/blocks/parents.py
index 51e86b00..ce57a145 100644
--- a/shared/blocks/parents.py
+++ b/shared/blocks/parents.py
@@ -11,32 +11,42 @@ from wagtail.blocks import (
 )
 from wagtail.documents.blocks import DocumentChooserBlock
 from wagtail.images.blocks import ImageChooserBlock
-from .children import CTAMixin, LinkBlock, NavbarMenuItemBlock, PersonContactBlockMixin, ProgramBlockPopout, ProgramPopoutCategory, FlipCardBlock, PersonBoxBlock
-
-# Mixins (or used as such)
-
-
-PROGRAM_RICH_TEXT_FEATURES = [
-    "h3",
-    "h4",
-    "h5",
-    "bold",
-    "italic",
-    "ol",
-    "ul",
-    "hr",
-    "link",
-    "document-link",
-    "image",
-    "superscript",
-    "subscript",
-    "strikethrough",
-    "blockquote",
-    "embed",
-]
-
+import datetime
+import json
+import logging
+import re
+import typing
+import urllib
+
+import requests
+from django.core.cache import cache
+from django.core.exceptions import ValidationError
+from django.core.files.images import ImageFile
+from django.forms.utils import ErrorList
+from wagtail import blocks
+from wagtail.blocks.struct_block import StructBlockValidationError
+from wagtail.contrib.table_block.blocks import TableBlock
+from wagtail.images.blocks import ImageChooserBlock
+from wagtail.images.models import Image
+from wagtail.models import Collection
+
+from maps_utils.blocks import MapFeatureCollectionBlock, MapPointBlock
+from shared.const import (
+    ALIGN_CHOICES,
+    ALIGN_CSS,
+    BLACK_ON_WHITE,
+    COLOR_CHOICES,
+    COLOR_CSS,
+    LEFT,
+    RICH_TEXT_DEFAULT_FEATURES,
+)
+from .children import (
+    CTAMixin, LinkBlock, NavbarMenuItemBlock, PersonContactBlockMixin, ProgramBlockPopout, ProgramPopoutCategory, FlipCardBlock, PersonBoxBlock, ProgramGroupBlockMixin, ProgramPointBlock,
+    CandidateBlock, SecondaryCandidateBlock, CarouselProgramCategoryItemBlock, CarouselProgramCategoryBlock,
+    ColorBlock, AlignBlock
+)
 
-# Navbar
+logger = logging.getLogger(__name__)
 
 
 class SocialLinkBlock(LinkBlock):
@@ -51,9 +61,6 @@ class SocialLinkBlock(LinkBlock):
         label = "Odkaz"
 
 
-# Articles
-
-
 class NewsBlock(StructBlock):
     title = CharBlock(
         label="Titulek",
@@ -85,9 +92,6 @@ class ArticleDownloadBlock(StructBlock):
         template = "styleguide2/includes/molecules/blocks/download_block.html"
 
 
-# People
-
-
 # TODO: Merge
 class TwoTextColumnBlock(StructBlock):
     text_column_1 = RichTextBlock(label="První sloupec textu")
@@ -108,9 +112,6 @@ class PersonContactBoxBlock(StructBlock):
         label = "Kontakty"
 
 
-# Footer
-
-
 class OtherLinksBlock(StructBlock):
     title = CharBlock(label="Titulek")
     list = ListBlock(LinkBlock, label="Seznam odkazů")
@@ -120,9 +121,6 @@ class OtherLinksBlock(StructBlock):
         label = "Odkazy"
 
 
-# Program
-
-
 class FlipCardsBlock(StructBlock):
     cards = ListBlock(
         FlipCardBlock(label="Karta"),
@@ -151,9 +149,6 @@ class PeopleOverviewBlock(StructBlock):
         label = "Skupina osob"
 
 
-# Program
-
-
 class ProgramGroupBlockPopout(StructBlock):
     categories = ListBlock(ProgramPopoutCategory(), label="Kategorie programu")
 
@@ -162,95 +157,14 @@ class ProgramGroupBlockPopout(StructBlock):
         label = "Vyskakovací program"
 
 
-class ProgramGroupBlockMixin(StructBlock):
-    title = CharBlock(
-        label="Název programu",
-        help_text="Např. 'Krajské volby 2024', 'Evropské volby 2024', ...",
-    )
-    # point_list = ListBlock(ProgramBlock(), label="Jednotlivé články programu")
-
-    class Meta:
-        icon = "date"
-        template = "styleguide2/includes/molecules/program/program_block.html"
-        # label = "Skupina programů"
-
-    def get_prep_value(self, value):
-        value = super().get_prep_value(value)
-        value["slug"] = slugify(value["title"])
-        return value
-
-
-class ProgramBlock(StructBlock):
-    url = URLBlock(
-        label="Odkaz pokrývající celou tuto část",
-        required=False,
-    )
-    icon = ImageChooserBlock(
-        label="Ikona",
-        required=False,
-    )
-    title = CharBlock(label="Titulek článku programu")
-    text = RichTextBlock(
-        label="Obsah",
-        features=PROGRAM_RICH_TEXT_FEATURES,
-    )
-
-    class Meta:
-        icon = "date"
-        label = "Článek programu"
-
-
 class ProgramGroupBlock(ProgramGroupBlockMixin):
-    point_list = ListBlock(ProgramBlock(), label="Jednotlivé články programu")
+    point_list = ListBlock(ProgramPointBlock(), label="Jednotlivé články programu")
 
     class Meta:
         icon = "date"
         label = "Běžný program"
 
 
-# Candidates
-
-
-class CandidateBlock(StructBlock):
-    # NOTE: Page type should be restricted in mixed-in classes
-    page = PageChooserBlock(label="Stránka")
-
-    image = ImageChooserBlock(
-        label="Obrázek",
-        help_text="Pokud není vybrán, použije se obrázek ze stránky kandidáta",
-        required=False,
-    )
-
-    description = TextBlock(label="Popis", required=False)
-
-    class Meta:
-        template = (
-            "styleguide2/includes/molecules/candidates/candidate_primary_box.html"
-        )
-        icon = "form"
-        label = "Kandidát"
-
-
-class SecondaryCandidateBlock(StructBlock):
-    number = CharBlock(label="Číslo")
-
-    # NOTE: Page type should be restricted in mixed-in classes
-    page = PageChooserBlock(label="Stránka")
-
-    image = ImageChooserBlock(
-        label="Obrázek",
-        help_text="Pokud není vybrán, použije se obrázek ze stránky kandidáta",
-        required=False,
-    )
-
-    class Meta:
-        template = (
-            "styleguide2/includes/molecules/candidates/candidate_secondary_box.html"
-        )
-        icon = "form"
-        label = "Kandidát"
-
-
 class CandidateListBlock(StructBlock):
     # NOTE: should be changed in mixed-in blocks.
     candidates = ListBlock(
@@ -283,26 +197,6 @@ class CandidateSecondaryListBlock(StructBlock):
         label = "Sekundární seznam kandidátů"
 
 
-class CarouselProgramCategoryItemBlock(StructBlock):
-    content = TextBlock(label="Obsah")
-
-    class Meta:
-        icon = "form"
-        label = "Bod"
-
-
-class CarouselProgramCategoryBlock(StructBlock):
-    number = IntegerBlock(label="Číslo")
-
-    name = CharBlock(label="Název")
-
-    points = ListBlock(CarouselProgramCategoryItemBlock(), label="Body")
-
-    class Meta:
-        icon = "form"
-        label = "Kategorie"
-
-
 class CarouselProgramBlock(StructBlock):
     label = CharBlock(label="Nadpis", help_text="Např. 'Program'", default="Program")
 
@@ -321,3 +215,27 @@ class CarouselProgramBlock(StructBlock):
         icon = "form"
         label = "Priority programu, carousel"
         template = "styleguide2/includes/molecules/program/card_program.html"
+
+
+class GalleryBlock(StructBlock):
+    gallery_items = ListBlock(
+        ImageChooserBlock(label="obrázek", required=True),
+        label="Galerie",
+        icon="image",
+        group="ostatní",
+    )
+
+    class Meta:
+        label = "Galerie"
+        icon = "image"
+        template = "styleguide2/includes/molecules/gallery/gallery.html"
+
+
+class FigureBlock(StructBlock):
+    img = ImageChooserBlock(label="Obrázek", required=True)
+    caption = TextBlock(label="Popisek", required=False)
+
+    class Meta:
+        label = "Obrázek"
+        icon = "image"
+        template = "styleguide2/includes/atoms/figure/figure.html"
\ No newline at end of file
diff --git a/uniweb/migrations/0067_uniwebhomepage_footer_other_links_and_more.py b/uniweb/migrations/0067_uniwebhomepage_footer_other_links_and_more.py
index 1ab2735c..3d553d0f 100644
--- a/uniweb/migrations/0067_uniwebhomepage_footer_other_links_and_more.py
+++ b/uniweb/migrations/0067_uniwebhomepage_footer_other_links_and_more.py
@@ -5,7 +5,7 @@ import wagtail.blocks
 import wagtail.fields
 from django.db import migrations, models
 
-import shared.blocks.main
+import shared.blocks
 
 
 class Migration(migrations.Migration):
@@ -28,7 +28,7 @@ class Migration(migrations.Migration):
                                 (
                                     "list",
                                     wagtail.blocks.ListBlock(
-                                        shared.blocks.main.LinkBlock,
+                                        shared.blocks.LinkBlock,
                                         label="Seznam odkazů",
                                     ),
                                 ),
-- 
GitLab