Integrate Hippo CMS with Cloudinary Imaging Services
Michiel Rop
2015-03-19
Various clients expressed the need for more advanced image manipulation possibilities in Hippo CMS. Hippo's pluggable architecture makes it possible to integrate external image manipulation tools. This post describes how to extend the Gallery Processor and how to let Cloudinary transform your images in Hippo CMS.
Cloudinary ☁️ 📸
Cloudinary is a software–as-a-service (SaaS) imaging solution hosted in the cloud. It provides an api for manipulating images via a REST-service. This lab requires a Cloudinary account. An account can be acquired at http://cloudinary.com/. Their free plan will be sufficient to explore the basic functionalities.
The following image is taken from Hippo CMS. Here Cloudinary is used to created a thumbnail using face detection and to apply a "sepia" effect.
Try it yourself
- Clone the demo project at https://github.com/onehippo/labs/tree/master/cloudinary
- Build and run the project
- Create a Cloudinary account
- Open the cms of the running project
- Open the update editor perspective
- Enter your Cloudinary Cloud name, API Key and API Secret in the useCloudinaryGalleryProcessor groovy script ( see screenshot below )
- Save and run the script
- Log out of the cms and log in again for the services to reload
- Create an image using the image Gallery !!!
Deep dive
A service initializes the Cloudinary Singleton at login into the cms. The plugin uses the credentials supplied in the above mentioned groovy script.
public class CloudinaryService extends Plugin {
private static final Logger LOGGER = LoggerFactory.getLogger(CloudinaryService.class);
public static final String CLOUD_NAME = "cloud_name";
public static final String API_KEY = "api_key";
public static final String API_SECRET = "api_secret";
private Cloudinary cloudinary;
public CloudinaryService(final IPluginContext context, final IPluginConfig config) {
super(context, config);
context.registerService(this, config.getString("cloudinary.service.id", CloudinaryService.class.getName()));
init();
}
public Cloudinary getCloudinary() {
return cloudinary;
}
private void init() {
String cloudName = getPluginConfig().getString(CLOUD_NAME);
String apiKey = getPluginConfig().getString(API_KEY);
String apiSecret = getPluginConfig().getString(API_SECRET);
if (StringUtils.isEmpty(cloudName)||StringUtils.isEmpty(apiKey)|| StringUtils.isEmpty(apiSecret)){
LOGGER.warn("Cloudinary initialization parameters has not been set, "
+ "Cloudinary can not be used. "
+ "Please set the parameters cloud_name, api_key and api_secret");
}
cloudinary = new Cloudinary(Cloudinary.asMap(
"cloud_name", cloudName,
"api_key", apiKey,
"api_secret", apiSecret));
}
}
After uploading the original image, each image variant is created using the properties defined on the subnodes of /hippo:configuration/hippo:frontend/cms/cms-services/cloudinaryGalleryProcessorService. With these properties a com.cloudinary.Transformation instance is created. As described on http://cloudinary.com/documentation/java_integration a java.util.Map is returned containing all properties of the image. The "public_id" property is at least needed to generate the image URL. Using that URL the manipulated image is requested. That variant is stored in the CMS.
CloudinaryImageOperation.java:
upload = cloudinary.uploader().upload(tmpFile, Cloudinary.asMap(
"transformation", transformation));
String format = getFormat();
if (StringUtils.isEmpty(format)) {
format = (String) upload.get("format");
}
String url = cloudinary.url().format(format).generate((String) upload.get("public_id"));
scaledData = new URL(url).openStream();
Conclusion 📚
This lab helps you tap into the extensive imaging capabilities of Cloudinary from within Hippo. It requires a Cloudinary subscription and server side access to Cloudinary. In this example images are still served from the CMS. This enables editors to use the default functionality for cropping and uploading a different version for image variants.
The approach can be generalized: Use Hippo's modular architecture to connect to external services to modify content and possibly serve it from the cloud.