Standard Image Template

There are four widgets that are image oriented and that all use an image template. These are:

dcm.CarouselWidget
dcm.GalleryWidget
dcm.ImageWidget
dcm.SliderWidget

Review the widgets for specific details on how the template is used. The code inside the template can generally rely on having the following rules available.

Variables

  • $_Image: data about the specific image (template is repeated for each image in the widget)

  • $_Gallery: the (structured) contents of the meta.json file for the gallery folder (same folder than holds the .v folders used by this widget)

  • $_Variant: link into the $_Gallery above, for easy access to the current variant in use

  • $_Show: link into the $_Gallery above, for easy access to the current show in use (if any)

The _ are the start of the variable name is a reminder that this is a system generated variable, not a variable found in your code. You very well may have a variable named “Show” or “Gallery”, and you can use those variables in your template as they will not conflict with the system variables. Unfortunately, For backwards compatibility, the variable $Image is an alias for $_Image in some places, however that usage is not supported nor preferred. TODO link to more about variable scope in scripts.

The $_Image Variable

It is easiest to express that values associated with $_Image in JSON format. This example is typical of what is available.

{ "Alias": "moving", "BasePath": "/banners/moving", "Path": "/galleries/banners/moving.v/full.jpg?dc-cache=20201216T040651483Z", "Position": 1, "Data": { "CenterHint": "1250" }, "Element": { "@Alias": "moving", "@Title": "lost" } }

As the template is repeated for each image in the widget, the values in the structure above will change, but the primary fields available remain the same.

  • Alias: the name of the image folder (minus the .v), access the value using $_Image.Aliass
  • BasePath: the path to the image folder (minus the .v and without the leading “galleries” path), access the value using $_Image.BasePath
  • Path: the full path to the image as would be seen by a web browser, this may include the caching stamp (dc-cache), access the value using $_Image.Path
  • Position: the position of this image in the list of images (1 for the first, 2 for the second, etc), access the value using $_Image.Position
  • Data: the (structured) contents of the meta.json file for the image (inside the .v folder) using the current locale (for example “eng”) from that file. Above $_Image.Data.CenterHint would contain the center hint (“1250”).
  • Element: a structured representation of the Image element that is the source of this image. It is an oversimplification, but basically all the attributes of the element are available as @ fields of the Element. Above $_Image.Element.@Title would contain the title (“lost”).

The $_Gallery Variable

The entire meta.json file, which could be as simple as a few variations. Example:

{ "Shows": [ { "Title": "Home Banners", "Alias": "home", "Images": [ "banner-1", "banner-2" ], "Centering": true } ], "Variations": [ { "ExactWidth": 670, "ExactHeight": 335, "Alias": "full", "Name": "Full" } , { "ExactWidth": 152, "ExactHeight": 152, "Alias": "thumb", "Name": "Thumbnail" } ] }

To access the width of the second variant, your code would be: $_Gallery.Variations.1.ExactWidth (remember that arrays start counting a 0, so 1 is the second). The value returned would be “152” for our example.

The $_Variant Variable

A subset of the $_Gallery data for the current variant in use. Example:

{ "ExactWidth": 670, "ExactHeight": 670, "Alias": "full", "Name": "Full" }

To access the width of the current variant, your code would be: $_Variant.ExactWidth . The value returned would be “152” for our example.

The $_Show Variable

A subset of the $_Gallery data for the current show in use. Example:

{ "Title": "Home Banners", "Alias": "home", "Images": [ "banner-1", "banner-2" ], "Centering": true }

However, developer's should generally avoid using shows and so the $_Show variable would rarely be used - and only if the widget is tied to a show.

To access the title of the current show, your code would be: $_Show.Title . The value returned would be “Home Banners” for our example.

GalleryWidget and ImageWidget (Standard Mode)

These widgets use a template to produce a visible image with possibly some additional text or an alt tag. The simplest usage example is a template that contains an img pointing to the path contained in $_Image.Path . Consider this example template from an GalleryWidget.

<Template> <div data-dcm-alias="{$_Image.Alias}"> <img src="{$_Image.Path}" class="pure-img" /> </div> </Template>

GalleryWidget

In order for a GalleryWidget to work with the CMS it needs the data-dcm-alias attribute with the img wrapped in a div so that entry can link to the image alias (folder name) from $_Image.Alias . (note - if not intended for editing in CMS, the gallery may contain only an img in the template.)

Each image in the gallery repeats the template and adds it to the html output. Let's examine how a gallery's template expands with this example:

