Documentation Index

Fetch the complete documentation index at: https://help.elaine.io/llms.txt

Use this file to discover all available pages before exploring further.

Elaine Markup Language (EML) reference

Prev Next

 Elaine Markup Language (EML) extends HTML and other message content with structure, editable components, personalization fields, conditions, language variants, tracked links, and content variants. It is the technical foundation for reusable, privacy-aware, real-time hyperpersonalization in Elaine templates.

Note

EML templates use tenant-specific data fields, salutation IDs, Datastore fields, Business Rules, and tracking conventions. Confirm these values in the target tenant instead of copying example identifiers unchanged.

Core syntax

[tag attribute(value) other(value)]
content
[/tag]

 Attribute values are not quoted. For example, mime(html) is valid and mime("html") is not. Widget MIME types always use the complex/ prefix, such as mime(complex/input).

Structural elements

                                                                                       
ElementPurpose
[struct]...[/struct]Optional outermost language variant containing one complete document.
[composing]...[/composing]Managed content area containing articles.
[part]...[/part]Content article, inline condition, subject, composition, or nested editor widget.
[part mime(subject)]Your personal update[/part]
<!doctype html>
<html>
<head><title>[subject]</title></head>
<body>
[trackimage]
[composing name(main) mime(html)]
  [part id(0) mime(html) title(introduction)]
    <p>Hello [c_prename],</p>
  [/part]
[/composing]
</body>
</html>

Articles and widgets

 Normal HTML articles use mime(html). Controlled editor components use an outer mime(complex/composition) article and nested widgets such as complex/input, complex/textarea, complex/link, or complex/imagelink.

[part id(0) mime(complex/composition) showmime(html) title(hero)]
  <h2>
    [part mime(complex/input) label(Headline) varname(headline) showmime(html)]
      A relevant headline
    [/part]
  </h2>
[/part]

Widget types

 Widgets are nested [part] elements inside a mime(complex/composition) article. They expose selected content or properties to editors while the surrounding HTML remains controlled by the template. Use a unique varname within the containing article.

                                                                                                                                                                                                                                                                                                     
Widget MIME typeWhat editors can changeTypical use
complex/inputOne line of plain textHeadlines, labels, prices, or short values
complex/simpletextareaMultiple lines of plain textCopy whose formatting is controlled entirely by the template
complex/textareaFormatted rich textEditorial copy with permitted links and text formatting
complex/linkLink text, target, title, and configured presentationText links and calls to action
complex/imageImage source and configured image propertiesUnlinked editorial or product images
complex/imagelinkImage plus its optional linkLinked hero images, banners, and product tiles
complex/switchimageImages and links for configured device classesDevice-dependent image output
complex/switchlinkLink targets for configured device classesDevice-dependent destinations, such as app-store links
complex/listRepeatable items that can be added, removed, and sortedBenefits, navigation entries, product rows, or other repeatable content
complex/indexA generated list of eligible articlesLinked tables of contents for longer messages

Input

 Use complex/input for a single-line value. The surrounding HTML controls its visual presentation.

<h2>
[part mime(complex/input) label(Headline) varname(headline) showmime(html)]
  A relevant headline
[/part]
</h2>

Simple textarea

 Use complex/simpletextarea for multi-line plain text without rich-text formatting controls.

<p class="editorial">
[part mime(complex/simpletextarea) label(Editorial) varname(editorial) showmime(html)]
  First line
  Second line
[/part]
</p>

Rich-text textarea

 Use complex/textarea when editors need permitted formatting such as paragraphs, emphasis, or links. Available toolbar functions can be restricted by configuration.

[part mime(complex/textarea) label(Body) varname(body) showmime(html)]
  <p>Editable <strong>rich text</strong>.</p>
[/part]

 Use complex/link for an editable tracked text link. linktype follows the tenant's tracking conventions.

