Skip to content
Snippets Groups Projects
Commit af23f95c authored by OndraRehounek's avatar OndraRehounek Committed by jan.bednarik
Browse files

ArticleMixin: YouTubeVideoBlock

parent 41758d49
No related branches found
No related tags found
2 merge requests!473Release,!469ArticleMixin: YouTubeVideoBlock
# 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",
),
),
]
# 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",
),
),
]
import logging
import re
from django.forms.utils import ErrorList from django.forms.utils import ErrorList
from wagtail.core import blocks from wagtail.core import blocks
from wagtail.core.blocks.struct_block import StructBlockValidationError from wagtail.core.blocks.struct_block import StructBlockValidationError
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
logger = logging.getLogger(__name__)
class GalleryBlock(blocks.StructBlock): class GalleryBlock(blocks.StructBlock):
gallery_items = blocks.ListBlock( gallery_items = blocks.ListBlock(
...@@ -14,6 +19,7 @@ class GalleryBlock(blocks.StructBlock): ...@@ -14,6 +19,7 @@ class GalleryBlock(blocks.StructBlock):
class Meta: class Meta:
label = "Galerie" label = "Galerie"
icon = "image"
template = "styleguide/2.3.x/blocks/gallery_block.html" template = "styleguide/2.3.x/blocks/gallery_block.html"
...@@ -57,3 +63,77 @@ class ProgramItemBlock(blocks.StructBlock): ...@@ -57,3 +63,77 @@ class ProgramItemBlock(blocks.StructBlock):
completion_percentage = blocks.IntegerBlock( completion_percentage = blocks.IntegerBlock(
label="Procento dokončení", required=True 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 ""
...@@ -24,7 +24,6 @@ from markdown.inlinepatterns import InlineProcessor ...@@ -24,7 +24,6 @@ from markdown.inlinepatterns import InlineProcessor
from wagtail.contrib.redirects.models import Redirect from wagtail.contrib.redirects.models import Redirect
from wagtail.core.models import Page from wagtail.core.models import Page
from wagtail.core.models.collections import Collection from wagtail.core.models.collections import Collection
from wagtail.core.rich_text import RichText
from wagtail.images.models import Image from wagtail.images.models import Image
from yaml.scanner import ScannerError from yaml.scanner import ScannerError
......
...@@ -11,7 +11,12 @@ from wagtail.core.fields import StreamField ...@@ -11,7 +11,12 @@ from wagtail.core.fields import StreamField
from wagtail.core.models import Page from wagtail.core.models import Page
from wagtail.images.edit_handlers import ImageChooserPanel from wagtail.images.edit_handlers import ImageChooserPanel
from shared.blocks import GalleryBlock, MenuItemBlock, MenuParentBlock from shared.blocks import (
GalleryBlock,
MenuItemBlock,
MenuParentBlock,
YouTubeVideoBlock,
)
class SubpageMixin: class SubpageMixin:
...@@ -61,6 +66,7 @@ class ArticleMixin(models.Model): ...@@ -61,6 +66,7 @@ class ArticleMixin(models.Model):
RichTextBlock(label="Textový editor", features=RICH_TEXT_FEATURES), RichTextBlock(label="Textový editor", features=RICH_TEXT_FEATURES),
), ),
("gallery", GalleryBlock(label="Galerie")), ("gallery", GalleryBlock(label="Galerie")),
("youtube", YouTubeVideoBlock(label="YouTube video")),
], ],
verbose_name="Článek", verbose_name="Článek",
blank=True, blank=True,
......
...@@ -7,6 +7,10 @@ table caption { ...@@ -7,6 +7,10 @@ table caption {
position: relative; position: relative;
} }
.responsive-object.ratio-16-9 {
padding-bottom: calc(100% / 16 * 9);
}
.responsive-object iframe, .responsive-object iframe,
.responsive-object object, .responsive-object object,
.responsive-object embed { .responsive-object embed {
......
{% 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>
# 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",
),
),
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment