Skip to content

Commit 7cb60aa

Browse files
authored
Merge pull request plone#1192 from plone/mrtango-classic-ui-images
Add images chapter to classic-ui docs
2 parents 83a35d0 + 72fe140 commit 7cb60aa

File tree

2 files changed

+250
-2
lines changed

2 files changed

+250
-2
lines changed

docs/classic-ui/images.md

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
---
2+
html_meta:
3+
"description": "Image resolution and scaling in Plone Classic UI"
4+
"property=og:description": "Image resolution and scaling in Plone Classic UI"
5+
"property=og:title": "Image resolving and scaling"
6+
"keywords": "Plone, Classic UI, classic-ui, image, resize, scale"
7+
---
8+
9+
(classic-ui-images-label)=
10+
11+
# Image handling
12+
13+
The default content types and behaviors use the field `plone.namedfile.NamedBlobImage` for all images.
14+
15+
For this field, image scaling and HTML tag creation is provided by the `plone.namedfile.scaling` module, specifically in the [`ImageScaling`](https://github.com/plone/plone.namedfile/blob/ecf33a2bc7a8c61888909bc383b3e08d80888e43/plone/namedfile/scaling.py#L350) view.
16+
17+
Given a Dexterity content type named `news-item1` with a `plone.namedfile.NamedBlobImage` field named `image`, we can use the following APIs to access the image scales and manage scales.
18+
19+
```{note}
20+
We will use the image object as context in the following examples.
21+
```
22+
23+
(classic-ui-images-default-scales-label)=
24+
25+
## Default scales
26+
27+
In `/@@imaging-controlpanel` Plone allows you to configure which scales are available and what dimensions they should have. By default we have the following scales configured:
28+
29+
* large 768:768
30+
* preview 400:400
31+
* mini 200:200
32+
* thumb 128:128
33+
* tile 64:64
34+
* icon 32:32
35+
* listing 16:16
36+
37+
You can add or change scales as you like.
38+
39+
40+
(classic-ui-images-image-resolving-by-uri-label)=
41+
42+
## Image resolving by URI
43+
44+
Plone can resolve an image scale via URI in different ways.
45+
46+
47+
(classic-ui-images-by-field-and-scale-name-label)=
48+
49+
### By field and scale name
50+
51+
Given our `news-item1` with the field `image`, we can get the name scale `thumb` as follows:
52+
53+
`http://localhost:8080/Plone/news-item1/@@images/image/thumb`
54+
55+
To get the original image, you can leave out the scale:
56+
57+
`http://localhost:8080/Plone/news-item1/@@images/image`
58+
59+
60+
(classic-ui-images-by-cacheable-scale-uid-name-label)=
61+
62+
### By cacheable scale UID name
63+
64+
When an image scale is created, it will be cached under the name `UID.EXT` (i.e. `f4c34254b44ba351af7393bfe0296664.jpeg`) in the object annotations.
65+
Scaling keeps the uploaded formats, except for TIFF which ends up as JPEG.
66+
It can be resolved as follows:
67+
68+
`http://localhost:8080/Plone/news-item1/@@images/3d182f34-8773-4f20-a79d-8774c3151b7e.jpeg`
69+
70+
This is useful for caching URLs in Varnish or the browser.
71+
In case the uploaded image or scale definitions have changed, they will be saved again under a different UID.
72+
This changes the URL and forces either the browser, or a cache proxy such as Varnish, to fetch it again.
73+
74+
75+
(classic-ui-images-image-tag-label)=
76+
77+
## Image tag
78+
79+
To get an HTML tag for a scaled image, you can use the `ImageScaling` view as follows:
80+
81+
```python
82+
from plone import api
83+
84+
scale_util = api.content.get_view("images", context, request)
85+
tag = scale_util.tag("image", scale="mini")
86+
```
87+
88+
To get a specific image size:
89+
90+
```python
91+
from plone import api
92+
93+
scale_util = api.content.get_view("images", context, request)
94+
tag = scale_util.tag("image", width="600", height="200")
95+
```
96+
97+
The complete list of arguments with their default values is shown in the following example.
98+
99+
```python
100+
from plone import api
101+
102+
scale_util = api.content.get_view("images", context, request)
103+
tag = scale_util.tag(
104+
fieldname=None,
105+
scale=None,
106+
height=None,
107+
width=None,
108+
direction="thumbnail"
109+
)
110+
```
111+
112+
If you pass additional kwargs to `tag`, they become attributes on `tag`.
113+
114+
115+
(classic-ui-images-image-scaling-no-tag-creation-label)=
116+
117+
## Image scaling without tag creation
118+
119+
To get the scaling information only without creating an HTML tag, you can use the `ImageScaling` view as follows:
120+
121+
```python
122+
from plone import api
123+
124+
scale_util = api.content.get_view("images", context, request)
125+
# The default `Image` content type's field name is "image".
126+
# On the following line of code, "image" is the field name.
127+
image_scale = scale_util.scale("image", scale="mini")
128+
print(image_scale.url)
129+
print(image_scale.width)
130+
print(image_scale.height)
131+
```
132+
133+
This will produce the following output:
134+
135+
```console
136+
http://localhost:8080/Plone/news-item1/@@images/3d182f34-8773-4f20-a79d-8774c3151b7e.jpeg
137+
200
138+
110
139+
```
140+
141+
The most important properties are the following:
142+
143+
- `data`
144+
- `fieldname`
145+
- `height`
146+
- `mimetype`
147+
- `srcset`
148+
- `srcset_attribute`
149+
- `tag`
150+
- `uid`
151+
- `url`
152+
- `width`
153+
154+
You can directly create an HTML tag from `image_scale`:
155+
156+
```pycon
157+
>>> print(image_scale.tag())
158+
159+
<img src="http://localhost:8080/Plone/news/newsitem1/@@images/9f676d46-0cb3-4512-a831-a5db4079bdfa.jpeg" alt="News Item 1!" title="News Item 1" height="21" width="32" srcset="http://localhost:8080/Plone/news/newsitem1/@@images/4a68513c-cffd-4de0-8a35-80627945b80f.jpeg 2x, http://localhost:8080/Plone/news/newsitem1/@@images/c32929c6-cb89-4ce7-846f-38adf29c09a4.jpeg 3x" />
160+
```
161+
162+
Instead of using the configured named scales, you can get an HTML tag with any specific size in pixels:
163+
164+
```python
165+
from plone import api
166+
167+
scale_util = api.content.get_view("images", context, request)
168+
tag = scale_util.scale("image", width="600", height="200")
169+
```
170+
171+
(classic-ui-images-using-image_scale0-in-templates-label)=
172+
173+
### Using image_scale in templates
174+
175+
You could use the URL-variant from above, but that would be an uncached version.
176+
To create a cached scale in a page template you can do the following:
177+
178+
```xml
179+
<div tal:define="scale_view context/@@images;
180+
image_scale python: scale_view.scale('image', 'mini')">
181+
<img
182+
src="${python: image_scale.url}"
183+
width="${python: image_scale.width"
184+
height="${python: image_scale.height}"
185+
>
186+
</div>
187+
```
188+
189+
Or you can get the HTML tag back, and replace the current tag with it:
190+
191+
```xml
192+
<div tal:define="scale_view context/@@images">
193+
<img tal:replace="structured python: scale_view.tag('image', 'mini')">
194+
</div>
195+
```
196+
197+
You can also provide the following keyword arguments to set `title`, `alt`, or `css_class` for the generated tag:
198+
199+
```xml
200+
<div tal:define="scale_view context/@@images">
201+
<img tal:replace="structured python: scale_view.tag('banner', 'mini', title='The Banner', alt='Alternative text', css_class='banner')">
202+
</div>
203+
```
204+
205+
(classic-ui-images-get-image_scale-by-cached-uid-name-label)=
206+
207+
### Get image_scale by cached UID name
208+
209+
If you only have the cached image name from an URL and need to get the image scale, unfortunately you can't use restrictedTraverse(), as this will not be able to resolve the scale. But you can use this workaround, by calling the `publishTraverse` method in `ImageScaling` directly:
210+
211+
```python
212+
import re
213+
from plone import api
214+
215+
uri = "http://localhost:8080/Plone/news-item1/@@images/3d182f34-8773-4f20-a79d-8774c3151b7e.jpeg"
216+
image_url = re.compile(r"(.*@@images)\/([a-zA-Z0-9.-]*)\/?([a-zA-Z]*)")
217+
218+
url_match = image_url.match(uri)
219+
groups = url_match.groups()
220+
# ("http://localhost:8080/Plone/news-item1", "3d182f34-8773-4f20-a79d-8774c3151b7e.jpeg")
221+
scale_util = api.content.get_view("images", context, request)
222+
image_scale = scaling_util.publishTraverse(context.REQUEST, groups[1])
223+
```
224+
225+
226+
(classic-ui-images-scaling-direction-label)=
227+
228+
## Scaling `direction`
229+
230+
The default direction is `thumbnail`.
231+
232+
Other options are:
233+
234+
* `down`
235+
* `keep`
236+
* `scale-crop-to-fill`
237+
* `scale-crop-to-fit`
238+
* `thumbnail`
239+
* `up`
240+
241+
242+
(classic-ui-images-permissions-label)=
243+
244+
## Permissions
245+
246+
The `ImageScaling` view explicitly checks the permissions of the current user.
247+
To access image scales, which are normally not accessible to the current user, override the `validate_access` method in `plone.namedfile.scaling.ImageScale`.

docs/classic-ui/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ This frontend is now called "Classic UI".
2727

2828
Choosing one frontend over another depends on several factors.
2929

30-
Classic UI would be a better choice for the following situations.
30+
Classic UI would be a better choice for the following situations.
3131

3232
- Reason 1
3333
- Reason 2
3434
- Reason N
3535

36-
The default frontend Volto would be a better choice for the following situations.
36+
The default frontend Volto would be a better choice for the following situations.
3737

3838
- Reason 1
3939
- Reason 2
@@ -55,6 +55,7 @@ viewlets
5555
forms
5656
portlets
5757
csrf
58+
images
5859
icons
5960
recipes
6061
whatsnew

0 commit comments

Comments
 (0)