-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add blurry_image Jinja extension (#75)
Adds blurry_image extension to insert an <img> tag with width & height into a Jinja template. Optionally inserts an image of a specific size. Usage: ``` {% blurry_image page.image, width=250 %} ```
- Loading branch information
1 parent
73154f2
commit dc2ac7b
Showing
11 changed files
with
270 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import mimetypes | ||
from pathlib import Path | ||
from urllib.parse import urlparse | ||
|
||
from jinja2_simple_tags import StandaloneTag | ||
from rich.console import Console | ||
from wand.exceptions import BlobError | ||
from wand.image import Image | ||
|
||
from blurry.images import add_image_width_to_path | ||
from blurry.settings import get_build_directory | ||
from blurry.utils import build_path_to_url | ||
|
||
warning_console = Console(stderr=True, style="bold yellow") | ||
|
||
|
||
class BlurryImage(StandaloneTag): | ||
safe_output = True | ||
tags = {"blurry_image"} | ||
|
||
def render(self, *args, **kwargs): | ||
(image_url, width) = args | ||
image_content_path: str = "." + urlparse(image_url).path | ||
image_path = get_build_directory() / image_content_path | ||
|
||
try: | ||
with Image(filename=str(image_path)) as image: | ||
image_width = image.width | ||
image_height = image.height | ||
image_mimetype = image.mimetype | ||
except BlobError: | ||
warning_console.print(f"Could not find image: {image_path}") | ||
return "" | ||
|
||
attributes = { | ||
"width": image_width, | ||
"height": image_height, | ||
} | ||
for attribute_key in kwargs: | ||
if attribute_key in ["width", "height"]: | ||
warning_console.print( | ||
f"blurry_image: Received {attribute_key} in template {self.template} but this attribute is dynamic. Skipping." | ||
) | ||
continue | ||
attributes[attribute_key] = kwargs.get(attribute_key) | ||
|
||
if width: | ||
image_path = add_image_width_to_path(image_path, width) | ||
|
||
if image_mimetype in [ | ||
mimetypes.types_map[".jpg"], | ||
mimetypes.types_map[".png"], | ||
]: | ||
image_path = Path(str(image_path).replace(image_path.suffix, ".avif")) | ||
|
||
if not image_path.exists(): | ||
warning_console.print( | ||
f"blurry_image: Could not find {image_path}. Skipping." | ||
) | ||
return "" | ||
|
||
attributes["src"] = build_path_to_url(image_path) | ||
|
||
if "alt" not in attributes: | ||
warning_console.print( | ||
f"blurry_image: alt attribute missing for image in {self.template}. " | ||
"This can negatively affect accessibility. " | ||
"Use an empty alt tag if an image is only for show." | ||
) | ||
|
||
attributes_str = " ".join( | ||
f'{name}="{value}"' for name, value in attributes.items() | ||
) | ||
|
||
return f"<img {attributes_str}/>" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
+++ | ||
"@type" = "WebPage" | ||
name = "Plugins: write a Jinja extension plugin" | ||
abstract = "Documentation for Blurry's Jinja extension plugins" | ||
datePublished = 2024-04-28 | ||
+++ | ||
|
||
# Plugins: write an Jinja extension plugin | ||
|
||
Blurry makes it easy to add [custom Jinja extensions](https://jinja.palletsprojects.com/en/3.1.x/extensions/) to your site. | ||
What is a Jinja extension? | ||
From the Jinja docs: | ||
|
||
> Jinja supports extensions that can add extra filters, tests, globals or even extend the parser. The main motivation of extensions is to move often used code into a reusable class like adding support for internationalization. | ||
With [custom extensions](https://jinja.palletsprojects.com/en/3.1.x/extensions/#module-jinja2.ext) you can add custom tags to Jinja, like Blurry's `{% blurry_image %}` tag. | ||
|
||
## Example: `{% blurry_image %}` | ||
|
||
This tag finds the optimized version of an image at the specified URL, and optionally of the specified size. | ||
You can find it in Blurry's source code in `blurry/plugins/jinja_plugins/blurry_image_extension.py`. | ||
|
||
Under the hood the extension uses [`jinja2-simple-tags`](https://github.com/dldevinc/jinja2-simple-tags) to simplify the process of writing a custom extension. | ||
|
||
To use a custom Jinja extension you've developed, add the appropriate plugin syntax to your project's `pyproject.toml` file: | ||
|
||
```toml | ||
[tool.poetry.plugins."blurry.jinja_extensions"] | ||
stars = "{{ yourproject.your_extension_file }}:YourExtension" | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.