<dcm.GalleryWidget Path="/examples/simple/board" Size="1-4"> <Template> <div data-dcm-alias="{$_Image.Alias}"> <img src="{$_Image.Path}" alt="photo of {$_Image.Element.@Title}" class="pure-img" /> </div> </Template> <Image Alias="lance" Title="Lance Gold" /> <Image Alias="mac" Title="Mac Orange" /> <Image Alias="tom" Title="Tom Blue" /> <Image Alias="carrie" Title="Carrie Green" /> </dcm.GalleryWidget>

After the server processes this widget, here is the code that is generated, the HTML Output:

<div class="pure-g dc-widget dc-widget-gallery"> <div data-dcm-alias="lance" class="pure-u pure-u-1-4"> <img src="/galleries/examples/simple/board/lance.v/full.jpg?dc-cache=20201216T040652111Z" alt="photo of Lance Gold" class="pure-img"> </div> <div data-dcm-alias="mac" class="pure-u pure-u-1-4"> <img src="/galleries/examples/simple/board/mac.v/full.jpg?dc-cache=20201216T040652111Z" alt="photo of Mac Orange" class="pure-img"> </div> <div data-dcm-alias="tom" class="pure-u pure-u-1-4"> <img src="/galleries/examples/simple/board/tom.v/full.jpg?dc-cache=20201216T040652111Z" alt="photo of Tom Blue" class="pure-img"> </div> <div data-dcm-alias="carrie" class="pure-u pure-u-1-4"> <img src="/galleries/examples/simple/board/carrie.v/full.jpg?dc-cache=20201216T040652111Z" alt="photo of Carrie Green" class="pure-img"> </div> </div>

Note how the template has repeated four times, once for each image, and how data-dcm-alias , src , and alt all have the variables replaced with their actual value for that current image (current to the loop that repeats the template).

Here is the visual output, review the image for the alt attribute to confirm the variables are replaced:

ImageWidget

Consider this example with a ImageWidget using a simple template:

<dcm.ImageWidget Path="/examples/simple/board/mac" Description="Mac Orange"> <Template> <img src="{$_Image.Path}" alt="photo of {$_Image.Element.@Description}" class="pure-img-inline" /> </Template> </dcm.ImageWidget>

This is the html generated:

<div class="dc-widget dc-widget-image dc-media-box dc-media-image"> <img src="/galleries/examples/simple/board/mac.v/full.jpg?dc-cache=20201216T040652111Z" alt="photo of Mac Orange" class="pure-img-inline"> </div>

This is the visual output:

photo of Mac Orange

Why not just put “Mac Orange” directly into the alt? We could, but if the ImageWidget is setup to be used by the CMS keep in mind that regular users of the widget cannot edit the template. The Description attribute on the other hand is editable through the CMS, thus allowing the user to change not only the photo but also the alt text through the CMS. Therefore, it is important to consider NOT putting information into a Template if it may need to be edited later. If something more than just alt text is needed there are options such as extending the ImageWidget for this website or, perhaps simpler, using the images own meta.json for extra data.

ImageWidget Alternative Approach

This is not recommended, but may sometimes be useful.

Taking the meta.json example further, consider if Mac's data file - found here /galleries/examples/simple/board/mac.v/meta.json - had the following:

{ default: { Name: "Mac Ternes", Title: "CIO", Email: "mac@abc.com", Phone: "ext. 201" }, eng: { Description: "Server guru" }, spa: { Description: "GurĂº del servidor" } }

An image meta file is always collapsed to the the current locale before it is used as Data. First the “default” values are loaded and then what ever is in the current locale (such as “eng”) is merged into the structure. So for an English locale this is what Data will contain:

{ "Email": "mac@abc.com", "Description": "Server guru", "Phone": "ext. 201", "Title": "CIO", "Name": "Mac Ternes" }

Thus $_Image.Data.Name is the correct way to access the name field of that data.

And then we used the image data instead of the Description attribute. This is elegant because switching the image automatically switches to the correct name as well, without the addition of the Description. However, CMS users need to learn to use and edit those image properties. Plus a change to those properties is immediate, there is no preview mode for them - so for simplicity using Description is a good idea.

<dcm.ImageWidget Path="/examples/simple/board/mac"> <Template> <img src="{$_Image.Path}" alt="{$_Image.Data.Name}" class="pure-img-inline" /> </Template> </dcm.ImageWidget>

This is the visual output:

Mac Ternes

TODO link to page about using meta.json files and on how the locale support is superior

ImgCache Shortcut

It is fine to use dc.ImgCache instead of img and doing so shortens the code needed a little.

<dcm.ImageWidget Path="/examples/simple/board/mac"> <Template> <dc.ImgCache alt="photo of {$_Image.Data.Name}" /> </Template> </dcm.ImageWidget>

The ImgCache will automatically pickup the src and class attributes for you, as well add the loading="lazy" option.

This is the visual output:

photo of Mac Ternes

