Added 'picture' TALES extension
authorThierry Florac <thierry.florac@onf.fr>
Mon, 16 Jul 2018 12:14:21 +0200
changeset 122 e6e53cb1785c
parent 121 31c780a74151
child 123 01eb2fba1632
Added 'picture' TALES extension
src/pyams_file/image.py
src/pyams_file/templates/picture.pt
--- a/src/pyams_file/image.py	Thu Jul 12 18:18:29 2018 +0200
+++ b/src/pyams_file/image.py	Mon Jul 16 12:14:21 2018 +0200
@@ -9,6 +9,7 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
+from pyramid.renderers import render
 
 __docformat__ = 'restructuredtext'
 
@@ -21,10 +22,11 @@
 
 # import interfaces
 from pyams_file.interfaces import IImage, IThumbnailer, IThumbnailGeometry, IThumbnails, IResponsiveImage
+from pyams_utils.interfaces.tales import ITALESExtension
 
 # import packages
-from pyams_utils.adapter import ContextAdapter, adapter_config
-from zope.interface import implementer
+from pyams_utils.adapter import adapter_config, ContextAdapter, ContextRequestViewAdapter
+from zope.interface import implementer, Interface
 from zope.schema.fieldproperty import FieldProperty
 
 from pyams_file import _
@@ -245,3 +247,35 @@
 
     label = _("Large screen thumbnail")
     weight = 13
+
+
+#
+# Responsive 'picture' TALES extension
+#
+
+@adapter_config(name='picture',
+                context=(Interface, Interface, Interface),
+                provides=ITALESExtension)
+class PictureTALESExtension(ContextRequestViewAdapter):
+    """Picture TALES adapter
+
+    This TALES adapter can be used to automatically create a 'picture' HTML tag
+    embedding all image attributes.
+    """
+
+    def render(self, context=None, lg_thumb='lg', lg_width=12, md_thumb='md', md_width=12,
+               sm_thumb='sm', sm_width=12, xs_thumb='xs', xs_width=12, css_class=''):
+        if context is None:
+            context = self.context
+        return render('templates/picture.pt',
+                      {'image': context,
+                       'lg_thumb': lg_thumb,
+                       'lg_width': lg_width,
+                       'md_thumb': md_thumb,
+                       'md_width': md_width,
+                       'sm_thumb': sm_thumb,
+                       'sm_width': sm_width,
+                       'xs_thumb': xs_thumb,
+                       'xs_width': xs_width,
+                       'css_class': css_class},
+                      request=self.request)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_file/templates/picture.pt	Mon Jul 16 12:14:21 2018 +0200
@@ -0,0 +1,53 @@
+<picture
+	tal:define="image_url tales:absolute_url(image);
+				timestamp tales:timestamp(image);
+				base_width 100 / 12;"
+	tal:attributes="class css_class">
+	<!-- lg source -->
+	<source media="(min-width: 1200px)"
+			tal:condition="lg_width"
+			tal:attributes="srcset string:${image_url}/++thumb++${lg_thumb}:w1200?_=${timestamp} 1200w,
+										  ${image_url}/++thumb++${lg_thumb}:w512?_=${timestamp} 512w,
+										  ${image_url}/++thumb++${lg_thumb}:w256?_=${timestamp} 256w,
+										  ${image_url}/++thumb++${lg_thumb}:w128?_=${timestamp} 128w;
+							sizes string:${round(base_width * lg_width)}vw" />
+	<source media="(min-width: 1200px)"
+			srcset="/--static--/pyams_skin/img/dot.png" sizes="100vw"
+			tal:condition="not:lg_width" />
+	<!-- md source -->
+	<source media="(min-width: 992px)"
+			tal:condition="md_width"
+			tal:attributes="srcset string:${image_url}/++thumb++${md_thumb}:w992?_=${timestamp} 992w,
+										  ${image_url}/++thumb++${md_thumb}:w512?_=${timestamp} 512w,
+										  ${image_url}/++thumb++${md_thumb}:w256?_=${timestamp} 256w,
+										  ${image_url}/++thumb++${md_thumb}:w128?_=${timestamp} 128w;
+							sizes string:${round(base_width * md_width)}vw" />
+	<source media="(min-width: 992px)"
+			srcset="/--static--/pyams_skin/img/dot.png" sizes="100vw"
+			tal:condition="not:md_width" />
+	<!-- sm source -->
+	<source media="(min-width: 768px)"
+			tal:condition="sm_width"
+			tal:attributes="srcset string:${image_url}/++thumb++${sm_thumb}:w768?_=${timestamp} 768w,
+										  ${image_url}/++thumb++${sm_thumb}:w512?_=${timestamp} 512w,
+										  ${image_url}/++thumb++${sm_thumb}:w256?_=${timestamp} 256w,
+										  ${image_url}/++thumb++${sm_thumb}:w128?_=${timestamp} 128w;
+							sizes string:${round(base_width * sm_width)}vw" />
+	<source media="(min-width: 768px)"
+			srcset="/--static--/pyams_skin/img/dot.png" sizes="100vw"
+			tal:condition="not:sm_width" />
+	<!-- xs source -->
+	<source media="(max-width: 767px)"
+			tal:condition="xs_width"
+			tal:attributes="srcset string:${image_url}/++thumb++${xs_thumb}:w768?_=${timestamp} 768w,
+										  ${image_url}/++thumb++${xs_thumb}:w512?_=${timestamp} 512w,
+										  ${image_url}/++thumb++${xs_thumb}:w256?_=${timestamp} 256w,
+										  ${image_url}/++thumb++${xs_thumb}:w128?_=${timestamp} 128w;
+							sizes string:${round(base_width * xs_width)}vw" />
+	<source media="(max-width: 767px)"
+			srcset="/--static--/pyams_skin/img/dot.png" sizes="100vw"
+			tal:condition="not:xs_width" />
+	<!-- fallback image -->
+	<img style="width: 100%;"
+		 tal:attributes="src image_url" />
+</picture>