From af23f95c55f8654978f368deae0913bca620f5e5 Mon Sep 17 00:00:00 2001
From: OndraRehounek <ondra.rehounek@seznam.cz>
Date: Thu, 21 Apr 2022 11:14:11 +0200
Subject: [PATCH] ArticleMixin: YouTubeVideoBlock

---
 ...er_districtarticlepage_content_and_more.py | 269 ++++++++++++++++++
 ...lter_regionarticlepage_content_and_more.py | 269 ++++++++++++++++++
 shared/blocks.py                              |  80 ++++++
 shared/jekyll_import.py                       |   1 -
 shared/models.py                              |   8 +-
 shared/static/shared/css/helpers.css          |   4 +
 .../styleguide/2.3.x/blocks/video_block.html  |  10 +
 .../0024_alter_uniwebarticlepage_content.py   |  88 ++++++
 8 files changed, 727 insertions(+), 2 deletions(-)
 create mode 100644 district/migrations/0055_alter_districtarticlepage_content_and_more.py
 create mode 100644 region/migrations/0030_alter_regionarticlepage_content_and_more.py
 create mode 100644 shared/templates/styleguide/2.3.x/blocks/video_block.html
 create mode 100644 uniweb/migrations/0024_alter_uniwebarticlepage_content.py

diff --git a/district/migrations/0055_alter_districtarticlepage_content_and_more.py b/district/migrations/0055_alter_districtarticlepage_content_and_more.py
new file mode 100644
index 00000000..67289e95
--- /dev/null
+++ b/district/migrations/0055_alter_districtarticlepage_content_and_more.py
@@ -0,0 +1,269 @@
+# Generated by Django 4.0.3 on 2022-04-21 08:57
+
+import wagtail.contrib.table_block.blocks
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtail.images.blocks
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("district", "0054_alter_districtcenterpage_content_and_more"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="districtarticlepage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "text",
+                        wagtail.core.blocks.RichTextBlock(
+                            features=[
+                                "h2",
+                                "h3",
+                                "h4",
+                                "bold",
+                                "italic",
+                                "ol",
+                                "embed",
+                                "ul",
+                                "link",
+                                "document-link",
+                                "image",
+                            ],
+                            label="Textový editor",
+                        ),
+                    ),
+                    (
+                        "gallery",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "gallery_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.images.blocks.ImageChooserBlock(
+                                            label="obrázek", required=True
+                                        ),
+                                        group="ostatní",
+                                        icon="image",
+                                        label="Galerie",
+                                    ),
+                                )
+                            ],
+                            label="Galerie",
+                        ),
+                    ),
+                    (
+                        "youtube",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "video_url",
+                                    wagtail.core.blocks.URLBlock(
+                                        help_text="Odkaz na YouTube video bude automaticky zkonvertován na ID videa a NEBUDE uložen.",
+                                        label="Odkaz na video",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "video_id",
+                                    wagtail.core.blocks.CharBlock(
+                                        help_text="Není třeba vyplňovat, bude automaticky načteno z odkazu.",
+                                        label="ID videa (automatické pole)",
+                                        required=False,
+                                    ),
+                                ),
+                            ],
+                            label="YouTube video",
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Článek",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="districtcenterpage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    ("text", wagtail.core.blocks.RichTextBlock()),
+                    ("table", wagtail.contrib.table_block.blocks.TableBlock()),
+                ],
+                blank=True,
+                verbose_name="Obsah",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="districtcustompage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    ("text", wagtail.core.blocks.RichTextBlock()),
+                    ("table", wagtail.contrib.table_block.blocks.TableBlock()),
+                    (
+                        "people_group",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "group_title",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=True
+                                    ),
+                                ),
+                                (
+                                    "person_list",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.PageChooserBlock(
+                                            label="Osoba",
+                                            page_type=[
+                                                "district.DistrictPersonPage",
+                                                "region.RegionPersonPage",
+                                            ],
+                                        ),
+                                        label="List osob",
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Obsah",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="districtprogrampage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "static_program_block",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "headline",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek bloku", required=True
+                                    ),
+                                ),
+                                (
+                                    "perex",
+                                    wagtail.core.blocks.TextBlock(
+                                        label="Krátký text pod nadpisem", required=True
+                                    ),
+                                ),
+                                (
+                                    "person",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="Garant",
+                                        page_type=["district.DistrictPersonPage"],
+                                    ),
+                                ),
+                                (
+                                    "completion_percentage",
+                                    wagtail.core.blocks.IntegerBlock(
+                                        label="Procento dokončení", required=True
+                                    ),
+                                ),
+                                (
+                                    "program_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "title",
+                                                    wagtail.core.blocks.CharBlock(
+                                                        label="Název", required=True
+                                                    ),
+                                                ),
+                                                (
+                                                    "completion_percentage",
+                                                    wagtail.core.blocks.IntegerBlock(
+                                                        label="Procento dokončení",
+                                                        required=True,
+                                                    ),
+                                                ),
+                                            ]
+                                        ),
+                                        label="Seznam bodů",
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                    (
+                        "redmine_program_block",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "headline",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek bloku", required=True
+                                    ),
+                                ),
+                                (
+                                    "perex",
+                                    wagtail.core.blocks.TextBlock(
+                                        label="Krátký text pod nadpisem", required=True
+                                    ),
+                                ),
+                                (
+                                    "person",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="Garant",
+                                        page_type=["district.DistrictPersonPage"],
+                                    ),
+                                ),
+                                (
+                                    "redmine_issue",
+                                    wagtail.core.blocks.IntegerBlock(
+                                        label="Číslo Redmine issue", required=True
+                                    ),
+                                ),
+                                (
+                                    "completion_percentage",
+                                    wagtail.core.blocks.IntegerBlock(
+                                        help_text="Hodnota se automaticky načte s Redmine",
+                                        label="Procento dokončení - bude doplněno automaticky",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "program_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "title",
+                                                    wagtail.core.blocks.CharBlock(
+                                                        label="Název", required=True
+                                                    ),
+                                                ),
+                                                (
+                                                    "completion_percentage",
+                                                    wagtail.core.blocks.IntegerBlock(
+                                                        label="Procento dokončení",
+                                                        required=True,
+                                                    ),
+                                                ),
+                                            ]
+                                        ),
+                                        help_text="Hodnota se automaticky načte s Redmine",
+                                        label="Seznam bodů - bude doplněno automaticky",
+                                        required=False,
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="obsah stránky",
+            ),
+        ),
+    ]
diff --git a/region/migrations/0030_alter_regionarticlepage_content_and_more.py b/region/migrations/0030_alter_regionarticlepage_content_and_more.py
new file mode 100644
index 00000000..eac00125
--- /dev/null
+++ b/region/migrations/0030_alter_regionarticlepage_content_and_more.py
@@ -0,0 +1,269 @@
+# Generated by Django 4.0.3 on 2022-04-21 08:57
+
+import wagtail.contrib.table_block.blocks
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtail.images.blocks
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("region", "0029_alter_regioncenterpage_content_and_more"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="regionarticlepage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "text",
+                        wagtail.core.blocks.RichTextBlock(
+                            features=[
+                                "h2",
+                                "h3",
+                                "h4",
+                                "bold",
+                                "italic",
+                                "ol",
+                                "embed",
+                                "ul",
+                                "link",
+                                "document-link",
+                                "image",
+                            ],
+                            label="Textový editor",
+                        ),
+                    ),
+                    (
+                        "gallery",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "gallery_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.images.blocks.ImageChooserBlock(
+                                            label="obrázek", required=True
+                                        ),
+                                        group="ostatní",
+                                        icon="image",
+                                        label="Galerie",
+                                    ),
+                                )
+                            ],
+                            label="Galerie",
+                        ),
+                    ),
+                    (
+                        "youtube",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "video_url",
+                                    wagtail.core.blocks.URLBlock(
+                                        help_text="Odkaz na YouTube video bude automaticky zkonvertován na ID videa a NEBUDE uložen.",
+                                        label="Odkaz na video",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "video_id",
+                                    wagtail.core.blocks.CharBlock(
+                                        help_text="Není třeba vyplňovat, bude automaticky načteno z odkazu.",
+                                        label="ID videa (automatické pole)",
+                                        required=False,
+                                    ),
+                                ),
+                            ],
+                            label="YouTube video",
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Článek",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="regioncenterpage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    ("text", wagtail.core.blocks.RichTextBlock()),
+                    ("table", wagtail.contrib.table_block.blocks.TableBlock()),
+                ],
+                blank=True,
+                verbose_name="Obsah",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="regioncustompage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    ("text", wagtail.core.blocks.RichTextBlock()),
+                    ("table", wagtail.contrib.table_block.blocks.TableBlock()),
+                    (
+                        "people_group",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "group_title",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek", required=True
+                                    ),
+                                ),
+                                (
+                                    "person_list",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.PageChooserBlock(
+                                            label="Osoba",
+                                            page_type=[
+                                                "district.DistrictPersonPage",
+                                                "region.RegionPersonPage",
+                                            ],
+                                        ),
+                                        label="List osob",
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Obsah",
+            ),
+        ),
+        migrations.AlterField(
+            model_name="regionprogrampage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "static_program_block",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "headline",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek bloku", required=True
+                                    ),
+                                ),
+                                (
+                                    "perex",
+                                    wagtail.core.blocks.TextBlock(
+                                        label="Krátký text pod nadpisem", required=True
+                                    ),
+                                ),
+                                (
+                                    "person",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="Garant",
+                                        page_type=["region.RegionPersonPage"],
+                                    ),
+                                ),
+                                (
+                                    "completion_percentage",
+                                    wagtail.core.blocks.IntegerBlock(
+                                        label="Procento dokončení", required=True
+                                    ),
+                                ),
+                                (
+                                    "program_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "title",
+                                                    wagtail.core.blocks.CharBlock(
+                                                        label="Název", required=True
+                                                    ),
+                                                ),
+                                                (
+                                                    "completion_percentage",
+                                                    wagtail.core.blocks.IntegerBlock(
+                                                        label="Procento dokončení",
+                                                        required=True,
+                                                    ),
+                                                ),
+                                            ]
+                                        ),
+                                        label="Seznam bodů",
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                    (
+                        "redmine_program_block",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "headline",
+                                    wagtail.core.blocks.CharBlock(
+                                        label="Titulek bloku", required=True
+                                    ),
+                                ),
+                                (
+                                    "perex",
+                                    wagtail.core.blocks.TextBlock(
+                                        label="Krátký text pod nadpisem", required=True
+                                    ),
+                                ),
+                                (
+                                    "person",
+                                    wagtail.core.blocks.PageChooserBlock(
+                                        label="Garant",
+                                        page_type=["region.RegionPersonPage"],
+                                    ),
+                                ),
+                                (
+                                    "redmine_issue",
+                                    wagtail.core.blocks.IntegerBlock(
+                                        label="Číslo Redmine issue", required=True
+                                    ),
+                                ),
+                                (
+                                    "completion_percentage",
+                                    wagtail.core.blocks.IntegerBlock(
+                                        help_text="Hodnota se automaticky načte s Redmine",
+                                        label="Procento dokončení - bude doplněno automaticky",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "program_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.core.blocks.StructBlock(
+                                            [
+                                                (
+                                                    "title",
+                                                    wagtail.core.blocks.CharBlock(
+                                                        label="Název", required=True
+                                                    ),
+                                                ),
+                                                (
+                                                    "completion_percentage",
+                                                    wagtail.core.blocks.IntegerBlock(
+                                                        label="Procento dokončení",
+                                                        required=True,
+                                                    ),
+                                                ),
+                                            ]
+                                        ),
+                                        help_text="Hodnota se automaticky načte s Redmine",
+                                        label="Seznam bodů - bude doplněno automaticky",
+                                        required=False,
+                                    ),
+                                ),
+                            ]
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="obsah stránky",
+            ),
+        ),
+    ]
diff --git a/shared/blocks.py b/shared/blocks.py
index 846a082a..ecb3382a 100644
--- a/shared/blocks.py
+++ b/shared/blocks.py
@@ -1,8 +1,13 @@
+import logging
+import re
+
 from django.forms.utils import ErrorList
 from wagtail.core import blocks
 from wagtail.core.blocks.struct_block import StructBlockValidationError
 from wagtail.images.blocks import ImageChooserBlock
 
