Skip to content

Latest commit

 

History

History
983 lines (705 loc) · 14.6 KB

TESTS.md

File metadata and controls

983 lines (705 loc) · 14.6 KB

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

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

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://slim-lang.com">slim-lang.com</a>

renders as

<a href="http://slim-lang.com">slim-lang.com</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://slim-lang.com" slim-lang.com

renders as

Link to <a href="http://slim-lang.com">slim-lang.com</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://slim-lang.com">slim-lang.com</a>

renders as

<a href="http://slim-lang.com">slim-lang.com</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!

Output =

The equal sign = produces dynamic output.

= 7*7

renders as

49

Dynamic output is escaped by default.

= '<script>evil();</script>'

renders as

&lt;script&gt;evil();&lt;/script&gt;

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 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>

Output with trailing white space ='

The equal sign with apostrophe =' produces dynamic output with a 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>

Output without HTML escaping and trailing ws =='

The double equal sign with apostrophe ==' 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" />

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://slim-lang.com" class="important") Link
li
  a[href="http://slim-lang.com" class="important"] Link
li
  a{href="http://slim-lang.com" class="important"} Link

renders as

<li>
  <a class="important" href="http://slim-lang.com">Link</a>
</li>
<li>
  <a class="important" href="http://slim-lang.com">Link</a>
</li>
<li>
  <a class="important" href="http://slim-lang.com">Link</a>
</li>

If you wrap the attributes, you can spread them across multiple lines:

a(href="http://slim-lang.com"

     class="important") Link

renders as

<a class="important" href="http://slim-lang.com">Link</a>
dl(
  itemprop='address'
  itemscope
  itemtype='http://schema.org/PostalAddress'
)

renders as

<dl itemprop="address" itemscope="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://slim-lang.com" title='Slim Homepage' Goto the Slim homepage

renders as

<a href="http://slim-lang.com" title="Slim Homepage">Goto the Slim homepage</a>

You can use text interpolation in the quoted attributes:

- url='slim-lang.com'
a href="http://#{url}" Goto the #{url}

renders as

<a href="http://slim-lang.com">Goto the slim-lang.com</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=="&amp;" Link

renders as

<li>
  <a href="&amp;">Link</a>
</li>
<li>
  <a href="&amp;">Link</a>
</li>

You can break quoted attributes with 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 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="disabled" type="text" /><input disabled="disabled" type="text" /><input disabled="disabled" type="text" /><input disabled="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" />

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://slim-lang.com/" Slim-lang.com

renders as

<a class="menu highlight" href="http://slim-lang.com/">Slim-lang.com</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 a_unless_current
    @page_current ? {:tag => 'span'} : {:tag => 'a', :href => 'http://slim-lang.com/'}
  end
- @page_current = true
*a_unless_current Link
- @page_current = false
*a_unless_current Link

renders as

<span>Link</span><a href="http://slim-lang.com/">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" />

ID shortcut and class shortcut .

Text interpolation

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 &lt;john@doe.net&gt;!
</h1>

Embedded engines

Configuring Slim

Plugins