[part mime(complex/link) label(Call to action) varname(cta)
  linktitle(Learn more) linktype(info) linkurl(https://www.elaine.io)
  showmime(html)]
  <a href="https://www.elaine.io">Learn more</a>
[/part]

Image

 Use complex/image for an editable image that does not require a surrounding link.

[part mime(complex/image) label(Hero image) varname(hero_image)
  imageurl(https://example.com/hero.jpg) imagealt(Product overview)
  showmime(html)]
  <img src="https://example.com/hero.jpg" alt="Product overview">
[/part]

 Use complex/imagelink when editors should manage an image and its optional tracked destination together.

[part mime(complex/imagelink) label(Linked hero) varname(linked_hero)
  imageurl(https://example.com/hero.jpg)
  linkurl(https://www.elaine.io) linktype(info) showmime(html)]
  <a href="https://www.elaine.io">
    <img src="https://example.com/hero.jpg" alt="Elaine">
  </a>
[/part]

Switch image

 Use complex/switchimage to configure different image resources for supported device classes. The configured clients, URL order, and output markup must correspond.

[part mime(complex/switchimage) label(Responsive hero) varname(responsive_hero)
  clients(desk,mobile)
  imageurls(https://example.com/hero-desktop.jpg,https://example.com/hero-mobile.jpg)
  linkurls(https://www.elaine.io,https://www.elaine.io)
  linktype(info) showmime(html)]
  ...configured device-dependent image output...
[/part]

 Use complex/switchlink when the visible call to action remains consistent but its destination depends on the detected device class.

[part mime(complex/switchlink) label(Get the app) varname(app_link)
  clients(desk,ios,android)
  linkurls(https://example.com/app,https://apps.apple.com/app,https://play.google.com/store)
  linktitle(Get the app) linktype(info) showmime(html)]
  <a href="https://example.com/app">Get the app</a>
[/part]

List

 Use complex/list for repeatable and sortable items. Header and footer attributes define the wrapper; item header and footer attributes define each entry.

[part mime(complex/list) label(Benefits) varname(benefits) showmime(html)
  listheader(<ul>) listfooter(</ul>)
  listitemheader(<li>) listitemfooter(</li>)
  listitem_0(First benefit) listitem_1(Second benefit)]
  <ul><li>First benefit</li><li>Second benefit</li></ul>
[/part]

Index

 Use complex/index to render linked entries for eligible articles in an indexed composing box. Article attributes such as indexlabel, indexkey, and hideindex control participation.

[part mime(complex/index) label(Table of contents) varname(toc)
  listheader(<ul>) listfooter(</ul>)
  listitemheader(<li>) listitemfooter(</li>)
  showmime(html)]
[/part]

Note

These examples show the core widget structure. Optional attributes, editor settings, client identifiers, tracking types, and rendered HTML can differ by tenant and template. Preserve known working attributes or confirm the target configuration instead of inventing values.

 A stored or top-level content article requires title(...). Nested widgets and mime(subject) parts do not. The form mime(input) is invalid.

Personalization and realtime resolution

 Available fields are inserted in brackets, for example [c_prename]. During rendering, Elaine can combine CRM and profile data with event or transaction context, Datastore values, recommendations, product and content information, intent signals, and values prepared by Business Rules.

 Depending on the integration design, additional data can be queried live, prepared before rendering, or provided through intelligent caching. Therefore, “real time” describes resolution during the rendering and decision process; it does not mean that every connected source is queried live for every recipient.

Conditional content

[part id(0) mime(html) title(premium_offer) condition(c_status=premium)]
  <p>Your premium offer.</p>
[/part]

 Conditions support equality and ordered comparisons, string matching, logical AND and OR, negation, exclusive OR, and grouped expressions. Reserved characters inside EML attributes must be escaped. For example, [ becomes (5B), ] becomes (5D), ( becomes (28), and ) becomes (29).

AIDO variants

 The testingvariant(...) attribute is valid only on normal, non-complex/... content parts. Do not add it to complex composition articles or widgets.

[part id(0) mime(html) title(offer_a) testingvariant(0:0)]
  <p>Benefit-led content.</p>
[/part]
[part id(0) mime(html) title(offer_b) testingvariant(0:1)]
  <p>Curiosity-led content.</p>
[/part]

Agent-ready instructions

 Want to create or validate EML from an AI assistant, coding agent, or other AI environment? Download the compact instruction file and add it to the agent's context:

 Download the Elaine EML instructions for AI agents (Markdown)

 The downloadable file contains strict generation rules, examples, condition operators, escaping rules, an HTML-to-EML conversion procedure, and an agent validation checklist.