Tags map directly to the DOM tag with that name. If the tag is omitted it is assumed to be a div.
h1
span
input
divIds begin with # just like the CSS selector for them. If a tag has an id it must be before any classes. An element can have zero or one id.
The tag may be omitted and assumed to be a div.
#main
#hero
nav#nav
form#my-formClasses begin with a . just like the CSS selector for them. An element can have zero or more classes.
img.avatar
a.button
button.primary
.tool.eraserContent that appears after an element treated as the text content of the element.
ul
li A
li List
li of
li ItemsBlocks of text content can be nested using the "plain" filter.
.content
:plain
Hello this is some
nested text content
It sure is!Attributes are declared inside (...), just like regular HTML attributes. Multiple attributes are separated by spaces.
form(action="/login")
input(type="text" value=@name)
button(click=@accept) Ok!Attributes have a shorthand notation when the name is the same as the method:
input(@value)
button(@click) Radical!If attributes are present they must occur after any ids or classes.
button#primary.flat(click=@activate) ActivateThe structure of a document is determined by the nesting.
nav
a.home Home
a.about AboutUnbuffered code is evaluated but it's result is not included in the output. You may use it to declare variables or for regular CoffeeScript control flow.
.main
- if @loggedIn
a Log Out
- else
a Log InBuffered code begins with an =. It can be inline or nested. The code is evaluated at runtime and it is converted into a string and inserted as text content. If the method is an observable or a function that depends on other observable the content will be updated when any of the observable dependencies change.
.person
.name
= @first
= @last
You can insert CoffeeScript or JavaScript code or verbatim text using filters.
coffeescript:
alert "cool"
javascript:
alert("hey");
textarea
verbatim:
.example
This will end up as text in the text area is is