Jael syntax is a superset of HTML. The following is valid both in HTML and Jael:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Title</title>
  5. </head>
  6. <body>
  7. <h1>Hello!</h1>
  8. </body>
  9. </html>

However, Jael adds two major changes.

Interpolation

Firstly, text blocks can contain interpolations, which are merely Dart expression contained in double curly braces ({{ }}). The value within the braces, once evaluated will be HTML escaped, to prevent XSS. To achieve unescaped output, append a hyphen (-) to the first brace ({{- }}).

  1. <div>
  2. {{ user.name }}
  3. </div>
  4. <!-- Do not HTML escape this: -->
  5. <div>
  6. {{- raw.data.will.not.be('escaped') }}
  7. </div>

Attributes

Secondly, whereas in HTML, the values of attributes can only be strings, Jael allows for their values to be any Dart expression:

  1. <img src=profile.avatar ?? "http://example.com/img/avatars/default.png">
  2. <a class=['btn', 'ban-default', 'btn-lg']>Link</a>
  3. <p style={'color': 'red'}></p>

Attribute Values

Values are handled as such:

  • Maps: Serialized as though they were style attributes.
  • Iterables: Joined by a space, like class attributes.
  • Anything else: toString() is invoked.

Quoted Attribute Names

In case the name of your attribute is not a valid Dart identifier, you can wrap it with quotes, and it will still be processed as per normal:

  1. <button "(click)"="myEventHandler($event)" />

Unescaped Attributes

These will also be HTML escaped; however, you can replace = with != to print unescaped text:

  1. <img src!="<SCARY XSS STRING BEWARE!!!>" />