Preview templates

A shortcode card in the editor tells you what the parameters are, not what the result looks like. The preview pane is where that happens, and the preview property on a block shortcode is the HTML it uses. Emet can’t run your Hugo templates in the browser, so you give it a simplified stand-in with the field values dropped in.

This mostly affects the preview pane. A block card in the visual editor never renders it; the one place it shows up in the editor is the label on a chip for a shortcode sitting inside a sentence.

Placeholders#

shortcodes:
  figure:
    label: Figure
    fields:
      - name: src
        type: image
      - name: caption
        type: string
    preview: |
      <figure>
        <img src="{{src}}" alt="">
        <figcaption>{{caption}}</figcaption>
      </figure>
Placeholder Replaced with
{{fieldname}} The value of that field
{{content}} The text between the opening and closing tags
{{children}} The rendered previews of the child shortcodes, for containers
{{#if fieldname}}...{{else}}...{{/if}} The first part when the field is set (and isn’t false or 0), otherwise the {{else}} part, which is optional
{{#unless fieldname}}...{{/unless}} The contents only when the field is empty

Positional parameters are matched to fields by order, so {{src}} works for {{< figure "cat.jpg" >}} too. Any placeholder with no value is removed, and values go in as-is, without HTML escaping, so a quote mark in a caption can break your markup. Image src values are rewritten the same way as images in the body, which is what makes pictures in private repositories show up.

The conditionals are for the optional bits of a shortcode, so you don’t end up with an empty <figcaption> when there’s no caption:

preview: |
  <figure>
    <img src="{{src}}" alt="{{alt}}">
    {{#if caption}}<figcaption>{{caption}}</figcaption>{{/if}}
  </figure>

They nest, and that’s the whole language: no loops, no comparisons, no {{else if}}. If you need more than that, it belongs in your real Hugo template, not the preview.

The same interpolation produces the text on an in-flow shortcode’s chip in the editor, with the HTML stripped, so a preview is worth writing even for shortcodes you only ever use mid-sentence.

What the pane shows#

Each block shortcode becomes a small card: a header with the icon and label from its config, and your rendered HTML beneath. A container’s children are rendered inside it as nested cards, unless your template has a {{children}} placeholder, in which case they go where the placeholder is and nowhere else.

The card styling ships with the preview frame, so it looks the same with or without your own preview.styles. If you want it to look different, your styles can target .shortcode-preview and .shortcode-preview-header.

Your site’s CSS, if you’ve configured it, applies to the preview HTML, so the class names in your template can be the ones your real shortcode produces. Without configured styles you get Emet’s built-in typography. Either way the frame runs with scripts disabled: <script> tags and on* attributes are stripped, and an embedded player won’t actually play. A static placeholder with the video ID in it is a more useful preview than a dead iframe.

Shortcodes without a preview#

A configured shortcode with no preview shows as a card with its icon and label in the header and its syntax underneath, {{< name key="value" >}}, in whichever delimiter it was written. A shortcode that isn’t in site.yaml at all gets a generic ⚡ icon and its name instead, and in the editor its card says “Unknown shortcode type. Configure in site.yaml to enable editing.” with no fields. It’s still preserved on save, exactly as it was read.

When you’re running Emet locally with npm run dev, there’s one extra trick: for an unknown shortcode, the dev server looks for layouts/shortcodes/<name>.html (or _shortcodes, or the same in the active theme) and infers a label, fields and a basic preview from the .Get calls in it, the same way the setup wizard does. That only happens in local development, and it’s a fallback rather than a substitute for configuring the shortcode.

Inline shortcodes#

Inline shortcodes have no preview property. Their template is real Go template code, and the preview pane makes a best-effort attempt at rendering it; see Template interpolation.