Images in page templates¶
Description
How to link to images in page templates in Plone.
Putting a static image into a page template¶
Here is an example how to create an <img>
tag in a .pt
file:
<img tal:attributes="src string:${context/@@plone_portal_state/portal_url}/++resource++plonetheme.mfabrik/close-icon.png" alt="[ X ]"/>
Let’s break this down:
We are rendering an
<img>
tag.The
src
attribute is dynamically generated using a TALES expression.We use string comprehension to create the
src
attribute. Alternatively we could use e.g. thepython:
TALES expression type and embed one line python of code to generate the attribute value.We look up a helper view called plone_portal_state. This is a
BrowserView
shipped with Plone. Its purpose is to expose different helper methods to page templates and Python code.We call
plone_portal_state
’sportal_url()
method. This will return the root URL of our site. Note that this is not necessary the domain’s top-level URL, as Plone sites can be nested in folders, or served on a path among unrelated web properties.We append our Zope 3 resource path to our site root URL (see below). This maps to some static media folder in our add-on files on the disk.
There we point to
close-icon.png
image file.We also add the
alt
attribute of the<img>
tag normally. It is not dynamically generated.
When the page template is generated, the following snippet could look like, for example:
<img src="http://localhost:8080/mfabrik/++resource++plonetheme.mfabrik/logo.png" alt="[ X ]">
… or:
<img src="http://mfabrik.com/++resource++plonetheme.mfabrik/logo.png" alt="[ X ]">
… depending on the site virtual hosting configuration.
Relative image look-ups¶
Warning
Never create relative image look-ups without prefixing the image source URL with the site root.
Hardcoded relative image path might seem to work:
<img src="++resource++plonetheme.mfabrik/logo.png" >
… but this causes a different image base URL to be used on every page. The image URLs, from the browser point of view, would be:
<img src="http://yoursite/++resource++plonetheme.mfabrik/logo.png" >
… and then in another folder:
<img src="http://yoursite/folder/++resource++plonetheme.mfabrik/logo.png" >
… which prevents the browser from caching the image.
Registering static media folders in your add-on product¶
Zope 3 resource directory¶
The right way to put in a static image is to use a Zope 3 resource directory.
Create folder
yourcompany.product/yourcompany/product/browser/static
.Add the following ZCML to
yourcompany.product/yourcompany/product/browser/configure.zcml
.
<browser:resourceDirectory
name="yourcompany.product"
directory="static"
layer=".interfaces.IThemeSpecific"
/>
This will be picked up at the ++resource++yourcompany.product/
static
media path.
Layer is optional: the static media path is available only when your add-on product is installed if the layer is specified.
Also see Resource folders
Rendering Image content items¶
You can refer to ATImage
object’s content data download by adding
/image
to the URL:
<img alt="" tal:attributes="src string:${context/getImage/absolute_url}/image" />
The magic is done in the __bobo_traverse__
method of ATImage
by
providing traversable hooks to access image download:
Rendering ImageField
¶
Archetypes’s ImageField
maps its data to the content object at attribute
which is the field’s name.
If you have a field campaignVideoThumbnail
you can generate an image tag
as follows:
<img class="thumbnail" tal:attributes="src string:${campaign/absolute_url}/campaignVideoThumbnail" alt="Campaign video" />
If you need more complex <img>
output,
create a helper function in your BrowserView
and use Python code
to perform the ImageField
manipulation.
See ImageField
for more information:
tag()
method¶
Note
Using tag()
is discouraged. Create your image tags manually.
Some content provides a handy tag()
method to generate
<img src="" />
tags
with different image sizes.
tag()
is available on
Archetypes
ImageField
ATNewsItem
ATImage
FSImage
(Zope 2 image object on the file-system)
tag()
is defined in OFS.Image.
Scaling images¶
tag()
supports scaling. Scale sizes are predefined.
When an ATImage
is uploaded,
various scaled versions of it are stored in the database.
Displaying a version of the image using the “preview” scale:
image.tag(scale="preview", alt="foobar text")
This will generate:
<img src="http://something/folder/image/image_preview" alt="foobar text" />
Note
If you are not using the alt
attribute, you should set it to an
empty string: alt=""
. Otherwise screen readers will read
the src
attribute of the <img>
tag aloud.
In order to simplify accessing these image scales, use
archetypes.fieldtraverser.
This package allows you to traverse to the stored image scales while still
using AnnotationStorage
and is a lot simpler to get going (in the
author’s humble opinion :).
Default scale names and sizes are defined in ImageField
declaration for
custom ImageField
s.
For ATImage
, those are in
Products.ATContentTypes.content.image.
Lightbox style image pop-ups¶
Plone comes with plone.app.jquerytools which offers easy integration for lightbox style image pop-ups.
You can use Plone standard image content type, defining scales using plone.app.imaging or you can define image fields in your schema.
In the example below we define custom image fields in Archetypes schema.
contenttype.py:
atapi.ImageField(
'imageTwo',
widget=atapi.ImageWidget(
label=_(u"Kuva #2"),
),
validators=('isNonEmptyFile'),
languageIndependent=True,
sizes={
'thumb': (90, 90),
'large': (768, 768),
},
),
atapi.ImageField(
'imageThree',
widget=atapi.ImageWidget(
label=_(u"Kuva #3"),
),
validators=('isNonEmptyFile'),
languageIndependent=True,
sizes={
'thumb': (90, 90),
'large': (768, 768),
},
),
Related view page template file
<div class="product-all-images">
<img class="product-image-preview" tal:condition="context/getImageTwo" tal:attributes="src string:${context/absolute_url}/@@images/imageTwo/thumb" alt="" />
<img class="product-image-preview" tal:condition="context/getImageThree" alt="" tal:attributes="src string:${context/absolute_url}/@@images/imageThree/thumb" />
</div>
And then we activate all this in a JavaScript using prepOverlay()
from plone.app.jquerytools
/*global window,document*/
(function($) {
"use strict";
/**
* Make images clickable and open a bigger version of the image when clicked
*/
function prepareProductImagePreviews() {
// https://pypi.python.org/pypi/plone.app.jquerytools/1.4#examples
$('.product-image-preview')
.prepOverlay({
subtype: 'image',
urlmatch: 'thumb',
urlreplace: 'large'
});
}
$(document).ready(function() {
prepareProductImagePreviews();
});
})(jQuery);