kopia lustrzana https://github.com/wagtail/wagtail
fix small youtube embed - allow to override max_width/max_height in EmbedBlock
rodzic
a64eb1f2f3
commit
50e4f5151d
|
@ -10,6 +10,7 @@ Changelog
|
|||
* Added `full_url` property to image renditions (Shreyash Srivastava)
|
||||
* Added locale selector when choosing translatable snippets (Karl Hobley)
|
||||
* Added `WAGTAIL_WORKFLOW_ENABLED` setting for enabling / disabling moderation workflows globally (Matt Westcott)
|
||||
* Allow specifying `max_width` and `max_height` on EmbedBlock (Petr Dlouhý)
|
||||
* Fix: Invalid filter values for foreign key fields in the API now give an error instead of crashing (Tidjani Dia)
|
||||
* Fix: Ordering specified in `construct_explorer_page_queryset` hook is now taken into account again by the page explorer API (Andre Fonseca)
|
||||
* Fix: Deleting a page from its listing view no longer results in a 404 error (Tidjani Dia)
|
||||
|
|
|
@ -33,6 +33,8 @@ nest the embed code.
|
|||
The :class:`~wagtail.embeds.block.EmbedBlock` block type allows embeds
|
||||
to be placed into a ``StreamField``.
|
||||
|
||||
The ``max_width`` and ``max_height`` arguments are sent to the provider when fetching the embed code.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
@ -42,7 +44,7 @@ For example:
|
|||
class MyStreamField(blocks.StreamBlock):
|
||||
...
|
||||
|
||||
embed = EmbedBlock()
|
||||
embed = EmbedBlock(max_width=800, max_height=400)
|
||||
|
||||
``{% embed %}`` tag
|
||||
-------------------
|
||||
|
|
|
@ -332,6 +332,8 @@ Field block types
|
|||
A field for the editor to enter a URL to a media item (such as a YouTube video) to appear as embedded media on the page. The following keyword arguments are accepted in addition to the standard ones:
|
||||
|
||||
:param required: If true (the default), the field cannot be left blank.
|
||||
:param max_width: The maximum width of the embed, in pixels; this will be passed to the provider when requesting the embed.
|
||||
:param max_height: The maximum height of the embed, in pixels; this will be passed to the provider when requesting the embed.
|
||||
:param max_length: The maximum allowed length of the field.
|
||||
:param min_length: The minimum allowed length of the field.
|
||||
:param help_text: Help text to display alongside the field.
|
||||
|
|
|
@ -18,6 +18,7 @@ Other features
|
|||
* Added ``full_url`` property to image renditions (Shreyash Srivastava)
|
||||
* Added locale selector when choosing translatable snippets (Karl Hobley)
|
||||
* Added ``WAGTAIL_WORKFLOW_ENABLED`` setting for enabling / disabling moderation workflows globally (Matt Westcott)
|
||||
* Allow specifying ``max_width`` and ``max_height`` on EmbedBlock (Petr Dlouhý)
|
||||
|
||||
Bug fixes
|
||||
~~~~~~~~~
|
||||
|
|
|
@ -14,12 +14,14 @@ class EmbedValue:
|
|||
we want to be able to do {% embed value.url 500 %} without
|
||||
doing a redundant fetch of the embed at the default width.
|
||||
"""
|
||||
def __init__(self, url):
|
||||
def __init__(self, url, max_width=None, max_height=None):
|
||||
self.url = url
|
||||
self.max_width = max_width
|
||||
self.max_height = max_height
|
||||
|
||||
@cached_property
|
||||
def html(self):
|
||||
return embed_to_frontend_html(self.url)
|
||||
return embed_to_frontend_html(self.url, self.max_width, self.max_height)
|
||||
|
||||
def __str__(self):
|
||||
return self.html
|
||||
|
@ -34,7 +36,7 @@ class EmbedBlock(blocks.URLBlock):
|
|||
return self.meta.default
|
||||
else:
|
||||
# assume default has been passed as a string
|
||||
return EmbedValue(self.meta.default)
|
||||
return EmbedValue(self.meta.default, getattr(self.meta, 'max_width', None), getattr(self.meta, 'max_height', None))
|
||||
|
||||
def to_python(self, value):
|
||||
# The JSON representation of an EmbedBlock's value is a URL string;
|
||||
|
@ -42,7 +44,7 @@ class EmbedBlock(blocks.URLBlock):
|
|||
if not value:
|
||||
return None
|
||||
else:
|
||||
return EmbedValue(value)
|
||||
return EmbedValue(value, getattr(self.meta, 'max_width', None), getattr(self.meta, 'max_height', None))
|
||||
|
||||
def get_prep_value(self, value):
|
||||
# serialisable value should be a URL string
|
||||
|
@ -63,7 +65,7 @@ class EmbedBlock(blocks.URLBlock):
|
|||
if not value:
|
||||
return None
|
||||
else:
|
||||
return EmbedValue(value)
|
||||
return EmbedValue(value, getattr(self.meta, 'max_width', None), getattr(self.meta, 'max_height', None))
|
||||
|
||||
def clean(self, value):
|
||||
if isinstance(value, EmbedValue) and not value.html:
|
||||
|
|
|
@ -3,13 +3,14 @@ from hashlib import md5
|
|||
|
||||
from django.utils.timezone import now
|
||||
|
||||
from ..core.utils import accepts_kwarg
|
||||
from .exceptions import EmbedUnsupportedProviderException
|
||||
from .finders import get_finders
|
||||
from .models import Embed
|
||||
|
||||
|
||||
def get_embed(url, max_width=None, finder=None):
|
||||
embed_hash = get_embed_hash(url, max_width)
|
||||
def get_embed(url, max_width=None, max_height=None, finder=None):
|
||||
embed_hash = get_embed_hash(url, max_width, max_height)
|
||||
|
||||
# Check database
|
||||
try:
|
||||
|
@ -20,14 +21,17 @@ def get_embed(url, max_width=None, finder=None):
|
|||
# Get/Call finder
|
||||
if not finder:
|
||||
|
||||
def finder(url, max_width=None):
|
||||
def finder(url, max_width=None, max_height=None):
|
||||
for finder in get_finders():
|
||||
if finder.accept(url):
|
||||
return finder.find_embed(url, max_width=max_width)
|
||||
kwargs = {}
|
||||
if accepts_kwarg(finder.find_embed, 'max_height'):
|
||||
kwargs['max_height'] = max_height
|
||||
return finder.find_embed(url, max_width=max_width, **kwargs)
|
||||
|
||||
raise EmbedUnsupportedProviderException
|
||||
|
||||
embed_dict = finder(url, max_width)
|
||||
embed_dict = finder(url, max_width, max_height)
|
||||
|
||||
# Make sure width and height are valid integers before inserting into database
|
||||
try:
|
||||
|
@ -65,10 +69,13 @@ def get_embed(url, max_width=None, finder=None):
|
|||
return embed
|
||||
|
||||
|
||||
def get_embed_hash(url, max_width=None):
|
||||
def get_embed_hash(url, max_width=None, max_height=None):
|
||||
h = md5()
|
||||
h.update(url.encode("utf-8"))
|
||||
if max_width is not None:
|
||||
h.update(b"\n")
|
||||
h.update(str(max_width).encode("utf-8"))
|
||||
if max_height is not None:
|
||||
h.update(b"\n")
|
||||
h.update(str(max_height).encode("utf-8"))
|
||||
return h.hexdigest()
|
||||
|
|
|
@ -45,7 +45,7 @@ class OEmbedFinder(EmbedFinder):
|
|||
def accept(self, url):
|
||||
return self._get_endpoint(url) is not None
|
||||
|
||||
def find_embed(self, url, max_width=None):
|
||||
def find_embed(self, url, max_width=None, max_height=None):
|
||||
# Find provider
|
||||
endpoint = self._get_endpoint(url)
|
||||
if endpoint is None:
|
||||
|
@ -57,6 +57,8 @@ class OEmbedFinder(EmbedFinder):
|
|||
params['format'] = 'json'
|
||||
if max_width:
|
||||
params['maxwidth'] = max_width
|
||||
if max_height:
|
||||
params['maxheight'] = max_height
|
||||
|
||||
# Perform request
|
||||
request = Request(endpoint + '?' + urlencode(params))
|
||||
|
|
|
@ -4,9 +4,9 @@ from wagtail.embeds import embeds
|
|||
from wagtail.embeds.exceptions import EmbedException
|
||||
|
||||
|
||||
def embed_to_frontend_html(url):
|
||||
def embed_to_frontend_html(url, max_width=None, max_height=None):
|
||||
try:
|
||||
embed = embeds.get_embed(url)
|
||||
embed = embeds.get_embed(url, max_width, max_height)
|
||||
|
||||
# Render template
|
||||
return render_to_string('wagtailembeds/embed_frontend.html', {
|
||||
|
|
|
@ -122,7 +122,7 @@ class TestEmbeds(TestCase):
|
|||
def setUp(self):
|
||||
self.hit_count = 0
|
||||
|
||||
def dummy_finder(self, url, max_width=None):
|
||||
def dummy_finder(self, url, max_width=None, max_height=None):
|
||||
# Up hit count
|
||||
self.hit_count += 1
|
||||
|
||||
|
@ -175,7 +175,7 @@ class TestEmbeds(TestCase):
|
|||
self.assertFalse(embed.is_responsive)
|
||||
self.assertIsNone(embed.cache_until)
|
||||
|
||||
def dummy_cache_until_finder(self, url, max_width=None):
|
||||
def dummy_cache_until_finder(self, url, max_width=None, max_height=None):
|
||||
# Up hit count
|
||||
self.hit_count += 1
|
||||
|
||||
|
@ -210,7 +210,7 @@ class TestEmbeds(TestCase):
|
|||
self.assertEqual(embed, embed_3)
|
||||
self.assertEqual(embed_3.cache_until, future_dt)
|
||||
|
||||
def dummy_finder_invalid_width(self, url, max_width=None):
|
||||
def dummy_finder_invalid_width(self, url, max_width=None, max_height=None):
|
||||
# Return a record with an invalid width
|
||||
return {
|
||||
'title': "Test: " + url,
|
||||
|
@ -228,7 +228,7 @@ class TestEmbeds(TestCase):
|
|||
self.assertEqual(embed.width, None)
|
||||
|
||||
def test_no_html(self):
|
||||
def no_html_finder(url, max_width=None):
|
||||
def no_html_finder(url, max_width=None, max_height=None):
|
||||
"""
|
||||
A finder which returns everything but HTML
|
||||
"""
|
||||
|
@ -710,7 +710,7 @@ class TestEmbedBlock(TestCase):
|
|||
self.assertIn('<h1>Hello world!</h1>', result)
|
||||
|
||||
# Check that get_embed was called correctly
|
||||
get_embed.assert_any_call('http://www.example.com/foo')
|
||||
get_embed.assert_any_call('http://www.example.com/foo', None, None)
|
||||
|
||||
@patch('wagtail.embeds.embeds.get_embed')
|
||||
def test_render_within_structblock(self, get_embed):
|
||||
|
@ -735,7 +735,7 @@ class TestEmbedBlock(TestCase):
|
|||
self.assertIn('<h1>Hello world!</h1>', result)
|
||||
|
||||
# Check that get_embed was called correctly
|
||||
get_embed.assert_any_call('http://www.example.com/foo')
|
||||
get_embed.assert_any_call('http://www.example.com/foo', None, None)
|
||||
|
||||
def test_value_from_form(self):
|
||||
"""
|
||||
|
|
|
@ -129,4 +129,4 @@ class TestFrontendMediaEmbedHandler(TestCase):
|
|||
|
||||
result = expand_db_html('<p>1 2 <embed embedtype="media" url="https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25" /> 3 4</p>')
|
||||
self.assertIn('test html', result)
|
||||
get_embed.assert_called_with('https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25')
|
||||
get_embed.assert_called_with('https://www.youtube.com/watch?v=O7D-1RG-VRk&t=25', None, None)
|
||||
|
|
Ładowanie…
Reference in New Issue