Image-like content¶
Description
How to programmatically manipulate images on your Plone site.
Introduction¶
Plone supports image content in several forms:
- stand-alone content type
- As stand-alone content type, images will be visible in the sitemap.
This is the case for the default
Imagecontent type, but you can create custom content types with similar properties. - image field
As a field, the image is directly associated with one content object. Use
plone.namedfile.field.namedfile.NamedBlobImage:custom_image = NamedBlobImage( title=_(u'label_customimage', default=u'Custom Image'), description=_(u'help_customimage', default=u''), required=False, )
- behavior using an image field
- The
plone.leadimagebehavior inplone.app.contenttypes.behaviors.leadimageprovides a field calledleadimage. Custom behaviors like this can be created too.
Custom image content type¶
If you want to have your custom content type behave like the stock Plone Image content type:
- Inherit from the content class
plone.app.contenttype.content.Imageand use the xml schema from that class. - When writing the
GenericSetupXML of your type, follow the example of Image.xml. - Do not set workflow for your type in
profiles/default/workflows.xml.
<?xml version="1.0"?>
<object name="portal_workflow" meta_type="Plone Workflow Tool">
<bindings>
<type type_id="YourImageType"/>
</bindings>
</object>
Accessing images¶
Both - Dexterity and Archetypes - are offering the same traversable @@images view.
It can be used from page templates and Python code to provide access to the image and different image scales for image fields on content.
The code for image access and scales for Dexterity based content is handled by plone.namedfile. Old Archetypes based content image scales is handled by plone.app.imaging.
Using direct URLs¶
If your image field is a primary field, like at the default Image content type,
then access works by calling the url without any view:
http://yoursite/imagecontent
The generic way to access any image on your content is an URL like so:
http://yoursite/imagecontent/@@images/FIELDNAME
Predefined image scales from the configuration settings are accessed this way:
http://yoursite/imagecontent/@@images/FIELDNAME/SCALENAME
You might find URLs of custom (on-the-fly) image scales accessed this way (see below):
http://yoursite/imagecontent/@@images/FIELDNAME/CUSTOM_SCALE_UID.jpg
Examples 1,
show the original image from the plone.leadimage behavior:
http://yoursite/imagecontent/@@images/leadimage
Examples 2,
show the scale mini from the field custom_image:
http://yoursite/imagecontent/@@images/custom_image/mini
Access by creating tags programmatically¶
In code a lookup of the images multi-adapter is needed.
It implements the plone.app.imaging.interfaces.IImageScaling interface, thus it provides:
scale(fieldname=None, scalename=None, **parameters)Retrieve a scale based on the given name or set of parameters. The parameters can be anything supported by scaleImage and would usually consist of at least a width & height.
Returns either an object implementing IImageScale or None
tag(fieldname=None, scalename=None, **parameters)- Like
scalebut returns a tag for a scale. getAvailableSizes(fieldname=None)- returns a dictionary of scale name => (width, height)
getImageSize(fieldname=None)- returns the original image size, a tuple of (width, height)
getInfo(fieldname=None, scalename=None, **parameters)- returns metadata for the requested scale from the storage
images is in fact a view (a multi-adapter between context and request),
we can use plone.api.content.get_view for lookup:
from plone import api
...
scale_util = api.content.get_view('images', context, request)
tag = scale_util.tag('leadimage', 'mini')
Creating Scales¶
Named scales¶
In the Plone Control Panel under Image Handling images scales can be defined (and redefined).
Those scales are stored in the configuration registry.
In a custom GenericSetup profile additional scales can be added by adding some lines to registry.xml like so:
<?xml version="1.0"?>
<registry>
<records
interface="Products.CMFPlone.interfaces.controlpanel.IImagingSchema"
prefix="plone">
<value key="allowed_sizes" purge="false">
<element>custom_4to3 400:300</element>
<element>custom_3to4 300:400</element>
</value>
</records>
...
</registry>
Scales On-The-Fly¶
Sometimes scales need to be created on-the-fly.
This can be done programmatically only.
In order to create scale on the fly the images multi-adapter is used.
The methods scale, tag or getInfo can be used to create a scale.
In order to create a custom scale skip the scalename parameter and use height and width parameters.
Optional choose the direction parameter:
- up
- Scaling scales the smallest dimension up to the required size and scrops the other dimension if needed.
- down
- Scaling starts by scaling the largest dimension to the required size and scrops the other dimension if needed.
- thumbnail
- scales to the requested dimensions without cropping. The resulting image may have a different size than requested. This option requires both width and height to be specified. keep is accepted as an alternative spelling for this option, but its use is deprecated.
Example, scale down (crop) to 300x200:
from plone import api
...
scale_util = api.content.get_view('images', context, request)
tag = scale_util.tag('leadimage', width=300, height=200, direction=down)
Attention: The generated URL is based on a genrated UID which points to the current scaled down version of the image. After modification of the content type the scale is not updated, but a new URL to the new scale will be generated. But the generated UID will be reused for the same upload, so one version is scaled only once.
portal_catalog and images¶
Never index image objects or store them as metadata,
as adding image data to the portal_catalog brain objects would greatly increase their site and make brain look-up slow.
Instead recreate the path of the image
Or if you have custom scales not available in configuration, index only image paths with ths scale information using getPhysicalPath().
Addons¶
Manual croppings can be choosen by using plone.app.imagecropping