+logger = logging.getLogger(__name__)
+
 
 class GalleryBlock(blocks.StructBlock):
     gallery_items = blocks.ListBlock(
@@ -14,6 +19,7 @@ class GalleryBlock(blocks.StructBlock):
 
     class Meta:
         label = "Galerie"
+        icon = "image"
         template = "styleguide/2.3.x/blocks/gallery_block.html"
 
 
@@ -57,3 +63,77 @@ class ProgramItemBlock(blocks.StructBlock):
     completion_percentage = blocks.IntegerBlock(
         label="Procento dokončení", required=True
     )
+
+
+class YouTubeVideoBlock(blocks.StructBlock):
+    video_url = blocks.URLBlock(
+        label="Odkaz na video",
+        required=False,
+        help_text="Odkaz na YouTube video bude automaticky "
+        "zkonvertován na ID videa a NEBUDE uložen.",
+    )
+    video_id = blocks.CharBlock(
+        label="ID videa (automatické pole)",
+        required=False,
+        help_text="Není třeba vyplňovat, bude automaticky " "načteno z odkazu.",
+    )
+
+    class Meta:
+        label = "YouTube video"
+        icon = "media"
+        template = "styleguide/2.3.x/blocks/video_block.html"
+
+    def clean(self, value):
+        errors = {}
+
+        if not value["video_url"] and not value["video_id"]:
+            errors["video_url"] = ErrorList(["Zadejte prosím odkaz na YouTube video."])
+
+        if value["video_url"]:
+            if not value["video_url"].startswith("https://youtu.be") and not value[
+                "video_url"
+            ].startswith("https://www.youtube.com"):
+                errors["video_url"] = ErrorList(
+                    [
+                        'Odkaz na video musí začínat "https://www.youtube.com" '
+                        'nebo "https://youtu.be"'
+                    ]
+                )
+
+        if value["video_id"]:
+            if not re.match("^[A-Za-z0-9_-]{11}$", value["video_id"]):
+                errors["video_url"] = ErrorList(
+                    ["Formát ID YouTube videa není validní"]
+                )
+
+        if errors:
+            raise StructBlockValidationError(errors)
+        return super().clean(value)
+
+    def get_prep_value(self, value):
+        value = super().get_prep_value(value)
+
+        if value["video_url"]:
+            value["video_id"] = self.convert_youtube_link_to_video_id(
+                value["video_url"]
+            )
+
+        value["video_url"] = ""
+
+        return value
+
+    @staticmethod
+    def convert_youtube_link_to_video_id(url):
+        reg_str = (
+            "((?<=(v|V)/)|(?<=youtu\.be/)|(?<=youtube\.com/watch(\?|\&)v=)"
+            "|(?<=embed/))([\w-]+)"
+        )
+        search_result = re.search(reg_str, url)
+
+        if search_result:
+            return search_result.group(0)
+
+        logger.warning(
+            "Nepodařilo se získat video ID z YouTube URL", extra={"url": url}
+        )
+        return ""
diff --git a/shared/jekyll_import.py b/shared/jekyll_import.py
index 96fe829f..c348b692 100644
--- a/shared/jekyll_import.py
+++ b/shared/jekyll_import.py
@@ -24,7 +24,6 @@ from markdown.inlinepatterns import InlineProcessor
 from wagtail.contrib.redirects.models import Redirect
 from wagtail.core.models import Page
 from wagtail.core.models.collections import Collection
-from wagtail.core.rich_text import RichText
 from wagtail.images.models import Image
 from yaml.scanner import ScannerError
 
diff --git a/shared/models.py b/shared/models.py
index 09c39f31..adc305d0 100644
--- a/shared/models.py
+++ b/shared/models.py
@@ -11,7 +11,12 @@ from wagtail.core.fields import StreamField
 from wagtail.core.models import Page
 from wagtail.images.edit_handlers import ImageChooserPanel
 
-from shared.blocks import GalleryBlock, MenuItemBlock, MenuParentBlock
+from shared.blocks import (
+    GalleryBlock,
+    MenuItemBlock,
+    MenuParentBlock,
+    YouTubeVideoBlock,
+)
 
 
 class SubpageMixin:
@@ -61,6 +66,7 @@ class ArticleMixin(models.Model):
                 RichTextBlock(label="Textový editor", features=RICH_TEXT_FEATURES),
             ),
             ("gallery", GalleryBlock(label="Galerie")),
