A template's layers are stored as JSON in the Layout JSON field. The canvas size, background colour and background image are separate form fields, not part of the JSON.
Structure
{
"layers": [
{ "type": "rect", "x": 0, "y": 0, "width": 4, "height": 630, "color": "#6366f1" },
{ "type": "text", "content": "{{item.title}}", "x": 60, "y": 120,
"font_size": 52, "font_weight": "700", "color": "#ffffff",
"max_width": 680, "max_lines": 3, "line_height": 1.2 },
{ "type": "image", "src": "{{item.thumbnail_url}}", "fallback": "{{site.logo_url}}",
"x": 820, "y": 0, "width": 380, "height": 630, "fit": "cover" }
]
}
Layers are drawn in array order. A layer without a type, or with an unknown type, is skipped. An error while drawing one layer does not stop the others.
Geometry
x, y, width and height are integers in pixels by default. Two alternatives are accepted by the renderer but not exposed in the editor fields:
- Set
"unit": "percent"on a layer to interpret all four values as percentages of the canvas. - Give an individual value as a string ending in
%, for example"max_width": "60%".
Text layer
| Key | Default | Notes |
|---|---|---|
content |
Text with {{variables}}. Empty content draws nothing. |
|
x, y |
0 |
Left edge of the text box, and its top, middle or bottom (see anchor). |
font_size |
24 |
Pixels, as in the editor. A line's baseline is 0.8 × font_size below its top. |
font_weight |
"400" |
bold, 700, 800 or 900 select the bold face. |
font_family |
"Inter" |
A bundled or registered family (see Fonts); falls back to Inter when unknown. |
font_style |
"normal" |
italic selects the italic face, where the family has one. |
color |
#ffffff |
Hex colour. Invalid values fall back to white. |
max_width |
canvas width minus x |
Wrap width in pixels. |
max_lines |
10 |
Extra lines are dropped; the last kept line is trimmed with an ellipsis. |
line_height |
1.3 |
Multiplier of font_size. |
align |
left |
left, center or right within max_width. |
anchor |
top |
Whether y is the top, middle or bottom of the lines drawn. |
letter_spacing |
0 |
Extra pixels between letters. |
background |
none |
solid draws a box of background_color behind each line. |
background_color |
#000000 |
Colour of that box. |
padding |
8 |
How far the box reaches beyond the line's capital letters, in pixels. |
Rectangle and line layers
| Key | Default | Notes |
|---|---|---|
x, y, width, height |
0 |
Filled rectangle. line is rendered identically to rect. |
color |
#ffffff |
Hex colour. |
opacity |
1 |
0 (invisible) to 1 (solid). |
gradient |
none |
down or right blends from color at opacity to gradient_to at opacity_to. |
gradient_to |
color |
The gradient's end colour. |
opacity_to |
opacity |
The gradient's end opacity. |
Image layer
| Key | Default | Notes |
|---|---|---|
src |
Image URL, may contain variables. | |
fallback |
Used when src resolves to an empty string. |
|
x, y, width, height |
0 |
Layers with zero width or height are skipped. |
fit |
cover |
cover (crop to fill), contain (whole image inside the box) or fill (stretch). |
inset |
0 |
Pixels between the box's edge and the image. |
matte |
none |
Fill the box behind the image: color with matte_color, or auto with the median colour around the image's edge. |
matte_color |
#ffffff |
Used when matte is color. |
feather |
0 |
Fades the image's edges to transparent over this many pixels. |
overlay_color, overlay_opacity |
#000000, 0 |
Colour tint over the image (over the whole box when it has a matte); opacity 0 to 1. |
fade_edge, fade_color, fade_strength |
none, #000000, 0.8 |
Gradient from top, bottom, left or right. |
border_radius |
0 |
Rounds the image's corners (the box's, when it has a matte). Half the shorter side makes a circle. |
rotation |
0 |
Degrees clockwise about the box's centre. The corners are not cut off. |
shadow_blur, shadow_offset_x, shadow_offset_y, shadow_color |
0, 0, 0, rgba(0,0,0,0.5) |
Drop shadow in the image's own shape. shadow_color accepts rgba(r,g,b,a), rgb(r,g,b) or hex (at half opacity). Blur needs Imagick. |
How image URLs are loaded
An image that cannot be loaded draws nothing, not even its shadow.
Before fetching, the renderer tries to map the URL to a local file: for an absolute http(s) URL it takes the path component and looks for that file under the Omeka root; for a relative path it prepends the Omeka root. Files in Omeka's local files/ store are therefore read straight from disk. Anything else is fetched with file_get_contents, which requires allow_url_fopen and network access from the server. Unreadable or undecodable images are skipped silently.
Background
The template's Background color fills the canvas first. If Background image URL is set it is interpolated, loaded the same way as an image layer and drawn with cover fit across the whole canvas, before any layers.
Fonts
These families are bundled in modules/OgImages/asset/font, with their licences (SIL Open Font License, and the Bitstream Vera licence for DejaVu) in its licenses folder:
font_family |
Faces |
|---|---|
Inter |
Regular, Bold |
Gelasio |
Regular, Bold, Italic, Bold Italic |
Saira Condensed |
Medium (as regular), Bold |
DejaVu Sans Mono |
Regular, Bold |
A family without the face asked for uses its regular face, and an unknown family uses Inter. Additional families can be registered by developers through the og_images_fonts global setting, a JSON-encoded array of objects with family and regular_file, bold_file, italic_file or bold_italic_file keys, where the files are placed in the same font directory. There is no admin UI for this setting. Registered families are offered in the editor's Font list, and a layer selects one with font_family.
Rendering without TrueType support
If GD was built without FreeType, text is drawn with GD's built-in bitmap font 5 at a fixed size, wrapped by character count. Font size, weight and family are ignored in that mode.