Slim test suite
You can run this testsuite with rake test:literate
.
We use pretty mode in the test suite to make the output more readable. Pretty mode is enabled by setting the option
:pretty => true
Line indicators
In this section we test all line indicators.
Text |
A text blocks starts with the |
as line indicator.
| Text block
renders as
Text block
You can add leading or trailing white space with the <
and >
markers:
|< Text with leading whitespace.
| Text with leading whitespace.
|> Text with trailing whitespace.
|<> Text with both leading and trailing whitespace.
renders as
Text with leading whitespace. Text with leading whitespace.Text with trailing whitespace. Text with both leading and trailing whitespace.
Multiple lines can be indented beneath the first text line.
| Text
block
with
multiple
lines
renders as
Text
block
with
multiple
lines
The first line of a text block determines the indentation.
|
Text
block
with
multiple
lines
renders as
Text
block
with
multiple
lines
|><
Text
block
with
multiple
lines
renders as
Text
block
with
multiple
lines
You can nest text blocks beneath tags.
body
| Text
renders as
<body>
Text
</body>
You can embed html code in the text which is not escaped.
| <a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
renders as
<a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
|<a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
renders as
<a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
Text with trailing white space '
A text blocks with trailing white space starts with the '
as line indicator.
' Text block
renders as
Text block
This is especially useful if you use tags behind a text block.
' Link to
a href="http://github.com/slim-template/slim" github.com/slim-template/slim
renders as
Link to <a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
Multiple lines can be indented beneath the first text line.
' Text
block
with
multiple
lines
renders as
Text
block
with
multiple
lines
The first line of a text block determines the indentation.
'
Text
block
with
multiple
lines
renders as
Text
block
with
multiple
lines
Inline HTML <
HTML can be written directly.
<a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
renders as
<a href="http://github.com/slim-template/slim">github.com/slim-template/slim</a>
HTML tags allow nested blocks inside.
<html>
<head>
title Example
</head>
body
- if true
| yes
- else
| no
</html>
renders as
<html><head><title>Example</title></head>
<body>
yes
</body>
</html>
Control code -
The dash -
denotes arbitrary control code.
- greeting = 'Hello, World!'
- if false
| Not true
- else
= greeting
renders as
Hello, World!
Complex code can be broken with backslash \
.
- greeting = 'Hello, '+\
\
'World!'
- if false
| Not true
- else
= greeting
renders as
Hello, World!
You can also write loops like this
- items = [{name: 'table', price: 10}, {name: 'chair', price: 5}]
table#items
- for item in items do
tr
td.name = item[:name]
td.price = item[:price]
which renders as
<table id="items">
<tr>
<td class="name">
table
</td>
<td class="price">
10
</td>
</tr>
<tr>
<td class="name">
chair
</td>
<td class="price">
5
</td>
</tr>
</table>
The do
keyword can be omitted.
- items = [{name: 'table', price: 10}, {name: 'chair', price: 5}]
table#items
- for item in items
tr
td.name = item[:name]
td.price = item[:price]
which renders as
<table id="items">
<tr>
<td class="name">
table
</td>
<td class="price">
10
</td>
</tr>
<tr>
<td class="name">
chair
</td>
<td class="price">
5
</td>
</tr>
</table>
Output =
The equal sign =
produces dynamic output.
= 7*7
renders as
49
Dynamic output is escaped by default.
= '<script>evil();</script>'
renders as
<script>evil();</script>
Long code lines can be broken with \
.
= (0..10).map do |i|\
2**i \
end.join(', ')
renders as
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024
You don't need the explicit \
if the line ends with a comma ,
.
ruby:
def self.test(*args)
args.join('-')
end
= test('arg1',
'arg2',
'arg3')
renders as
arg1-arg2-arg3
You can also disable HTML escaping globally by setting the option
:disable_escape => true
= '<script>evil();</script>'
renders as
<script>evil();</script>
The equal sign with modifier =>
produces dynamic output with a trailing white space.
=> 7*7
renders as
49
=< 7*7
renders as
49
The equal sign with modifier =<
produces dynamic output with a leading white space.
=< 7*7
renders as
49
The equal sign with modifiers =<>
produces dynamic output with a leading and trailing white space.
=<> 7*7
renders as
49
Output without HTML escaping ==
The double equal sign ==
produces dynamic output without HTML escaping.
== '<script>evil();</script>'
renders as
<script>evil();</script>
The option option
:disable_escape => true
doesn't affect the output of ==
.
== '<script>evil();</script>'
renders as
<script>evil();</script>
The double equal sign with modifier ==>
produces dynamic output without HTML escaping and trailing white space.
==> '<script>evil();</script>'
renders as
<script>evil();</script>
The option option
:disable_escape => true
doesn't affect the output of ==
.
==> '<script>evil();</script>'
renders as
<script>evil();</script>
Code comment /
Code comments begin with /
and produce no output.
/ Comment
body
/ Another comment
with
multiple lines
p Hello!
renders as
<body>
<p>
Hello!
</p>
</body>
HTML comment /!
Code comments begin with /!
.
/! Comment
body
/! Another comment
with multiple lines
p Hello!
/!
First line determines indentation
of the comment
renders as
<!--Comment-->
<body>
<!--Another comment
with multiple lines-->
<p>
Hello!
</p>
<!--First line determines indentation
of the comment-->
</body>
IE conditional comment /[...]
/[if IE]
p Get a better browser.
renders as
<!--[if IE]>
<p>
Get a better browser.
</p>
<![endif]-->
HTML tags
Doctype tags
The doctype tag is a special tag which can be used to generate the complex doctypes in a very simple way.
You can output the XML version using the doctype tag.
doctype xml
doctype xml ISO-8859-1
renders as
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="iso-8859-1" ?>
In XHTML mode the following doctypes are supported:
doctype html
doctype 5
doctype 1.1
doctype strict
doctype frameset
doctype mobile
doctype basic
doctype transitional
renders as
<!DOCTYPE html>
<!DOCTYPE html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
If we activate HTML mode with the option
:format => :html
the following doctypes are supported:
doctype html
doctype 5
doctype strict
doctype frameset
doctype transitional
renders as
<!DOCTYPE html>
<!DOCTYPE html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
Closed tags
You can close tags explicitly by appending a trailing /
.
div id="not-closed"
.closed/
#closed/
div id="closed"/
renders as
<div id="not-closed"></div>
<div class="closed" />
<div id="closed" />
<div id="closed" />
Note, that this is usually not necessary since the standard html tags (img, br, ...) are closed automatically.
img src="image.png"
renders as
<img src="image.png" />
Trailing and leading whitespace
You can force a trailing whitespace behind a tag by adding >
.
a#closed> class="test" /
a#closed> class="test"/
a> href='url1' Link1
a< href='url1' Link1
renders as
<a class="test" id="closed" /> <a class="test" id="closed" /> <a href="url1">Link1</a> <a href="url1">Link1</a>
If you combine > and => only one trailing whitespace is added.
a> => 'Text1'
a => 'Text2'
a> = 'Text3'
a>= 'Text4'
a=> 'Text5'
a<= 'Text6'
a=< 'Text7'
renders as
<a>Text1</a> <a>Text2</a> <a>Text3</a> <a>Text4</a> <a>Text5</a> <a>Text6</a> <a>Text7</a>
You can force a leading whitespace before a tag by adding <
.
a#closed< class="test" /
a#closed< class="test"/
a< href='url1' Link1
a< href='url2' Link2
<a class="test" id="closed" /> <a class="test" id="closed" /> <a href="url1">Link1</a> <a href="url2">Link2</a>
You can also combine both.
a#closed<> class="test" /
a#closed>< class="test"/
a<> href='url1' Link1
a<> href='url2' Link2
<a class="test" id="closed" /> <a class="test" id="closed" /> <a href="url1">Link1</a> <a href="url2">Link2</a>
Inline tags
Sometimes you may want to be a little more compact and inline the tags.
ul
li.first: a href="/first" First
li: a href="/second" Second
renders as
<ul>
<li class="first">
<a href="/first">First</a>
</li>
<li>
<a href="/second">Second</a>
</li>
</ul>
For readability, don't forget you can wrap the attributes.
ul
li.first: a(href="/first") First
li: a(href="/second") Second
renders as
<ul>
<li class="first">
<a href="/first">First</a>
</li>
<li>
<a href="/second">Second</a>
</li>
</ul>
Text content
Dynamic content =
Attributes
Attribute wrapper
If a delimiter makes the syntax more readable for you, you can use the characters {...}
, (...)
, [...]
to wrap the attributes.
li
a(href="http://github.com/slim-template/slim" class="important") Link
li
a[href="http://github.com/slim-template/slim" class="important"] Link
li
a{href="http://github.com/slim-template/slim" class="important"} Link
renders as
<li>
<a class="important" href="http://github.com/slim-template/slim">Link</a>
</li>
<li>
<a class="important" href="http://github.com/slim-template/slim">Link</a>
</li>
<li>
<a class="important" href="http://github.com/slim-template/slim">Link</a>
</li>
If you wrap the attributes, you can spread them across multiple lines:
a(href="http://github.com/slim-template/slim"
class="important") Link
renders as
<a class="important" href="http://github.com/slim-template/slim">Link</a>
dl(
itemprop='address'
itemscope
itemtype='http://schema.org/PostalAddress'
)
renders as
<dl itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress"></dl>
You may use spaces around the wrappers and assignments:
h1 id = "logo" Logo
h2 [ id = "tagline" ] Tagline
renders as
<h1 id="logo">
Logo
</h1>
<h2 id="tagline">
Tagline
</h2>
Quoted attributes
You can use single or double quotes for simple text attributes.
a href="http://github.com/slim-template/slim" title='Slim Homepage' Goto the Slim homepage
renders as
<a href="http://github.com/slim-template/slim" title="Slim Homepage">Goto the Slim homepage</a>
You can use text interpolation in the quoted attributes:
- url='github.com/slim-template/slim'
a href="http://#{url}" Goto the #{url}
a href="{"test"}" Test of quoted text in braces
renders as
<a href="http://github.com/slim-template/slim">Goto the github.com/slim-template/slim</a><a href="{"test"}">Test of quoted text in braces</a>
The attribute value will be escaped by default. Use == if you want to disable escaping in the attribute.
li
a href='&' Link
li
a href=="&" Link
renders as
<li>
<a href="&">Link</a>
</li>
<li>
<a href="&">Link</a>
</li>
You can use newlines in quoted attributes
a data-title="help" data-content="extremely long help text that goes on
and one and one and then starts over...." Link
renders as
<a data-content="extremely long help text that goes on
and one and one and then starts over...." data-title="help">Link</a>
You can break quoted attributes with an backslash \
a data-title="help" data-content="extremely long help text that goes on\
and one and one and then starts over...." Link
renders as
<a data-content="extremely long help text that goes on and one and one and then starts over...." data-title="help">Link</a>
Ruby attributes
Long ruby attributes can be broken with backslash \
a href=1+\
1 Link
renders as
<a href="2">Link</a>
You don't need the explicit \
if the line ends with a comma ,
.
ruby:
def self.test(*args)
args.join('-')
end
a href=test('arg1',
'arg2',
'arg3') Link
renders as
<a href="arg1-arg2-arg3">Link</a>
Boolean attributes
The attribute values true
, false
and nil
are interpreted as booleans.
If you use the attribut wrapper you can omit the attribute assigment.
- true_value1 = ""
- true_value2 = true
input type="text" disabled=true_value1
input type="text" disabled=true_value2
input type="text" disabled="disabled"
input type="text" disabled=true
input(type="text" disabled)
renders as
<input disabled="" type="text" /><input disabled="" type="text" /><input disabled="disabled" type="text" /><input disabled="" type="text" /><input disabled="" type="text" />
- false_value1 = false
- false_value2 = nil
input type="text" disabled=false_value1
input type="text" disabled=false_value2
input type="text"
input type="text" disabled=false
input type="text" disabled=nil
renders as
<input type="text" /><input type="text" /><input type="text" /><input type="text" /><input type="text" />
If html5 is activated the attributes are written as standalone.
:format => :html
- true_value1 = ""
- true_value2 = true
input type="text" disabled=true_value1
input type="text" disabled=true_value2
input type="text" disabled="disabled"
input type="text" disabled=true
input(type="text" disabled)
renders as
<input disabled="" type="text"><input disabled type="text"><input disabled="disabled" type="text"><input disabled type="text"><input disabled type="text">
Attribute merging
You can configure attributes to be merged if multiple are given (See option :merge_attrs
). In the default configuration
this is done for class attributes with the white space as delimiter.
a.menu class="highlight" href="http://github.com/slim-template/slim/" github.com/slim-template/slim
renders as
<a class="menu highlight" href="http://github.com/slim-template/slim/">github.com/slim-template/slim</a>
You can also use an Array
as attribute value and the array elements will be merged using the delimiter.
- classes = [:alpha, :beta]
span class=["first","highlight"] class=classes First
span class=:second,:highlight class=classes Second
renders as
<span class="first highlight alpha beta">First</span><span class="second highlight alpha beta">Second</span>
Splat attributes *
Dynamic tags *
You can create completely dynamic tags using the splat attributes. Just create a method which returns a hash with the :tag key.
ruby:
def self.a_unless_current
@page_current ? {tag: 'span'} : {tag: 'a', href: 'http://github.com/slim-template/slim/'}
end
- @page_current = true
*a_unless_current Link
- @page_current = false
*a_unless_current Link
renders as
<span>Link</span><a href="http://github.com/slim-template/slim/">Link</a>
Shortcuts
Tag shortcuts
We add tag shortcuts by setting the option :shortcut
.
:shortcut => {'c' => {tag: 'container'}, 'sec' => {tag:'section'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} }
sec: c.content Text
renders to
<section>
<container class="content">Text</container>
</section>
Attribute shortcuts
We add &
to create a shortcut for the input elements with type attribute by setting the option :shortcut
.
:shortcut => {'&' => {tag: 'input', attr: 'type'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} }
&text name="user"
&password name="pw"
&submit.CLASS#ID
renders to
<input name="user" type="text" /><input name="pw" type="password" /><input class="CLASS" id="ID" type="submit" />
This is stupid, but you can also use multiple character shortcuts.
:shortcut => {'&' => {tag: 'input', attr: 'type'}, '#<' => {attr: 'id'}, '#>' => {attr: 'class'} }
&text name="user"
&password name="pw"
&submit#>CLASS#<ID
renders to
<input name="user" type="text" /><input name="pw" type="password" /><input class="CLASS" id="ID" type="submit" />
You can also set multiple attributes per shortcut.
:shortcut => {'.' => {attr: %w(id class)} }
.test
renders to
<div class="test" id="test"></div>
Shortcuts can also have multiple characters.
:shortcut => {'.' => {attr: 'class'}, '#' => {attr: 'id'}, '.#' => {attr: %w(class id)} }
.#test
.test
#test
renders to
<div class="test" id="test"></div>
<div class="test"></div>
<div id="test"></div>
ID shortcut and class shortcut .
ID and class shortcuts can contain dashes, slashes with digits, and colons.
.-test text
#test- text
.--a#b- text
.a--test-123#--b text
.a-1/2#b-1/2 text
.ab:c-test#d:e text
renders as
<div class="-test">
text
</div>
<div id="test-">
text
</div>
<div class="--a" id="b-">
text
</div>
<div class="a--test-123" id="--b">
text
</div>
<div class="a-1/2" id="b-1/2">
text
</div>
<div class="ab:c-test" id="d:e">
text
</div>
Text interpolation
Use standard Ruby interpolation. The text will be html escaped by default.
- user="John Doe <[email protected]>"
h1 Welcome #{user}!
renders as
<h1>
Welcome John Doe <[email protected]>!
</h1>
Pretty printing of XML
We can enable XML mode with
:format => :xml
doctype xml
document
closed-element/
element(boolean-attribute)
child attribute="value"
| content
<?xml version="1.0" encoding="utf-8" ?>
<document>
<closed-element />
<element boolean-attribute="">
<child attribute="value">
content
</child>
</element>
</document>