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
In this section we test all line indicators.
A text blocks starts with the | as line indicator.
| Text blockrenders as
Text blockYou 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
linesrenders as
Text
block
with
multiple
linesThe first line of a text block determines the indentation.
|
Text
block
with
multiple
linesrenders as
Text
block
with
multiple
lines|><
Text
block
with
multiple
linesrenders as
Text
block
with
multiple
lines You can nest text blocks beneath tags.
body
| Textrenders 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>A text blocks with trailing white space starts with the ' as line indicator.
' Text blockrenders 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/slimrenders 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
linesrenders as
Text
block
with
multiple
lines The first line of a text block determines the indentation.
'
Text
block
with
multiple
linesrenders as
Text
block
with
multiple
lines 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>The dash - denotes arbitrary control code.
- greeting = 'Hello, World!'
- if false
| Not true
- else
= greetingrenders as
Hello, World!Complex code can be broken with backslash \.
- greeting = 'Hello, '+\
\
'World!'
- if false
| Not true
- else
= greetingrenders 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>The equal sign = produces dynamic output.
= 7*7renders as
49Dynamic 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, 1024You 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-arg3You 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*7renders as
49 =< 7*7renders as
49The equal sign with modifier =< produces dynamic output with a leading white space.
=< 7*7renders as
49The equal sign with modifiers =<> produces dynamic output with a leading and trailing white space.
=<> 7*7renders as
49 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 comments begin with / and produce no output.
/ Comment
body
/ Another comment
with
multiple lines
p Hello!renders as
<body>
<p>
Hello!
</p>
</body>Code comments begin with /!.
/! Comment
body
/! Another comment
with multiple lines
p Hello!
/!
First line determines indentation
of the commentrenders as
<!--Comment-->
<body>
<!--Another comment
with multiple lines-->
<p>
Hello!
</p>
<!--First line determines indentation
of the comment-->
</body>/[if IE]
p Get a better browser.renders as
<!--[if IE]>
<p>
Get a better browser.
</p>
<![endif]-->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-1renders 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 transitionalrenders 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 transitionalrenders 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">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" />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' Link1renders 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> 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" Secondrenders 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") Secondrenders as
<ul>
<li class="first">
<a href="/first">First</a>
</li>
<li>
<a href="/second">Second</a>
</li>
</ul>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"} Linkrenders 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") Linkrenders 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" ] Taglinerenders as
<h1 id="logo">
Logo
</h1>
<h2 id="tagline">
Tagline
</h2>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 homepagerenders 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 bracesrenders 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=="&" Linkrenders 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...." Linkrenders 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...." Linkrenders as
<a data-content="extremely long help text that goes on and one and one and then starts over...." data-title="help">Link</a>Long ruby attributes can be broken with backslash \
a href=1+\
1 Linkrenders 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') Linkrenders as
<a href="arg1-arg2-arg3">Link</a>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=nilrenders 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">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/slimrenders 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 Secondrenders as
<span class="first highlight alpha beta">First</span><span class="second highlight alpha beta">Second</span>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 Linkrenders as
<span>Link</span><a href="http://github.com/slim-template/slim/">Link</a>We add tag shortcuts by setting the option :shortcut.
:shortcut => {'c' => {tag: 'container'}, 'sec' => {tag:'section'}, '#' => {attr: 'id'}, '.' => {attr: 'class'} }
sec: c.content Textrenders to
<section>
<container class="content">Text</container>
</section>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#IDrenders 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#<IDrenders 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)} }
.testrenders to
<div class="test" id="test"></div>Shortcuts can also have multiple characters.
:shortcut => {'.' => {attr: 'class'}, '#' => {attr: 'id'}, '.#' => {attr: %w(class id)} }
.#test
.test
#testrenders to
<div class="test" id="test"></div>
<div class="test"></div>
<div id="test"></div>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 textrenders 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>Use standard Ruby interpolation. The text will be html escaped by default.
- user="John Doe <john@doe.net>"
h1 Welcome #{user}!renders as
<h1>
Welcome John Doe <john@doe.net>!
</h1>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>