Code Monkey home page Code Monkey logo

canonicalwebteam.image-template's Introduction

canonicalwebteam.image-template

PyPI Tests Code coverage

A module to generate performant HTML image markup for images. The markup will:

  • Use native lazyloading if it's available
  • Output markup compatible with lazysizes noscript plugin
  • Explicitly define width and height attributes to avoid the page jumping effect
  • Prefix all image URLs with cloudinary CDN proxy URLs, to transform the image to the optimal size
  • Use predefined (2x) srcset break points for hidef screens

Parameters

  • url (mandatory string): The url to an image (e.g. https://assets.ubuntu.com/v1/9f6916dd-k8s-prometheus-light.png)
  • alt (mandatory string): Alt text to describe the image
  • hi_def (mandatory boolean): Has an image been uploaded 2x the width and height of the desired size
  • width (mandatory integer): The number of pixels wide the image should be
  • height (optional integer): The number of pixels high the image should be
  • fill (optional boolean): Set the crop mode to "fill"
  • loading (optional string, default: "lazy"): Set to "auto" or "eager" to disable lazyloading
  • attrs (optional dictionary): Extra <img> attributes (e.g. class or id) can be passed as additional arguments

Usage

Local development

For local development, it's best to test this module with one of our website projects like ubuntu.com. For more information, follow this guide (internal only).

Application code

The image_template function can be used directly to generate image Markup.

from canonicalwebteam import image_template

image_markup = image_template(
    url="https://assets.ubuntu.com/v1/450d7c2f-openstack-hero.svg",
    alt="",
    width="534",
    height="319",
    hi_def=True,
    loading="auto",
	fill=True,
    attrs={"class": "hero", "id": "openstack-hero"},
)

However, the most common usage is to add it to Django or Flask template contexts, as an image function.

Add lazysizes

At the time of writing, the loading attribute is only natively supported in Chrome. Therefore we use lazysizes to enable loading in other browsers while still taking advantage of the native functionality when it's available.

If loading is set to "lazy" (the default) we will output the Markup in a format supported by lazysizes, with the noscript and native-loading plugins enabled.

To support this in your site you need to add the following script to the <head> of each page, above any <link> attributes:

<script src="https://assets.ubuntu.com/v1/703e23c9-lazysizes+noscript+native-loading.5.1.2.min.js" defer></script>

Django usage

Add it as a template tag:

# myapp/templatetags.py

from canonicalwebteam import image_template
from django import template
from django.utils.safestring import mark_safe


register = template.Library()

@register.simple_tag
def image(*args, **kwargs):
    return mark_safe(image_template(*args, **kwargs))


# settings.py

TEMPLATES[0]["OPTIONS"]["builtins"].append("myapp.templatetags")

Use it in templates:

# templates/mytemplate.html

{% image url="https://assets.ubuntu.com/v1/9f6916dd-k8s-prometheus-light.png" alt="Operational dashboard" width="1040" height="585" hi_def=True fill=True %}

Flask usage

Add it as a template tag:

# app.py

from canonicalwebteam import image_template
from flask import Flask

app = Flask(__name__)

@app.context_processor
def utility_processor():
    return {"image": image_template}

Use it in templates, e.g.::

# templates/mytemplate.html

{{
  image(
    url="https://assets.ubuntu.com/v1/450d7c2f-openstack-hero.svg",
    alt="",
    width="534",
    height="319",
    hi_def=True,
	fill=True,
    loading="auto",
    attrs={"class": "hero", "id": "openstack-hero"},
  ) | safe
}}

Generated markup

The output image markup will be e.g.:

<img
    src="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,w_534,h_319,c_fill/https://assets.ubuntu.com/v1/450d7c2f-openstack-hero.svg"
    srcset="https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,w_1068,h_638,c_fill/https://assets.ubuntu.com/v1/450d7c2f-openstack-hero.svg 2x"
    alt=""
    width="534"
    height="319"
    loading="auto"
    class="hero"
    id="openstack hero"
/>

If loading is set to "lazy" (the default), the output markup will be wrapped in markup for lazysizes support:

<div class="lazyload" data-noscript>
  <noscript>
    <img ...>
  </noscript>
</div>

VS Code Snippet

To add the required markup for this template as a User Snippet, add the following as a HTML snippet (User Snippets under File > Preferences, or Code > Preferences on macOS):

"Image module": {
	"prefix": "image-module",
	"body": [
		"{{",
		"	image_template(",
		"		url=\"$1\",",
		"		alt=\"$2\",",
		"		height=\"$3\",",
		"		width=\"$4\",",
		"		hi_def=$5True,",
		"		loading=\"auto|lazy$6\",",
		"		attrs={\"class\": \"$7\"}",
		"	) | safe",
		"}}"
	],
	"description": "Image module include"
}"

canonicalwebteam.image-template's People

Contributors

albertkol avatar anthonydillon avatar barrymcgee avatar hatched avatar jkfran avatar lukewh avatar nottrobin avatar petesfrench avatar renovate-bot avatar sowasred2012 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

canonicalwebteam.image-template's Issues

Don't render images if not visible

I've no idea if we can actually solve this problem or not but there are cases where we hide images on small screens, for example the heros/takeovers on ubuntu.com.

I know there is an unresolved debate about hiding content, but seeing as it is something we currently do it would be great to solve this issue.

Not able to use with images with unknown dimensions

This isn't possible to use in a loop with images of multiple sizes when you don't have access to the size attributes of an image file.

For example the a selection of our certified public cloud partners section of https://ubuntu.com/public-cloud

{% for partner in partners %}
  <img src="{{ partner.logo }}" style="max-width: 144px;" width="144" alt="{{ partner.name }}" />
{% endfor %}

One solution could be for the width and height attributes to be optional but I'm not sure we want to encourage this.

Output image without wrapping in a `div`

Currently the image template outputs the image wrapped in a div. When using a pattern such as the heading icon this can cause problems. Ideally we should be able to output an image without a container, even if this is an option rather than a default.

Cloudinary urls getting two `w_x` set

https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,w_463,h_243,w_412/
w_463,h_243,w_412

We shouldn't use the width and height provided to resize as it doesn't take into account hidpi etc.
We should instead use the predefined widths in the template to best match vanilla breakpoints. So the above URL would become:
https://res.cloudinary.com/canonical/image/fetch/f_auto,q_auto,fl_sanitize,w_412/

Including the h_y option can also stretch images.

Allow any url, with hostname

snapcraft.io uses images served by dashboard.snapcraft.io, currently it's only possible to use images from assets.ubuntu.com.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.