+            ("youtube", YouTubeVideoBlock(label="YouTube video")),
         ],
         verbose_name="Článek",
         blank=True,
diff --git a/shared/static/shared/css/helpers.css b/shared/static/shared/css/helpers.css
index 7123673d..781d11ac 100644
--- a/shared/static/shared/css/helpers.css
+++ b/shared/static/shared/css/helpers.css
@@ -7,6 +7,10 @@ table caption {
     position: relative;
 }
 
+.responsive-object.ratio-16-9 {
+    padding-bottom: calc(100% / 16 * 9);
+}
+
 .responsive-object iframe,
 .responsive-object object,
 .responsive-object embed {
diff --git a/shared/templates/styleguide/2.3.x/blocks/video_block.html b/shared/templates/styleguide/2.3.x/blocks/video_block.html
new file mode 100644
index 00000000..31ab43a6
--- /dev/null
+++ b/shared/templates/styleguide/2.3.x/blocks/video_block.html
@@ -0,0 +1,10 @@
+{% load wagtailimages_tags %}
+<div class="content-block responsive-object ratio-16-9 w-full mb-10">
+  <iframe
+    src="https://www.youtube-nocookie.com/embed/{{ self.video_id }}"
+    title="YouTube video player"
+    frameborder="0"
+    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
+    allowfullscreen
+  ></iframe>
+</div>
diff --git a/uniweb/migrations/0024_alter_uniwebarticlepage_content.py b/uniweb/migrations/0024_alter_uniwebarticlepage_content.py
new file mode 100644
index 00000000..b08c5067
--- /dev/null
+++ b/uniweb/migrations/0024_alter_uniwebarticlepage_content.py
@@ -0,0 +1,88 @@
+# Generated by Django 4.0.3 on 2022-04-21 08:57
+
+import wagtail.core.blocks
+import wagtail.core.fields
+import wagtail.images.blocks
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("uniweb", "0023_alter_uniwebarticlepage_content"),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name="uniwebarticlepage",
+            name="content",
+            field=wagtail.core.fields.StreamField(
+                [
+                    (
+                        "text",
+                        wagtail.core.blocks.RichTextBlock(
+                            features=[
+                                "h2",
+                                "h3",
+                                "h4",
+                                "bold",
+                                "italic",
+                                "ol",
+                                "embed",
+                                "ul",
+                                "link",
+                                "document-link",
+                                "image",
+                            ],
+                            label="Textový editor",
+                        ),
+                    ),
+                    (
+                        "gallery",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "gallery_items",
+                                    wagtail.core.blocks.ListBlock(
+                                        wagtail.images.blocks.ImageChooserBlock(
+                                            label="obrázek", required=True
+                                        ),
+                                        group="ostatní",
+                                        icon="image",
+                                        label="Galerie",
+                                    ),
+                                )
+                            ],
+                            label="Galerie",
+                        ),
+                    ),
+                    (
+                        "youtube",
+                        wagtail.core.blocks.StructBlock(
+                            [
+                                (
+                                    "video_url",
+                                    wagtail.core.blocks.URLBlock(
+                                        help_text="Odkaz na YouTube video bude automaticky zkonvertován na ID videa a NEBUDE uložen.",
+                                        label="Odkaz na video",
+                                        required=False,
+                                    ),
+                                ),
+                                (
+                                    "video_id",
+                                    wagtail.core.blocks.CharBlock(
+                                        help_text="Není třeba vyplňovat, bude automaticky načteno z odkazu.",
+                                        label="ID videa (automatické pole)",
+                                        required=False,
+                                    ),
+                                ),
+                            ],
+                            label="YouTube video",
+                        ),
+                    ),
+                ],
+                blank=True,
+                verbose_name="Článek",
+            ),
+        ),
+    ]
-- 
GitLab