Markup Syntax

Components are the building blocks of Ink files. Documents and page level markup are written in .ink files. Components and templates are written in .ink files. In both cases, the code is written in a superset of HTML. The four sections that make up a ink file — imports, script, styles and markup — are all optional and can be used in any order. <!-- imports go here --> <style> /* styles go here */ </style> <script> // logic goes here </script> <!-- HTML goes here -->

Imports

Imports are used to include additional components, templates and stylesheets in the current component. Components can be imported as a template or component type. <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/prism.min.css" /> <link rel="stylesheet" type="text/css" href="/styles/layout.css" /> <link rel="import" type="template" href="@/components/html-head.ink" /> <link rel="import" type="component" href="@/components/i18n/translate.ink" name="i18n-translate" /> <style> /* styles go here */ </style> <script> // logic goes here </script> <!-- HTML goes here --> The rel attribute specifies the relationship between the current document and the linked resource. rel="import" denotes that the imported resource is a component or template. The type attribute specifies the type of the linked resource. type="component" imports a web component that can be used as regular markup with attributes and children. type="template" imports a template partial that can be included in the current markup. Template partials do not process attributes or children if given. The href attribute specifies the URL of the linked resource. The name attribute specifies the tag name of the imported component or template.

Styles

CSS styles inside a <style> block enables the native shadow DOM and will be scoped only to that component. Additionally styles defined outside of the component such as global styles will not affect the component. External stylesheets can be imported using the <link> tag or using @import() CSS directive. You can use host selectors to style an element from within a component. The :host pseudo-class always applies styles to the root element of the web component. <style> :host { display: block; } </style> You can also add conditional styles using the :host selector function. This can be used to style the host so long as it matches the given selector. For example, it can be used to select for hosts that have a given attribute or class. <style> :host([active]) { background-color: #333; color: #FFF; } :host(.active) { background-color: #333; color: #FFF; } </style>

Scripts

The <script> block is used to write TypeScript logic for the component. The script block can be used to define variables, functions, and event listeners. Variables declared (or imported) at the top level are 'visible' from the component's markup. <script> const title = 'Hello World'; </script> <h1>{title}</h1> The <script> block can also be used to import variables from other components to be used in the markup. <script> import getTitle from './getTitle'; const title = getTitle(); </script> <h1 title={title}>{title}</h1> You can use @/ to prefix the current working directory. This is useful when importing files completely in a separate directory in your project <script> import getTitle from '@/data/getTitle'; const title = getTitle(); </script> <h1 title={title}>{title}</h1>

Markup

In order to be closer to the native, Ink follows the same standards and conventions as HTML5 web components. Ink components are compiled to native web components that possibly can be used in other projects any modern browser.

Tag Names

For web components it's recommended that tag names must have at least one dash (-) in them. As such you probably want to name your element with two distinct words like i18n-translate. You can use as many dashes as you want, you're not limited to one. Some specific rules to follow in order to make a valid tag name:
    It must use all lowercase characters of the alphabet (a-z). It must contain at least one dash (-). Ink will auto prefix component names based on your configuration. It must not be an already reserved tag name including annotation-xml, color-profile, font-face, font-face-src, font-face-uri, font-face-format, font-face-name, and missing-glyph. It must not contain symbols, like =, @, $. It can contain underscores, and numbers. It can contain characters from different alphabets, such as é, ð, ö, 爱.
Additionally, Ink works best with correct markup. The following standards should be followed:
    Self closing tags like <img />, <link />, <meta />, <input /> must have a slash before the closing. When using tables, rows should be wrapped in a <tbody> tag and cells should be wrapped in a <tr> tag. ie. <table><tbody><tr><td> When using lists, items should be wrapped in a <ul> or <ol> tags. ie. <ul><li>
Warning: Any markup auto corrected by browser will cause data syncing issues with Ink. Ink components can loosely be self closing <i18n-translate /> or expressed as a block <i18n-translate></i18n-translate>.

Attributes

<a title={title} {href} {...attributes}> {title} </a> <i18n-translate title=title> {detail} </i18n-translate> Attributes can be bound to expressions using the {} syntax. Expressions can be variables, functions, or any valid JavaScript expression. By default, attributes work exactly like their HTML counterparts.
<button type="button" disabled>Submit</button>
Traditional HTML attributes can be assigned string values or no value evaluates as true. <a title={title}>Click</a> Attributes can be assigned variable names. <a title=title>Click</a> Variable names do not need to be wrapped in curly braces {}. <a {title}>Click</a> Attributes with the same name as a variable can be assigned by just wrapping curly braces. ie. {title}.
<script> const attributes = { target: '_blank' }; </script> <a {...attributes}>Click</a>
Spread operators can be used to assign multiple attributes.
<script> let count = 10 const metadata = { foo: 'bar', baz: 1, qux: true }; const data = () => metadata </script> <a {count} get={data} data-meta={metadata} disable={count < 10}> Click </a>
You can assign any valid JavaScript expression to an attribute.

Conditionals

<if true={count > 10}> <p>Count is greater than 10</p> <elif true={count < 5} /> <p>Count is less than 5</p> <else /> <p>Count is between 5 and 10</p> </if> Conditionals can be used to show or hide elements based on the value of a variable.
<if true={count > 10}> <p>Count is greater than 10</p> </if>
The basic syntax for an if statement looks like this and can be truesy or falsey.
<if false={count > 10}> <p>Count is not greater than 10</p> </if>
You can also use the false attribute to negate the condition.
<if true={count > 10}> <p>Count is greater than 10</p> <else /> <p>Count is less than or equal to 10</p> </if>
You can use the else block to show content when the condition is false. <if true={count > 10}> <p>Count is greater than 10</p> <elif true={count < 5} /> <p>Count is less than 5</p> </if> You can use the elif block to show content when the previous condition is false.

Iterations

<each key=index value=article from=articles> <h1>#{index + 1} {article.title}</h1> <p>{article.body}</p> </each> The <each> block can be used to iterate over an array of items or objects. The from attribute value is required and can be an array, object or JavaScript expression that evaluates to an array or object. Both the key and value attributes are optional.
<each value={article} from={articles}> <h1>{article.title}</h1> <p>{article.body}</p> </each>
The value of value, in this case article can be used only with in the block. This can be any valid JavaScript variable name. <each key={index} from={[1, 2, 3]}> <h1>#{index} ???</h1> </each> The value of key, in this case index can be used only with in the block. This can be any valid JavaScript variable name.

Try/Catch

<try> <p>{mayCauseError()}</p> <catch error={e} /> <p>Error: {e.message}</p> </try> The <try><catch> block can be used to catch errors that occur in the block. The <catch> block is required and can be used to handle the error. The value of error, in the <catch> block in this case e is an Error object that can only be used with in the block.