ImgCache will even pickup the Description and automatically create the alt :

<dcm.ImageWidget Path="/examples/simple/board/mac" Description="photo of Mac"> <Template> <dc.ImgCache /> </Template> </dcm.ImageWidget>

The ImgCache will automatically pickup the src and class attributes for you, as well add the loading="lazy" option.

This is the visual output:

photo of Mac

Galleries may use ImgCache as well, see below.

Expanding The Code

Gallery Widget is often used to link a gallery of images to a sub page. While you can create very creative code in a template - keeping in mind that it repeats for each image - this example will focus in on the case where a) each image entry links to a sub page and b) we display the name under the image.

Imagine that we have a sub page for each image in the folder “board” such that /board/mac, /board/carrie, /board/tom and /board/lance each have and note that the page name matches the Alias - for convenience. Here is how we could code that:

<dcm.GalleryWidget Path="/examples/simple/board" Size="1-4"> <Template> <div data-dcm-alias="{$_Image.Alias}" class="dc-layout-pad-large entry"> <dc.Link Page="/board/{$_Image.Alias}"> <dc.ImgCache alt="photo of {$_Image.Element.@Title}" /> <div class="name dc-align-center">{$_Image.Element.@Title}</div> </dc.Link> </div> </Template> <Image Alias="mac" Title="Mac Orange" /> <Image Alias="carrie" Title="Carrie Green" /> <Image Alias="tom" Title="Tom Blue" /> <Image Alias="lance" Title="Lance Gold" /> </dcm.GalleryWidget>

For the Link note that Page="/board/" expands out to those for paths above. Also note that <div> under the image is the code for displaying the name. Visual output:

SliderWidget and CarouselWidget (Standard Mode)

Both of these widgets support an AriaTemplate which is a template that is read by screen readers / assistive technologies. Since the operate nearly identically, and since SliderWidget is the recommended approach, we'll focus on that example. Note that $Image and $_Image are not the same fields for CarouselWidget - use the latter for consistency.

<dcm.SliderWidget Path="/examples/simple/board" Display="LRControl" Centering="true"> <AriaTemplate> <div role="listitem">{$_Image.Element.@Title}</div> </AriaTemplate> <Image Alias="mac" Title="Mac Orange" /> <Image Alias="carrie" Title="Carrie Green" /> <Image Alias="tom" Title="Tom Blue" /> <Image Alias="lance" Title="Lance Gold" /> </dcm.SliderWidget>

The <div role="listitem"> as the starting place is always recommended. A screen reader experiences the banners not as rotating images but as a list of descriptions. A screen reader does not wait for the images to change but rather can navigate through the list at will. So the screen reader would start with “List: banner images” and then “Item: Mac Orange” and then “next item: Carrie Green” etc. In order for assistive technologies to be useful with a banner the AriaTemplate must produce a useful description or summary of the image (and for each image).

Here is how this shows:

Mac Orange
Carrie Green
Tom Blue
Lance Gold

And here is how that the SliderWidget looks to screen readers (the images are hidden to screen readers and this list is hidden to the visual layout):

<div role="list" class="dc-element-hidden" aria-label="banner images"> <div role="listitem">Mac Orange</div> <div role="listitem">Carrie Green</div> <div role="listitem">Tom Blue</div> <div role="listitem">Lance Gold</div> </div>

GalleryWidget (Show Mode)

Although shows are not recommended, they are sometimes useful. Here is an example of the meta.json file found at /galleries/examples/simple/board:

{ "Variations": [ { "ExactWidth": 500, "Alias": "full", "Name": "Full" }, { "ExactWidth": 152, "ExactHeight": 152, "Alias": "thumb", "Name": "Thumb" } ] , "Shows": [ { "Title": "All board members", "Alias": "main", "Images": [ "carrie", "lance", "mac", "tom" ] } ] }

The show main lists all four of the board members, in the order to be displayed. Here is how to use that:

<dcm.GalleryWidget Path="/examples/simple/board" Size="1-4" Show="main"> <Template> <div data-dcm-alias="{$_Image.Alias}" class="dc-layout-pad-large entry"> <dc.Link Page="/board/{$_Image.Alias}"> <dc.ImgCache alt="photo of {$_Image.Data.Name}" /> <div class="name dc-align-center"> {$_Image.Data.Name}<br /> <i>{$_Image.Data.Phone}</i> </div> </dc.Link> </div> </Template> </dcm.GalleryWidget>

The changes are minor. Addition of the Show attribute. Removal of the <Image> tags. Switching from using $_Image.Element.@Title to $_Image.Data.Name for the names. And finally the addition of the phone extension just for fun. Everything else is the same. Here is how that displays:

That covers the general uses of (and similarities of) the image related widgets and their templates.