Browse Source

Use WebP for images (#513)

See new `images.rst` doc.

All images are now served in webp format, and use more consistent sizes:
* 1600x900 for cropped images.
* 800x450 for small cropped images.
* 256x256 for small square images (e.g. blurbs)
Vince Salvino 2 years ago
parent
commit
de3a82c7ee
27 changed files with 89 additions and 27 deletions
  1. 1 1
      coderedcms/templates/coderedcms/blocks/article_block_card.html
  2. 1 1
      coderedcms/templates/coderedcms/blocks/base_link_block.html
  3. 1 1
      coderedcms/templates/coderedcms/blocks/card_block.html
  4. 1 1
      coderedcms/templates/coderedcms/blocks/card_blurb.html
  5. 1 1
      coderedcms/templates/coderedcms/blocks/card_foot.html
  6. 1 1
      coderedcms/templates/coderedcms/blocks/card_head.html
  7. 1 1
      coderedcms/templates/coderedcms/blocks/card_head_foot.html
  8. 1 1
      coderedcms/templates/coderedcms/blocks/card_img.html
  9. 1 1
      coderedcms/templates/coderedcms/blocks/carousel_block.html
  10. 1 1
      coderedcms/templates/coderedcms/blocks/hero_block.html
  11. 1 1
      coderedcms/templates/coderedcms/blocks/image_block.html
  12. 2 2
      coderedcms/templates/coderedcms/blocks/image_gallery_block.html
  13. 1 1
      coderedcms/templates/coderedcms/blocks/image_link_block.html
  14. 1 1
      coderedcms/templates/coderedcms/blocks/pagelist_article_media.html
  15. 1 1
      coderedcms/templates/coderedcms/blocks/pagepreview_card.html
  16. 1 1
      coderedcms/templates/coderedcms/blocks/pricelistitem_block.html
  17. 1 1
      coderedcms/templates/coderedcms/pages/article_index_page.html
  18. 1 1
      coderedcms/templates/coderedcms/pages/article_page.html
  19. 4 2
      coderedcms/templates/coderedcms/pages/article_page.search.html
  20. 2 1
      coderedcms/templates/coderedcms/pages/base.html
  21. 1 1
      coderedcms/templates/coderedcms/pages/event_index_page.html
  22. 1 1
      coderedcms/templates/coderedcms/pages/web_page.html
  23. 1 1
      coderedcms/templates/coderedcms/snippets/navbar.html
  24. 1 1
      coderedcms/templates/wagtailadmin/base.html
  25. 3 1
      coderedcms/views.py
  26. 56 0
      docs/how_to/images.rst
  27. 1 0
      docs/how_to/index.rst

+ 1 - 1
coderedcms/templates/coderedcms/blocks/article_block_card.html

@@ -1,7 +1,7 @@
 {% load wagtailimages_tags %}
 <div class="card mb-3">
   {% if article.cover_image %}
-  {% image article.cover_image fill-900x600 as cover_image %}
+  {% image article.cover_image fill-800x450 format-webp as cover_image %}
   <a href="{{article.url}}" title="{{article.title}}"><img class="card-img-top" src="{{cover_image.url}}" alt="{{cover_image.title}}"></a>
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/base_link_block.html

@@ -10,7 +10,7 @@
     {% if ga_event_label %}data-ga-event-label="{{ ga_event_label }}"{% endif %}
     {% if ga_event_category %}data-ga-event-category="{{ ga_event_category }}"{% endif %}>
     {% if value.image %}
-    {% image value.image max-200x200 as img %}
+    {% image value.image max-256x256 format-webp as img %}
     <img src="{{img.url}}" class="w-100" alt="{{img.image.title}}" />
     {% elif value.display_text %}
     {{value.display_text|safe}}

+ 1 - 1
coderedcms/templates/coderedcms/blocks/card_block.html

@@ -1,7 +1,7 @@
 {% load wagtailcore_tags wagtailimages_tags %}
 <div class="card mb-3 {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>
   {% if self.image %}
-  {% image self.image fill-900x600 as card_img %}
+  {% image self.image fill-800x450 format-webp as card_img %}
   <img class="card-img-top w-100" src="{{card_img.url}}" alt="{{card_img.title}}">
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/card_blurb.html

@@ -1,7 +1,7 @@
 {% load wagtailcore_tags wagtailimages_tags %}
 <div class="card mb-3 border-0 bg-transparent text-center {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>
   {% if self.image %}
-  {% image self.image fill-150x150 as card_img %}
+  {% image self.image fill-256x256 format-webp as card_img %}
   <img class="rounded-circle w-25 mx-auto" src="{{card_img.url}}" alt="{{card_img.title}}">
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/card_foot.html

@@ -1,7 +1,7 @@
 {% load wagtailcore_tags wagtailimages_tags %}
 <div class="card mb-3 {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>
   {% if self.image %}
-  {% image self.image fill-900x600 as card_img %}
+  {% image self.image fill-800x450 format-webp as card_img %}
   <img class="card-img-top w-100" src="{{card_img.url}}" alt="{{card_img.title}}">
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/card_head.html

@@ -2,7 +2,7 @@
 <div class="card mb-3 {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>
   {% if self.title %}<h5 class="card-header">{{self.title}}</h5>{% endif %}
   {% if self.image %}
-  {% image self.image fill-900x600 as card_img %}
+  {% image self.image fill-800x450 format-webp as card_img %}
   <img class="w-100" src="{{card_img.url}}" alt="{{card_img.title}}">
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/card_head_foot.html

@@ -2,7 +2,7 @@
 <div class="card mb-3 {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>
   {% if self.title %}<h5 class="card-header">{{self.title}}</h5>{% endif %}
   {% if self.image %}
-  {% image self.image fill-900x600 as card_img %}
+  {% image self.image fill-800x450 format-webp as card_img %}
   <img class="w-100" src="{{card_img.url}}" alt="{{card_img.title}}">
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/card_img.html

@@ -1,7 +1,7 @@
 {% load wagtailcore_tags wagtailimages_tags %}
 
 <div class="card mb-3 bg-dark text-white {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}
-  {% if self.image %}{% image self.image fill-1000x1000 as card_img %}style="background-image:url('{{card_img.url}}');"{% endif %}>
+  {% if self.image %}{% image self.image fill-800x450 format-webp as card_img %}style="background-image:url('{{card_img.url}}');"{% endif %}>
   <div class="card-body">
     {% if self.title %}<h5 class="card-title">{{self.title}}</h5>{% endif %}
     {% if self.subtitle %}<h6 class="card-subtitle mb-2 text-muted">{{self.subtitle}}</h6>{% endif %}

+ 1 - 1
coderedcms/templates/coderedcms/blocks/carousel_block.html

@@ -18,7 +18,7 @@
       style="{% if item.background_color %}background-color: {{item.background_color}};{% endif %}">
       {% block carousel_slide_image %}
       {% if item.image %}
-      {% image item.image fill-2000x1000 as carouselimage %}
+      {% image item.image fill-1600x900 format-webp as carouselimage %}
       <img class="d-block w-100" src="{{carouselimage.url}}" alt="{{carouselimage.image.title}}" />
       {% endif %}
       {% endblock %}

+ 1 - 1
coderedcms/templates/coderedcms/blocks/hero_block.html

@@ -2,7 +2,7 @@
 {% if not self.fluid %}
 <div class="container">
 {% endif %}
-{% image self.background_image max-2000x2000 as background_image %}
+{% image self.background_image max-1600x1600 format-webp as background_image %}
 <div class="hero-bg {% if self.is_parallax %}parallax{% endif %} {% if self.tile_image %}tile{% endif %} {{self.settings.custom_css_class}}"
   style="{% if self.background_color %}background-color:{{self.background_color}};{% endif %}{% if background_image %}background-image:url({{background_image.url}});{% endif %}"
   {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>

+ 1 - 1
coderedcms/templates/coderedcms/blocks/image_block.html

@@ -1,3 +1,3 @@
 {% load wagtailimages_tags %}
-{% image self.image max-2000x2000 as self_image %}
+{% image self.image max-1600x1600 format-webp as self_image %}
 <img src="{{self_image.url}}" class="img-fluid {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %} alt="{{self_image.image.title}}">

+ 2 - 2
coderedcms/templates/coderedcms/blocks/image_gallery_block.html

@@ -4,8 +4,8 @@
 <section class="{{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{%endif %}>
   <div class="row">
     {% for picture in pictures %}
-    {% image picture fill-900x600 as picture_image %}
-    {% image picture original as original_image %}
+    {% image picture fill-800x450 format-webp as picture_image %}
+    {% image picture max-1600x1600 format-webp as original_image %}
     <div class="col-sm-6 col-md-4 col-lg-3 my-3">
       <a href="#" class="lightbox-preview" data-bs-toggle="modal" data-bs-target="#modal-{{modal_id}}">
         <img class="img-thumbnail w-100" src="{{picture_image.url}}" data-original-src="{{original_image.url}}"

+ 1 - 1
coderedcms/templates/coderedcms/blocks/image_link_block.html

@@ -5,6 +5,6 @@
   data-ga-event-label='{{self.settings.ga_tracking_event_label|default:self.alt_text}}'
   {% endif %}
   title="{{ self.alt_text|safe }}" {% if self.settings.custom_id %}id="{{ self.settings.custom_id }}"{% endif %}>
-  {% image self.image max-2000x2000 as self_image %}
+  {% image self.image max-1600x1600 format-webp as self_image %}
   <img src="{{self_image.url}}" class="img-fluid {{self.settings.custom_css_class}}" alt="{{self.alt_text|safe}}">
 </a>

+ 1 - 1
coderedcms/templates/coderedcms/blocks/pagelist_article_media.html

@@ -6,7 +6,7 @@
 <div class="d-flex">
   {% if article.cover_image %}
   <div class="flex-shrink-0">
-    {% image article.cover_image fill-150x100 as cover_image %}
+    {% image article.cover_image fill-800x450 format-webp as cover_image %}
     <a href="{{article.url}}"><img class="me-3" src="{{cover_image.url}}" alt="{{cover_image.title}}"></a>
   </div>
   {% endif %}

+ 1 - 1
coderedcms/templates/coderedcms/blocks/pagepreview_card.html

@@ -2,7 +2,7 @@
 <div class="card mb-3 {{self.settings.custom_css_class}}" {% if self.settings.custom_id %}id="{{self.settings.custom_id}}"{% endif %}>
   {% with page=self.page.specific %}
   {% if page.cover_image %}
-  {% image page.cover_image fill-900x600 as card_img %}
+  {% image page.cover_image fill-800x450 format-webp as card_img %}
   <img class="card-img-top w-100" src="{{card_img.url}}" alt="{{card_img.title}}">
   {% endif %}
   <div class="card-body">

+ 1 - 1
coderedcms/templates/coderedcms/blocks/pricelistitem_block.html

@@ -2,7 +2,7 @@
 <div class="row">
   {% if self.image %}
   <div class="col-md-4">
-    {% image self.image original as imagedata %}
+    {% image self.image max-1600x1600 format-webp as imagedata %}
     <img src="{{imagedata.url}}" alt="Photo of {{self.name}}" class="w-100">
   </div>
   <div class="col-md-8" style="overflow-x: hidden;">

+ 1 - 1
coderedcms/templates/coderedcms/pages/article_index_page.html

@@ -10,7 +10,7 @@
       {% if self.show_images %}
       <a href="{% pageurl article %}" title="{{article.title}}" class="text-white-50">
         {% if article.cover_image %}
-        {% image article.specific.cover_image fill-1000x500 as cover_image %}
+        {% image article.specific.cover_image fill-1600x900 format-webp as cover_image %}
         <img src="{{cover_image.url}}" class="w-100" alt="{{article.title}}" />
         {% endif %}
       </a>

+ 1 - 1
coderedcms/templates/coderedcms/pages/article_page.html

@@ -25,7 +25,7 @@
   {% block article_cover_image %}
   {% if self.cover_image %}
   <div class="container mb-5">
-    {% image self.cover_image fill-2000x1000 as cover_image %}
+    {% image self.cover_image fill-1600x900 format-webp as cover_image %}
     <img src="{{cover_image.url}}" class="w-100" />
   </div>
   {% endif %}

+ 4 - 2
coderedcms/templates/coderedcms/pages/article_page.search.html

@@ -1,9 +1,11 @@
 {% load wagtailimages_tags %}
 <div class="row">
   {% if page.cover_image %}
-  {% image page.cover_image fill-500x500 as cover_image %}
+  {% image page.cover_image fill-800x450 format-webp as cover_image %}
   <div class="col-4 col-md-3 col-lg-2">
-    <a href="{{page.url}}" title="{{page.title}}"><img src="{{cover_image.url}}" class="w-100" alt="{{page.title}}"></a>
+    <a href="{{page.url}}" title="{{page.title}}">
+      <img src="{{cover_image.url}}" class="w-100" alt="{{page.title}}">
+    </a>
   </div>
   {% endif %}
   <div class="col">

+ 2 - 1
coderedcms/templates/coderedcms/pages/base.html

@@ -78,11 +78,12 @@
   {% block favicon %}
   {% if settings.coderedcms.LayoutSettings.favicon %}
   {# See https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/ #}
+  {% image settings.coderedcms.LayoutSettings.favicon fill-256x256 format-webp as favicon_webp %}
   {% image settings.coderedcms.LayoutSettings.favicon fill-120x120 format-png as favicon_iphone %}
   {% image settings.coderedcms.LayoutSettings.favicon fill-180x180 format-png as favicon_iphone_plus %}
   {% image settings.coderedcms.LayoutSettings.favicon fill-152x152 format-png as favicon_ipad %}
   {% image settings.coderedcms.LayoutSettings.favicon fill-167x167 format-png as favicon_ipad_pro %}
-  <link rel="icon" type="image/png" href="{{ favicon_iphone_plus.url }}" />
+  <link rel="icon" type="image/webp" href="{{ favicon_webp.url }}" />
   <link rel="apple-touch-icon" href="{{ favicon_iphone_plus.url }}">
   <link rel="apple-touch-icon" sizes="120x120" href="{{ favicon_iphone.url }}">
   <link rel="apple-touch-icon" sizes="180x180" href="{{ favicon_iphone_plus.url }}">

+ 1 - 1
coderedcms/templates/coderedcms/pages/event_index_page.html

@@ -23,7 +23,7 @@
     {% block event_cover_image %}
     {% if event.cover_image %}
     <div class="col-md">
-      {% image event.cover_image fill-1000x500 as cover_image %}
+      {% image event.cover_image fill-1600x900 format-webp as cover_image %}
       <a href="{{ event.url }}" title="{{ event.title }}"><img src="{{ cover_image.url }}" class="w-100" alt="{{ event.title }}" /></a>
     </div>
     {% endif %}

+ 1 - 1
coderedcms/templates/coderedcms/pages/web_page.html

@@ -3,7 +3,7 @@
 
 {% block content_pre_body %}
 {% if self.cover_image %}
-{% image page.cover_image fill-2000x1000 as cover_image %}
+{% image page.cover_image fill-1600x900 format-webp as cover_image %}
 <div class="hero-bg mb-5" style="background-image:url({{cover_image.url}});">
   <div class="hero-fg">
     <div class="container">

+ 1 - 1
coderedcms/templates/coderedcms/snippets/navbar.html

@@ -4,7 +4,7 @@
   <div class="container{% if settings.coderedcms.LayoutSettings.navbar_content_fluid %}-fluid{% endif %}">
     <a class="navbar-brand" href="/">
       {% if settings.coderedcms.LayoutSettings.logo %}
-      {% image settings.coderedcms.LayoutSettings.logo original as logo %}
+      {% image settings.coderedcms.LayoutSettings.logo original format-webp as logo %}
       <img src="{{logo.url}}" alt="{{site.site_name}}" />
       {% else %}
       {{site.site_name}}

+ 1 - 1
coderedcms/templates/wagtailadmin/base.html

@@ -8,4 +8,4 @@
 
 {# NOTE: this must be on a single line, otherwise Django templates will create
   whitespace, and wagtail will think the whitespace is the custom logo! #}
-{% block branding_logo %}{% if settings.coderedcms.LayoutSettings.logo %}<div class="crx-logo-container {{settings.coderedcms.LayoutSettings.navbar_color_scheme}}">{% image settings.coderedcms.LayoutSettings.logo max-300x300 as logo_image %}<img src="{{ logo_image.url }}" class="crx-logo-custom" alt="Dashboard"/></div>{% endif %}{% endblock %}
+{% block branding_logo %}{% if settings.coderedcms.LayoutSettings.logo %}<div class="crx-logo-container {{settings.coderedcms.LayoutSettings.navbar_color_scheme}}">{% image settings.coderedcms.LayoutSettings.logo original format-webp as logo_image %}<img src="{{ logo_image.url }}" class="crx-logo-custom" alt="Dashboard"/></div>{% endif %}{% endblock %}

+ 3 - 1
coderedcms/views.py

@@ -120,7 +120,9 @@ def serve_protected_file(request, path):
 def favicon(request):
     icon = LayoutSettings.for_request(request).favicon
     if icon:
-        return HttpResponsePermanentRedirect(icon.get_rendition("original").url)
+        return HttpResponsePermanentRedirect(
+            icon.get_rendition("fill-256x256|format-webp").url
+        )
     raise Http404()
 
 

+ 56 - 0
docs/how_to/images.rst

@@ -0,0 +1,56 @@
+Best Practices for Images
+=========================
+
+
+For Editors
+-----------
+
+**Logo** and **Favicon**: Upload your logo and favicon under **Settings >
+Layout** using high resolution PNG (or WebP) files. Any size or resolution is
+acceptable. Note that the Favicon will be cropped to a square (1:1) aspect
+ratio.
+
+**Cover Images**: Cover images added to Web Pages, Article Pages, Event Pages,
+etc. will all be scaled to a **16:9 aspect ratio** with a maximum resolution of
+**1600x900 pixels**. Generally these should be uploaded in JPG (or WebP) format.
+Any resolution is fine, but common resolutions such as 1280x720, 1600x900, etc.
+are most appropriate. Avoid uploading huge "raw" image files (e.g. images
+greater than 1 MB in file size).
+
+**Image Blocks**: Images added in the page body (via the Image or Image Link
+blocks) will keep their original aspect ratio preserved, but will be scaled to a
+maximum width or height of 1600 pixels. Any aspect ratio or image resolution is
+acceptable.
+
+
+For Developers
+--------------
+
+.. versionadded:: 1.0
+
+   Images are served in WebP format.
+
+As of version 1.0, all images are served in WebP format. WebP format provides
+the benefit of significantly smaller file sizes and results in an overall faster
+website with better SEO performance. All mainstream browsers released after 2020
+include WebP support. The following browsers and/or operating systems *do not*
+support WebP, but might still be in use:
+
+* Internet Explorer
+* Safari on macOS 10 or older
+* iOS 13 or older
+* Consult the `full list of WebP browser support <https://caniuse.com/webp>`_
+
+If your website needs to support these systems, we recommend having Wagtail
+substitute WebP for JPG with the following setting in your Django settings file:
+
+.. code-block:: python
+
+   WAGTAILIMAGES_FORMAT_CONVERSIONS = {
+       "webp": "jpeg",
+    }
+
+If you would like to support both WebP and alternative fallback image formats,
+you may need to override the default CRX templates to use the `picture element
+as described in the Wagtail docs
+<https://docs.wagtail.org/en/stable/advanced_topics/images/image_file_formats.html>`_.

+ 1 - 0
docs/how_to/index.rst

@@ -8,6 +8,7 @@ website with Wagtail CRX.
 .. toctree::
     :maxdepth: 1
 
+    images
     headers_and_footers
     add_tracking_scripts
     link_targets