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

article mixin: YouTube block with poster (without migrations)

parent ae45d83c
Branches
No related tags found
2 merge requests!480Release,!478Feature/youtube block
...@@ -910,7 +910,6 @@ class DistrictCenterPage( ...@@ -910,7 +910,6 @@ class DistrictCenterPage(
CalendarMixin, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page CalendarMixin, ExtendedMetadataPageMixin, SubpageMixin, MetadataPageMixin, Page
): ):
### FIELDS ### FIELDS
# TODO tohle by šlo asi nahradit DistrictCustomPage
perex = models.TextField("Perex", blank=True, null=True) perex = models.TextField("Perex", blank=True, null=True)
background_photo = models.ForeignKey( background_photo = models.ForeignKey(
......
import logging import logging
import re import re
import urllib
from django.core.files.images import ImageFile
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.core.models import Collection
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
from wagtail.images.models import Image
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -67,6 +71,11 @@ class ProgramItemBlock(blocks.StructBlock): ...@@ -67,6 +71,11 @@ class ProgramItemBlock(blocks.StructBlock):
class YouTubeVideoBlock(blocks.StructBlock): class YouTubeVideoBlock(blocks.StructBlock):
poster_image = ImageChooserBlock(
label="Náhled videa (automatické pole)",
required=False,
help_text="Není třeba vyplňovat, náhled bude " "dohledán automaticky.",
)
video_url = blocks.URLBlock( video_url = blocks.URLBlock(
label="Odkaz na video", label="Odkaz na video",
required=False, required=False,
...@@ -118,6 +127,9 @@ class YouTubeVideoBlock(blocks.StructBlock): ...@@ -118,6 +127,9 @@ class YouTubeVideoBlock(blocks.StructBlock):
value["video_id"] = self.convert_youtube_link_to_video_id( value["video_id"] = self.convert_youtube_link_to_video_id(
value["video_url"] value["video_url"]
) )
value["poster_image"] = self.get_wagtail_image_id_for_youtube_poster(
value["video_id"]
)
value["video_url"] = "" value["video_url"] = ""
...@@ -138,3 +150,36 @@ class YouTubeVideoBlock(blocks.StructBlock): ...@@ -138,3 +150,36 @@ class YouTubeVideoBlock(blocks.StructBlock):
"Nepodařilo se získat video ID z YouTube URL", extra={"url": url} "Nepodařilo se získat video ID z YouTube URL", extra={"url": url}
) )
return "" return ""
@classmethod
def get_wagtail_image_id_for_youtube_poster(cls, video_id) -> int or None:
image_url = "https://img.youtube.com/vi/{}/hqdefault.jpg".format(video_id)
img_path = "/tmp/{}.jpg".format(video_id)
urllib.request.urlretrieve(image_url, img_path)
file = ImageFile(open(img_path, "rb"), name=img_path)
return cls.get_image_id(file, "YT_poster_v_{}".format(video_id))
@classmethod
def get_image_id(cls, file: ImageFile, image_title: str) -> int:
try:
image = Image.objects.get(title=image_title)
except Image.DoesNotExist:
image = Image(
title=image_title, file=file, collection=cls.get_posters_collection()
)
image.save()
return image.id
@staticmethod
def get_posters_collection() -> Collection:
collection_name = "YouTube nahledy"
try:
collection = Collection.objects.get(name=collection_name)
except Collection.DoesNotExist:
root_collection = Collection.get_first_root_node()
collection = root_collection.add_child(name=collection_name)
return collection
...@@ -20,3 +20,18 @@ table caption { ...@@ -20,3 +20,18 @@ table caption {
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.youtube-poster {
position: relative;
}
.youtube-poster i {
cursor: pointer;
left: 50%;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
transition: color 0.25s ease-in-out;
}
.youtube-poster:hover i {
color: white;
}
{% load wagtailimages_tags %} {% load wagtailimages_tags %}
<div class="content-block responsive-object ratio-16-9 w-full mb-10"> <div class="mb-10 text-center youtube-poster" id="ytVideo{{ self.video_id }}PosterContainer">
<iframe {% image self.poster_image width-720 as img %}
src="https://www.youtube-nocookie.com/embed/{{ self.video_id }}" <img src="{{ img.url }}" alt="{{ img.alt }}" class="w-full object-cover mb-2">
title="YouTube video player" <small class="font-bold">
frameborder="0" Spuštěním videa dojde k načtení obsahu třetích stran z portálu YouTube.
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" </small>
allowfullscreen <i class="ico--youtube text-9xl"></i>
></iframe>
</div> </div>
<div
class="content-block responsive-object ratio-16-9 mb-10 w-full"
id="ytVideo{{ self.video_id }}IframeContainer"
style="display: none"
>
</div>
{# Script, který při kliknutí na poster načte iframe s YouTube videem (v Enhanced Privacy Mode) #}
{# Záměrně je přímo na bloku, protože málokterý článek bude mít více videí a naopak většina článků YT videa nemá #}
<script>
(function () {
const posterContainer = document.getElementById('ytVideo{{ self.video_id }}PosterContainer')
const videoContainer = document.getElementById('ytVideo{{ self.video_id }}IframeContainer')
posterContainer.onclick = function () {
videoContainer.innerHTML = '<iframe src="https://www.youtube-nocookie.com/embed/{{ self.video_id }}?autoplay=1" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen ></iframe>'
videoContainer.style.display = 'block'
posterContainer.style.display = 'none'
}
})()
</script>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment