Skip to content

Commit affa538

Browse files
committed
set sizes for picture-tags, fixes #179
1 parent 104815e commit affa538

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

news/178.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
set sizes attribute on picture-tags [MrTango]

plone/namedfile/picture.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ def get_scale_width(self, scale):
4747
return scale_info[0]
4848

4949
def create_picture_tag(
50-
self, sourceset, attributes, uid=None, fieldname=None, resolve_urls=False
50+
self, sourceset, attributes, uid=None, fieldname=None, resolve_urls=False, sizes=None
5151
):
5252
"""Converts the img tag to a picture tag with picture_variant definition"""
5353
width = None
5454
height = None
55+
target_width = None
56+
sizes = sizes or ""
5557
src = attributes.get("src")
5658
if not uid and not src:
5759
raise TypeError("Either uid or attributes['src'] need to be given.")
@@ -68,6 +70,7 @@ def create_picture_tag(
6870
for i, source in enumerate(sourceset):
6971
target_scale = source["scale"]
7072
media = source.get("media")
73+
sizes = source.get("sizes")
7174

7275
additional_scales = source.get("additionalScales", None)
7376
if additional_scales is None:
@@ -78,6 +81,8 @@ def create_picture_tag(
7881
source_srcset = []
7982
for scale in source_scales:
8083
scale_width = self.get_scale_width(scale)
84+
if scale == target_scale:
85+
target_width = scale_width
8186
if not scale_width:
8287
logger.warning("No width found for scale %s.", scale)
8388
continue
@@ -92,7 +97,9 @@ def create_picture_tag(
9297
# scale_url = scale_obj.url
9398
scale_url = self.update_src_scale(src=src, scale=scale)
9499
source_srcset.append(f"{scale_url} {scale_width}w")
95-
source_tag = soup.new_tag("source", srcset=",\n".join(source_srcset))
100+
if not sizes:
101+
sizes = f"(min-width: 576px) {target_width}px, 98vw"
102+
source_tag = soup.new_tag("source", srcset=",\n".join(source_srcset), sizes=sizes)
96103
if media:
97104
source_tag["media"] = media
98105
picture_tag.append(source_tag)

plone/namedfile/tests/test_scaling.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ def patch_Img2PictureTag_picture_variants():
8888
"sourceset": [
8989
{
9090
"scale": "preview",
91-
"additionalScales": ["preview", "large", "larger"],
91+
"additionalScales": ["large", "larger"],
92+
"sizes": "(min-width: 576px) 350px, (min-width: 768px) 600px, 98vw",
9293
}
9394
],
9495
},
@@ -538,22 +539,55 @@ def testGetPictureTagByName(self, mock_uuid_to_object):
538539
mock_uuid_to_object.return_value = self.item
539540
tag = self.scaling.picture("image", picture_variant="medium")
540541
expected = """<picture>
541-
<source srcset="http://nohost/item/@@images/image-600-....png 600w,
542+
<source...srcset="http://nohost/item/@@images/image-600-....png 600w,
542543
http://nohost/item/@@images/image-400-....png 400w,
543544
http://nohost/item/@@images/image-800-....png 800w,
544545
http://nohost/item/@@images/image-1000-....png 1000w,
545-
http://nohost/item/@@images/image-1200-....png 1200w"/>
546+
http://nohost/item/@@images/image-1200-....png 1200w".../>
546547
<img...src="http://nohost/item/@@images/image-600-....png".../>
547548
</picture>"""
548549
self.assertTrue(_ellipsis_match(expected, tag.strip()))
550+
# The exact placement of the img tag attributes can differ, especially
551+
# with different beautifulsoup versions.
552+
# So check here that all attributes are present.
553+
self.assertIn('height="200"', tag)
554+
self.assertIn('loading="lazy"', tag)
555+
self.assertIn('title="foo"', tag)
556+
self.assertIn('width="200"', tag)
557+
self.assertIn('sizes="(min-width: 576px) 600px, 98vw"', tag)
549558

559+
@patch.object(
560+
plone.namedfile.scaling,
561+
"get_picture_variants",
562+
new=patch_Img2PictureTag_picture_variants,
563+
spec=True,
564+
)
565+
@patch.object(
566+
plone.namedfile.picture,
567+
"get_allowed_scales",
568+
new=patch_Img2PictureTag_allowed_scales,
569+
spec=True,
570+
)
571+
@patch.object(plone.namedfile.picture, "uuidToObject", spec=True)
572+
def testGetPictureTagCustomSizes(self, mock_uuid_to_object):
573+
ImageScaling._sizes = patch_Img2PictureTag_allowed_scales()
574+
mock_uuid_to_object.return_value = self.item
575+
tag = self.scaling.picture("image", picture_variant="small")
576+
expected = """<picture>
577+
<source...srcset="http://nohost/item/@@images/image-400-....png 400w,
578+
http://nohost/item/@@images/image-800-....png 800w,
579+
http://nohost/item/@@images/image-1000-....png 1000w".../>
580+
<img...src="http://nohost/item/@@images/image-400-....png".../>
581+
</picture>"""
582+
self.assertTrue(_ellipsis_match(expected, tag.strip()))
550583
# The exact placement of the img tag attributes can differ, especially
551584
# with different beautifulsoup versions.
552585
# So check here that all attributes are present.
553586
self.assertIn('height="200"', tag)
554587
self.assertIn('loading="lazy"', tag)
555588
self.assertIn('title="foo"', tag)
556589
self.assertIn('width="200"', tag)
590+
self.assertIn('sizes="(min-width: 576px) 350px, (min-width: 768px) 600px, 98vw"', tag)
557591

558592
@patch.object(
559593
plone.namedfile.scaling,
@@ -579,11 +613,11 @@ def testGetPictureTagWithAltAndTitle(self, mock_uuid_to_object):
579613
)
580614
base = self.item.absolute_url()
581615
expected = f"""<picture>
582-
<source srcset="{base}/@@images/image-600-....png 600w,
616+
<source...srcset="{base}/@@images/image-600-....png 600w,
583617
{base}/@@images/image-400-....png 400w,
584618
{base}/@@images/image-800-....png 800w,
585619
{base}/@@images/image-1000-....png 1000w,
586-
{base}/@@images/image-1200-....png 1200w"/>
620+
{base}/@@images/image-1200-....png 1200w".../>
587621
<img...src="{base}/@@images/image-600-....png".../>
588622
</picture>"""
589623
self.assertTrue(_ellipsis_match(expected, tag.strip()))

0 commit comments

Comments
 (0)