Skip to content
Bago edited this page Feb 28, 2018 · 17 revisions

Work in progress

We currently have a complete "low level" template language: we are working on a simpler template language to get started solving most content-editing issues without the need to learn a whole language... Stay tuned, and contact us to let us know your needs, so we can take them into consideration for the next releases!

Where to start

Take a look at the tutorial: https://github.com/voidlabs/mosaico/blob/master/templates/tutorial/mosaico-tutorial.md

Creating a new template

  • Create a new directory in 'templates', eg: 'mytemplate'
  • Create your template file inside it, eg: 'mytemplate/template-mytemplate.html'
  • Enable your template by editing Mosaico's 'index.html'. Look for the 'viewModel' initialization and add your template reference there.

Note: you can have a look at this project to see we automatically create thumbnails for the versafix template.

STEP1: Defining blocks

As a start you need a data-ko-container="main" on the wrapper tag that contains your blocks and a data-ko-block="nameOfYouBlock" in each children of this container that you want to be draggable/droppable in the container.

At this time you can only have a single "container" and it has to be named "main".

Make sure the container is not a TABLE because the browser will ad a TBODY tag that will be the only children. So data-ko-container should be added to a DIV or a TD. Also, at this time it is not supported to use it on TBODY because we don't support having blocks defined on TR tags. Your blocks should be defined in TABLE tags (this is also a best practice for creating email because some email client is not happy to have one big long table, and it is better to have separate tables that looks like a single one.

Blocks can be defined as "standalone" (not inside a container) or as children of the container: in the latter case you cannot have more tags between the container and the blocks.

data-ko-block="internalNameOfYourBlock" attribute must be added to every block your want to define. children of a data-ko-container not including the data-ko-block will be discarded (your can use to sample your template when you open it in a browser, but they will be dropped by mosaico).

Use the "Block" postfix when you name your block.

Also make sure running an html validator in your template so to avoid wasting time in weird behaviours: mosaico parser may not be forgiving like your browser.

Once you defined your blocks you should be able to run the makeThumbs script and to load your template in mosaico: it should give you on the left the list of your draggable blocks with their thumbnails and on the right you should see your template where data-ko-container has been emptied and accept your blocks to be dropped there.

WARNING

Here is just a raw list of language constructs: at this time you can't easily learn from this document.

We think that creating a good email template nowadays is really hard and needs a smart developer: if you are smart enough to create a good email template that will work fine in Outlook 2016 for Windows, in Gmail for Android, in Outlook.com Webmail and other weird environments then you will probably find easy to put your hands in our existing template and learn how it works by trial and error.

If you don't know how Outlook 2016 requires conditional comments and how each client will "break" your template then you probably better should simply USE versafix with no attempts to alter it or create a new template.

If you understood part of the language but need more help, then a good way to ask for more help is to provide a PR with improvements to the documention you already understood :-)

That said, get in touch with us so we know there is interest in learning Mosaico template-language! We'll be happy to help anyone that will show to have tried for a while with no success.

Current language structures

data-ko Attributes:

data-ko-display="condition" => the element and children are displayed only when condition is true. When you use this attribute for a "hidden by default" element, then add a style="display: none" to your element, so that the preview of the html will match your default version. Mosaico will remove the display none when interpreting this attribute.

data-ko-wrap="condition" => if condition is false this element is removed (but the content is kept) when the mailing is previewed and downloaded. However the element will always appear in the 'editor' view, regardless of whether the condition is true or false.

data-ko-container="main" (container name must be "main" at this time) => defines the block container

  • at this time you can't use this on TABLE or TBODY or TR. Use it on TD or DIV tags.

data-ko-block="blockname" => defines a new block

data-ko-editable="propname" => define an editable content (image or text)

  • for img: data-ko-placeholder-height/data-ko-placeholder-width
  • for inline elements, or for div: mosaico automatically use the multiline editing (and the big toolbar) when you use data-ko-editable on TD or DIV tags while it uses the single line editing (and the smaller toolbar) when you use it on other tags.

data-ko-link="propname" => alias for data-ko-unwrap + -ko-attr-href

-ko-properties as CSS styles:

-ko-bind-text: @prop => replaces the content of the tag with the text contained in prop variable

-ko-bind-html: @prop => replaces the content of the tag with the html contained in prop variable

-ko-attr-#attrname#: @prop => replaces the value of the attribute #attrname# with the value of prop

-ko-#propertyname#: @prop => replaces the value of the CSS property #propertyname# with the value of prop variable.

Shorthands

border-color: red transparent; -ko-border-color: @borderColor transparent;

Values needing non spaced concatenation

font-size: 30px; -ko-font-size: @[vertical]px; background-image: url('background.png'); -ko-background-image: url('@[backgroundSrc]');

Expressions

width: 50px 3px; -ko-width: @[100 - imageWidth]px 3px;

Ternary

width: 50px 3px; -ko-width: @[imageWith]px @[imageWith > 100 ? 10 : 5]px;

ADVANCED

<style>
@supports -ko-blockdefs {
  type { 
    label: ...;
    widget|extend|properties: ...;
    help: ....;
  }
  type:preview { ... }
}
</style>

The section "@supports -ko-blockdefs {}" is declared in a way similar to CSS styles but they are no way related to CSS styles. We needed a way for the template author to declare object/properties/content types and much more and we already had a CSS parser for mosaico, so we decided that the "DSL" for the template could have been declared using a CSS-like syntax. In order to make it "CSS valid" we abused the @supports css keyword.

This section declares classes/types you will use inside your template and the way properties will be edited, which label the editor will show, their constraint, their help, the available options, wether they are style or content properties, simple or complex types.

This about it as "class/type definition". From "versafix":

size { label: Size; widget: select; options:
8|9|10|11|12|13|14|15|16|18|20|22|25|28|31; }

This define a "size type" (or "size class"). if you use a size typed variable in your template then you'll get a "select widget" with the defined options and the label will be "Size".

image { label: Image; properties: src url alt }

This define the "image type" (or "image class"). In this case this is not a basic type, but this is a composition of 3 subtypes "src", "url" "alt".. three properties/types defined in the same way we defined "size" above.

So in your template you will use image.src to define the src property, image.url to define the url and image.alt to define the alt.

One important thing is that there is a "magic autodeprefix" so when you try to use a variable named "myImage" mosaico will try to see if you defined it as "myImage" (in the @supports section) and if it doesn't find it, it will look for "image" (camel-case deprefixing) and so on.

We probably should provide a "standard library" with most of this stuff already defined so that you can simply start using them, but at this time almost everything has to be defined.

The idea is you use "image" and "image.url" "image.src" "image.alt" instead of imageUrl, iamgeSrc, imageAlt so that the editor knows they have to be grouped on the left and that they are somehow linked (so when you select an image on the right side having the data-ko-editable="myImage.src" then the "myImage" object is also highlighted in the "Content tab" on the left.

Each type/class declaration can declare a "label" and can be a "base type" (declaring the editing "widget") or "extend a type" (declaring "extend" and the referenced type) or a complex object (declaring the "properties"). Then you may find other kind of modifiers (like "help", "options") that maybe you'll get on your own.

You can see also type:preview {} selector: this is advanced stuff used to create the "rounded previews" in the style tab for content styles.

notes

When referencing a variable for the first time it will be automatically defined.

When you use -ko-attr-* or -ko-* it must be preceded by the related attribute/property that will be used as default value.

HTMML

When you start having many blocks with many editable properties, your HTML will become bigger and bigger and harder to be maintained. We created HTMML mainly to help with this and versafix-template is created using HTMML.