A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Ben  McKernan
Jun 2, 2016
  6863
(6 votes)

Content reference list with page preview

I'm sure everyone has read Grzegorz Wiecheć awesome blog, and if you haven't then you should. I while back he blogged about adding previews to the content reference list (https://gregwiechec.com/2015/09/content-references-list-with-preview/) and the content area (https://gregwiechec.com/2016/03/updated-contentarea-with-images/). However it only supported previewing images, which I thought was under-selling the concept. So I'm going to one up him and add page and block preview support.

Image j2cWQXiw4B.gif

There is a library called rasterizeHTML.js (https://github.com/cburgmer/rasterizeHTML.js) which provides some nice methods for rendering an HTML document to a canvas element. My custom editor will use this to load the preview URL of a page or a block and render it to a canvas which is then displayed as a preview tooltip.

define([
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/on",
    "dojo/dom",
    "dojo/aspect",

    "dijit/popup",
    "dijit/TooltipDialog",

    "alloy/rasterize-html",

    "epi-cms/contentediting/editors/ContentReferenceListEditor"
], function (
    declare,
    lang,
    on,
    dom,
    aspect,

    popup,
    TooltipDialog,

    rasterizeHtml,

    ContentReferenceListEditor
) {

    return declare([ContentReferenceListEditor], {

        buildRendering: function () {
            this.inherited(arguments);

            var _this = this;
            aspect.around(this.list._list, "insertRow", function (originalInsertRow) {
                return function (object, parent, beforeNode, i, option) {
                    var row = originalInsertRow.apply(this, arguments);
                    if (object.hasTemplate) {
                        lang.hitch(_this, _this._createTooltip(row, object.previewUrl, !!object.downloadUrl));
                    }
                    return row;
                };
            });
        },

        _createTooltip: function (node, previewUrl, isImage) {
            var content;

            if (isImage) {
                content = document.createElement("img");
                content.src = previewUrl;
                content.setAttribute("style", "max-width: 500px;");
            } else {
                content = document.createElement("canvas");
                content.height = 600;
                content.width = 750;

                var context = content.getContext("2d");
                context.scale(0.75, 0.75);

                rasterizeHtml.drawURL(previewUrl, content, { height: 800, width: 1000 });
            }

            this.own(node.tooltip = new TooltipDialog({
                connectId: [node.id],
                content: content
            }));

            on(node, "mouseleave", function () {
                popup.close(node.tooltip);
            });

            on(node, "click", function () {
                popup.open({
                    popup: node.tooltip,
                    around: dom.byId(node.id),
                    orient: ["after-centered"]
                });
            });
        }
    });
});

This approach does not support CORS so the pages and blocks being rendered have to be from the same origin as the page running the script. Browser support is limited to Firefox, Chrome, Safari, and Edge.

The server side code to make your properties use this editor can be found on Grzegorz's blog post (https://gregwiechec.com/2015/09/content-references-list-with-preview/).

Jun 02, 2016

Comments

Jun 2, 2016 04:58 PM

Nice! :)

Daniel Ovaska
Daniel Ovaska Jun 2, 2016 09:57 PM

Nice concept!

Eric
Eric Jun 3, 2016 11:02 PM

Part of the nex ui update perhaps ;)

Please login to comment.
Latest blogs
Looking back at Optimizely in 2025

Explore Optimizely's architectural shift in 2025, which removed coordination cost through a unified execution loop. Learn how agentic Opal AI and...

Andy Blyth | Dec 17, 2025 |

Cleaning Up Content Graph Webhooks in PaaS CMS: Scheduled Job

The Problem Bit of a niche issue, but we are building a headless solution where the presentation layer is hosted on Netlify, when in a regular...

Minesh Shah (Netcel) | Dec 17, 2025

A day in the life of an Optimizely OMVP - OptiGraphExtensions v2.0: Enhanced Search Control with Language Support and Synonym Slots

Supercharge your Optimizely Graph search experience with powerful new features for multilingual sites and fine-grained search tuning. As search...

Graham Carr | Dec 16, 2025

A day in the life of an Optimizely OMVP - Optimizely Opal: Specialized Agents, Workflows, and Tools Explained

The AI landscape in digital experience platforms has shifted dramatically. At Opticon 2025, Optimizely unveiled the next evolution of Optimizely Op...

Graham Carr | Dec 16, 2025