PageRenderTime 129ms CodeModel.GetById 56ms app.highlight 64ms RepoModel.GetById 1ms app.codeStats 0ms

/scalate-website/src/documentation/_scaml-reference.md

http://github.com/scalate/scalate
Markdown | 1484 lines | 1231 code | 253 blank | 0 comment | 0 complexity | ff30dcd1cb2f8547be37ea76772a1001 MD5 | raw file
   1# Scaml (Scala Markup Language)
   2
   3{:toc}
   4
   5Scaml is a very DRY way of writing XHTML templates.  It is Scala
   6version of [Haml](http://haml-lang.com/). Scaml functions as a replacement
   7for inline page templating systems such as PHP, ERB, and ASP. However,
   8Scaml avoids the need for explicitly coding XHTML into the template,
   9because it uses a very concise white space active XHTML notation.
  10
  11## Features
  12
  13* Whitespace active
  14* Well-formatted markup
  15* DRY
  16* Follows CSS conventions
  17* Integrates Scala code
  18* [Haml](http://haml-lang.com/) or [Jade](http://jade-lang.com/) style 
  19  notation
  20
  21## Haml vs Jade Notation {#jade}
  22
  23Scaml supports both the original [Haml](http://haml-lang.com/) notation and a
  24newer [Jade](http://jade-lang.com/) notation. The Jade dialect of Haml
  25recognizes that Haml based notations are best used for rendering structured
  26XHTML markup and that content is best rendered using something like markdown.
  27It therefore, simplifies the element notation in exchange for complicating the
  28plain content notation.
  29
  30{pygmentize_and_compare::}
  31-----------------------------
  32scaml: An example .scaml file
  33-----------------------------
  34%html
  35  %body
  36    The quick brown fox jumps 
  37    over the lazy dog
  38-----------------------------
  39jade: An equivalent .jade file
  40-----------------------------
  41html
  42  body
  43    | The quick brown fox jumps 
  44    | over the lazy dog
  45{pygmentize_and_compare}
  46
  47Both examples above will render to the following:
  48
  49{pygmentize:: xml}
  50<html>
  51  <body>
  52    The quick brown fox jumps 
  53    over the lazy dog
  54  </body>
  55</html>
  56{pygmentize}
  57
  58The only difference between the Haml and Jade notation styles
  59are that in the Jade notation style:
  60
  61* Elements do not get prefixed with `%`
  62* Plain text sections must be prefixed with `|`
  63
  64The rest of this document will assume you are using the Haml notation
  65style.  All the examples will work with the Jade notation provided
  66you apply the differences listed above.
  67
  68## Plain Text
  69
  70A substantial portion of any HTML document is its content, which is plain old
  71text. Any Scaml line that's not interpreted as something else is taken to be
  72plain text, and passed through unmodified.
  73
  74For example:
  75
  76{pygmentize_and_compare::}
  77-----------------------------
  78scaml: example
  79-----------------------------
  80%gee
  81  %whiz
  82    Wow this is cool!
  83-----------------------------
  84xml: renders to
  85-----------------------------
  86<gee>
  87  <whiz>
  88    Wow this is cool!
  89  </whiz>
  90</gee>
  91{pygmentize_and_compare}
  92
  93Note that HTML tags are passed through unmodified as well.
  94If you have some HTML you don't want to convert to Scaml,
  95or you're converting a file line-by-line,
  96you can just include it as-is.
  97
  98{pygmentize_and_compare::}
  99-----------------------------
 100scaml: example
 101-----------------------------
 102%p
 103  <div id="blah">Blah!</div>
 104-----------------------------
 105xml: renders to
 106-----------------------------
 107<p>
 108  <div id="blah">Blah!</div>
 109</p>
 110{pygmentize_and_compare}
 111
 112### Escaping: `\`
 113
 114The backslash character escapes the first character of a line,
 115allowing use of otherwise interpreted characters as plain text.
 116
 117{pygmentize_and_compare::}
 118-----------------------------
 119scaml: example
 120-----------------------------
 121%title
 122  = title
 123  \= title
 124-----------------------------
 125xml: renders to
 126-----------------------------
 127<title>
 128  MyPage
 129  = title
 130</title>
 131{pygmentize_and_compare}
 132
 133## HTML Elements
 134
 135
 136### Element Name: `%`
 137
 138The percent character is placed at the beginning of a line.
 139It's followed immediately by the name of an element,
 140then optionally by modifiers (see below), a space,
 141and text to be rendered inside the element.
 142It creates an element in the form of `<element></element>`.
 143
 144{pygmentize_and_compare::}
 145-----------------------------
 146scaml: example
 147-----------------------------
 148%one
 149  %two
 150    %three Hey there
 151-----------------------------
 152xml: renders to
 153-----------------------------
 154<one>
 155  <two>
 156    <three>Hey there</three>
 157  </two>
 158</one>
 159{pygmentize_and_compare}
 160
 161Any string is a valid element name;
 162Scaml will automatically generate opening and closing tags for any element.
 163
 164### Attributes: `{` `}` or `(` `)` {#attributes}
 165
 166Brackets represent a Scala Map
 167that is used for specifying the attributes of an element.
 168Ruby hash syntax is used instead of Scala syntax to 
 169preserve a higher level of compatibility with the original
 170Haml implementation.
 171It is translated and evaluated as a Scala Map,
 172so logic will work in it and local variables may be used.
 173Quote characters within the attribute
 174will be replaced by appropriate escape sequences.
 175The hash is placed after the tag is defined.
 176
 177{pygmentize_and_compare::wide=true}
 178-----------------------------
 179scaml: example
 180-----------------------------
 181%html{:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => "en", :lang => "en"}
 182-----------------------------
 183xml: renders to
 184-----------------------------
 185<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"></html>
 186{pygmentize_and_compare}
 187
 188Attribute hashes can also be stretched out over multiple lines
 189to accommodate many attributes.
 190However, newlines may only be placed immediately after commas.
 191
 192{pygmentize_and_compare::wide=true}
 193-----------------------------
 194scaml: example
 195-----------------------------
 196%script{:type => "text/javascript",
 197        :src  => "javascripts/script"}
 198-----------------------------
 199xml: renders to
 200-----------------------------
 201<script type="text/javascript" src="javascripts/script"/>
 202{pygmentize_and_compare}
 203
 204Complex expressions are supported if you wrap them between the `{` 
 205and `}` characters.
 206
 207{pygmentize_and_compare::}
 208-----------------------------
 209scaml: example
 210-----------------------------
 211%li{:counter={3+4}} Stuff
 212-----------------------------
 213xml: renders to
 214-----------------------------
 215<li counter="7">Stuff</li>
 216{pygmentize_and_compare}
 217
 218#### HTML-style Attributes: `()`
 219
 220Scaml also supports a terser, less Scala-specific attribute syntax
 221based on HTML's attributes.
 222These are used with parentheses instead of brackets, like so:
 223
 224{pygmentize:: scaml}
 225%html(xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en")
 226{pygmentize}
 227
 228Scala variables can be used by omitting the quotes.
 229For example:
 230
 231{pygmentize:: scaml}
 232%a(title=title href=href) Stuff
 233{pygmentize}
 234
 235This is the same as:
 236
 237{pygmentize:: scaml}
 238%a{:title =>title, :href => href} Stuff
 239{pygmentize}
 240
 241Complex expressions are supported if you wrap them between the `{` 
 242and `}` characters.
 243
 244{pygmentize_and_compare::}
 245-----------------------------
 246scaml: example
 247-----------------------------
 248%li(counter={3+4}) Stuff
 249-----------------------------
 250xml: renders to
 251-----------------------------
 252<li counter="7">Stuff</li>
 253{pygmentize_and_compare}
 254
 255You can use both syntaxes together:
 256
 257{pygmentize:: scaml}
 258%a(title="Hello"){:href => "http://scalate.fusesource.org"} Stuff
 259{pygmentize}
 260
 261You can also use `#{}` interpolation to insert complicated expressions
 262in a HTML-style attribute:
 263
 264{pygmentize:: scaml}
 265%span(class="widget_#{widget.number}")
 266{pygmentize}
 267
 268HTML-style attributes can be stretched across multiple lines
 269just like hash-style attributes:
 270{pygmentize:: scaml}
 271%script(type="text/javascript"
 272        src="javascripts/script")
 273{pygmentize}
 274
 275<!-- TODO
 276#### Attribute Methods
 277
 278A Scala method call that returns a hash
 279can be substituted for the hash contents.
 280For example, Scaml::Helpers defines the following method:
 281
 282    def html_attrs(lang = "en-US")
 283      {:xmlns => "http://www.w3.org/1999/xhtml", "xml:lang" => lang, :lang => lang}
 284    end
 285
 286This can then be used in Scaml, like so:
 287
 288    %html{html_attrs("fr-fr")}
 289
 290This is rendered to:
 291
 292    <html lang="fr-fr" xml:lang="fr-fr" xmlns="http://www.w3.org/1999/xhtml">
 293    </html>
 294
 295You can use as many such attribute methods as you want
 296by separating them with commas,
 297like a Scala argument list.
 298All the hashes will me merged together, from left to right.
 299For example, if you defined
 300
 301    def hash1
 302      {:bread => "white", :filling => "peanut butter and jelly"}
 303    end
 304
 305    def hash2
 306      {:bread => "whole wheat"}
 307    end
 308
 309then
 310
 311    %sandwich{hash1, hash2, :delicious => true}/
 312
 313would render to:
 314
 315    <sandwich bread="whole wheat" delicious="true" filling="peanut butter and jelly" />
 316
 317Note that the Scaml attributes list has the same syntax as a Scala method call.
 318This means that any attribute methods must come before the hash literal.
 319
 320Attribute methods aren't supported for HTML-style attributes.
 321-->
 322
 323#### Boolean Attributes
 324
 325Some attributes, such as "checked" for `input` tags or "selected" for `option` tags,
 326are "boolean" in the sense that their values don't matter -
 327it only matters whether or not they're present.
 328In HTML (but not XHTML), these attributes can be written as
 329{pygmentize:: xml}
 330<input selected>
 331{pygmentize}
 332
 333To do this in Scaml using hash-style attributes, just assign a Scala
 334`true` value to the attribute:
 335{pygmentize:: scaml}
 336%input{:selected => true}
 337{pygmentize}
 338
 339In XHTML, the only valid value for these attributes is the name of the
 340attribute.  Thus this will render in XHTML as
 341{pygmentize:: xml}
 342<input selected="selected"/>
 343{pygmentize}
 344
 345To set these attributes to false, simply assign them to a Scala false value.
 346In both XHTML and HTML
 347{pygmentize:: scaml}
 348%input{:selected => false}
 349{pygmentize}
 350
 351will just render as
 352
 353{pygmentize:: xml}
 354<input/>
 355{pygmentize}
 356
 357HTML-style boolean attributes can be written just like HTML:
 358{pygmentize:: scaml}
 359%input(selected)
 360{pygmentize}
 361
 362or using `true` and `false`:
 363{pygmentize:: scaml}
 364%input(selected=true)
 365{pygmentize}
 366
 367### Class and ID: `.` and `#`
 368
 369The period and pound sign are borrowed from CSS.
 370They are used as shortcuts to specify the `class`
 371and `id` attributes of an element, respectively.
 372Multiple class names can be specified in a similar way to CSS,
 373by chaining the class names together with periods.
 374They are placed immediately after the tag and before an attributes hash.
 375
 376{pygmentize_and_compare::}
 377-----------------------------
 378scaml: example
 379-----------------------------
 380%div#things
 381  %span#rice Chicken Fried
 382  %p.beans{ :food => "true" } The magical fruit
 383  %h1.class.otherclass#id La La La
 384-----------------------------
 385xml: renders to
 386-----------------------------
 387<div id="things">
 388  <span id="rice">Chicken Fried</span>
 389  <p class="beans" food="true">The magical fruit</p>
 390  <h1 id="id" class="class otherclass">La La La</h1>
 391</div>
 392{pygmentize_and_compare}
 393
 394And,
 395
 396{pygmentize_and_compare::}
 397-----------------------------
 398scaml: example
 399-----------------------------
 400#content
 401  .articles
 402    .article.title Doogie Howser Comes Out
 403    .article.date 2006-11-05
 404    .article.entry
 405      Neil Patrick Harris would like to dispel any rumors that he is straight
 406-----------------------------
 407xml: renders to
 408-----------------------------
 409<div id="content">
 410  <div class="articles">
 411    <div class="article title">Doogie Howser Comes Out</div>
 412    <div class="article date">2006-11-05</div>
 413    <div class="article entry">
 414      Neil Patrick Harris would like to dispel any rumors that he is straight
 415    </div>
 416  </div>
 417</div>
 418{pygmentize_and_compare}
 419
 420### Weird Element Names: `'`element`'`
 421
 422Sometimes you have to generate markup with weird element names.  Element names
 423like `<funny.element/>`.  Since Scaml interprets the period as a class name for the 
 424element, the following example:
 425
 426{pygmentize_and_compare::}
 427-----------------------------
 428scaml: example
 429-----------------------------
 430%funny.element
 431-----------------------------
 432xml: renders to
 433-----------------------------
 434<funny class="element"/>
 435{pygmentize_and_compare}
 436
 437does not give you the desired result of `<funny.element/>`.  In these cases you must single
 438quote the element name. 
 439
 440Example:
 441
 442{pygmentize_and_compare::}
 443-----------------------------
 444scaml: example
 445-----------------------------
 446%'funny.element'
 447-----------------------------
 448xml: renders to
 449-----------------------------
 450<funny.element/>
 451{pygmentize_and_compare}
 452
 453#### Implicit Div Elements
 454
 455Because divs are used so often, they're the default elements.
 456If you only define a class and/or id using `.` or `#`,
 457a div is automatically used.
 458
 459{pygmentize_and_compare::}
 460-----------------------------
 461scaml: example
 462-----------------------------
 463#collection
 464  .item
 465    .description What a cool item!
 466-----------------------------
 467scaml: is the same as
 468-----------------------------
 469%div#collection
 470  %div.item
 471    %div.description What a cool item!
 472{pygmentize_and_compare}
 473
 474and is rendered to:
 475{pygmentize:: xml}
 476<div id="collection">
 477  <div class="item">
 478    <div class="description">What a cool item!</div>
 479  </div>
 480</div>
 481{pygmentize}
 482
 483### Self-Closing Tags: `/`
 484
 485The forward slash character, when placed at the end of a tag definition,
 486causes the tag to be self-closed.
 487For example:
 488
 489{pygmentize_and_compare::wide=true}
 490-----------------------------
 491scaml: example
 492-----------------------------
 493%br/
 494%meta{"http-equiv" => "Content-Type", :content => "text/html"}/
 495-----------------------------
 496xml: renders to
 497-----------------------------
 498<br/>
 499<meta http-equiv="Content-Type" content="text/html"/>
 500{pygmentize_and_compare}
 501
 502Some tags are automatically closed, as long as they have no content.
 503`meta`, `img`, `link`, `script`, `br`, and `hr` tags are closed by default.
 504This list can be customized by setting the [`ScamlOptions.autoclose`](http://scalate.fusesource.org/maven/${project_version}/scalate-core/scaladocs/org/fusesource/scalate/scaml/ScamlOptions$.html) option.
 505
 506{pygmentize_and_compare::wide=true}
 507-----------------------------
 508scaml: example
 509-----------------------------
 510%br
 511%meta{"http-equiv" => "Content-Type", :content => "text/html"}
 512-----------------------------
 513xml: renders to
 514-----------------------------
 515<br/>
 516<meta http-equiv="Content-Type" content="text/html"/>
 517{pygmentize_and_compare}
 518
 519### Whitespace Removal: `>` and `<`
 520
 521`>` and `<` give you more control over the whitespace near a tag.
 522`>` will remove all whitespace surrounding a tag,
 523while `<` will remove all whitespace immediately within a tag.
 524You can think of them as alligators eating the whitespace:
 525`>` faces out of the tag and eats the whitespace on the outside,
 526and `<` faces into the tag and eats the whitespace on the inside.
 527They're placed at the end of a tag definition,
 528after class, id, and attribute declarations
 529but before `/` or `=`.
 530
 531{pygmentize_and_compare::}
 532-----------------------------
 533scaml: example
 534-----------------------------
 535%blockquote<
 536  %div
 537    Foo!
 538-----------------------------
 539xml: renders to
 540-----------------------------
 541<blockquote><div>
 542  Foo!
 543</div></blockquote>
 544{pygmentize_and_compare}
 545
 546And:
 547{pygmentize_and_compare::}
 548-----------------------------
 549scaml: example
 550-----------------------------
 551%img
 552%img>
 553%img
 554-----------------------------
 555xml: renders to
 556-----------------------------
 557<img/><img/><img/>
 558{pygmentize_and_compare}
 559
 560And:
 561{pygmentize_and_compare::}
 562-----------------------------
 563scaml: example
 564-----------------------------
 565%p<= "Foo\nBar"
 566-----------------------------
 567xml: renders to
 568-----------------------------
 569<p>Foo
 570Bar</p>
 571{pygmentize_and_compare}
 572
 573And finally:
 574{pygmentize_and_compare::}
 575-----------------------------
 576scaml: example
 577-----------------------------
 578%img
 579%pre><
 580  foo
 581  bar
 582%img
 583-----------------------------
 584xml: renders to
 585-----------------------------
 586<img /><pre>foo
 587bar</pre><img />
 588{pygmentize_and_compare}
 589
 590## Doctype: `!!! format`
 591
 592When describing HTML documents with Scaml,
 593you can have a document type or XML prolog generated automatically
 594by including the characters `!!!`.
 595
 596{pygmentize_and_compare::wide=true}
 597-----------------------------
 598scaml: example
 599-----------------------------
 600!!! XML
 601!!!
 602%html
 603  %head
 604    %title Myspace
 605  %body
 606    %h1 I am the international space station
 607    %p Sign my guestbook
 608-----------------------------
 609xml: renders to
 610-----------------------------
 611<?xml version="1.0" encoding="utf-8" ?>
 612<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 613<html>
 614  <head>
 615    <title>Myspace</title>
 616  </head>
 617  <body>
 618    <h1>I am the international space station</h1>
 619    <p>Sign my guestbook</p>
 620  </body>
 621</html>
 622{pygmentize_and_compare}
 623
 624You can also specify the specific doctype after the `!!!`
 625When the `format` is set to `:xhtml` (the default),
 626the following doctypes are supported:
 627
 628#### `!!!`
 629> XHTML 1.0 Transitional
 630> `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">`
 631
 632#### `!!! Strict`
 633> XHTML 1.0 Strict
 634> `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">`
 635
 636#### `!!! Frameset`
 637> XHTML 1.0 Frameset<br/>
 638> `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">`
 639
 640#### `!!! 1.1`
 641> XHTML 1.1<br/>
 642> `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">`
 643
 644#### `!!! Basic`
 645> XHTML Basic 1.1<br/>
 646> `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"> `
 647
 648#### `!!! Mobile`
 649> XHTML Mobile 1.2<br/>
 650> `<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">`
 651
 652When the `format` option is set to `:html4`,
 653the following doctypes are supported:
 654
 655#### `!!!`
 656> HTML 4.01 Transitional<br/>
 657> `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">`
 658
 659#### `!!! Strict`
 660> HTML 4.01 Strict<br/>
 661> `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">`
 662
 663#### `!!! Frameset`
 664> HTML 4.01 Frameset<br/>
 665> `<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">`
 666
 667#### `!!! 5`
 668> HTML 5<br/>
 669> `<!DOCTYPE html>`<br/>
 670
 671When the `format` option is set to `:html5`,
 672`!!!` is always `<!DOCTYPE html>`.
 673
 674If you're not using the UTF-8 character set for your document,
 675you can specify which encoding should appear
 676in the XML prolog in a similar way.
 677
 678
 679{pygmentize_and_compare::}
 680-----------------------------
 681scaml: example
 682-----------------------------
 683!!! XML iso-8859-1
 684-----------------------------
 685xml: renders to
 686-----------------------------
 687<?xml version="1.0" encoding="iso-8859-1" ?>
 688{pygmentize_and_compare}
 689
 690## Comments
 691
 692Scaml supports two sorts of comments:
 693those that show up in the HTML output
 694and those that don't.
 695
 696### HTML Comments: `/`
 697
 698The forward slash character, when placed at the beginning of a line,
 699wraps all text after it in an HTML comment.
 700
 701{pygmentize_and_compare::}
 702-----------------------------
 703scaml: example
 704-----------------------------
 705%peanutbutterjelly
 706  / This is the comment
 707  I like sandwiches!
 708-----------------------------
 709xml: renders to
 710-----------------------------
 711<peanutbutterjelly>
 712  <!-- This is the comment -->
 713  I like sandwiches!
 714</peanutbutterjelly>
 715{pygmentize_and_compare}
 716
 717The forward slash can also wrap indented sections of code. For example:
 718
 719{pygmentize_and_compare::}
 720-----------------------------
 721scaml: example
 722-----------------------------
 723/
 724  %p This doesn't render...
 725  %div
 726    %h1 Because it's commented out!
 727-----------------------------
 728xml: renders to
 729-----------------------------
 730<!--
 731  <p>This doesn't render...</p>
 732  <div>
 733    <h1>Because it's commented out!</h1>
 734  </div>
 735-->
 736{pygmentize_and_compare}
 737
 738#### Conditional Comments: `/[]`
 739
 740You can also use [Internet Explorer conditional comments](http://www.quirksmode.org/css/condcom.html)
 741by enclosing the condition in square brackets after the `/`.
 742
 743{pygmentize_and_compare::wide=true}
 744-----------------------------
 745scaml: example
 746-----------------------------
 747/[if IE]
 748  %a{ :href => "http://www.mozilla.com/en-US/firefox/" }
 749    %h1 Get Firefox
 750-----------------------------
 751xml: renders to
 752-----------------------------
 753<!--[if IE]>
 754  <a href="http://www.mozilla.com/en-US/firefox/">
 755    <h1>Get Firefox</h1>
 756  </a>
 757<![endif]-->
 758{pygmentize_and_compare}
 759
 760### Scaml Comments: `-#`
 761
 762The hyphen followed immediately by the pound sign
 763signifies a silent comment.
 764Any text following this isn't rendered in the resulting document
 765at all.
 766
 767For example:
 768{pygmentize_and_compare::}
 769-----------------------------
 770scaml: example
 771-----------------------------
 772%p foo
 773-# This is a comment
 774%p bar
 775-----------------------------
 776xml: renders to
 777-----------------------------
 778<p>foo</p>
 779<p>bar</p>
 780{pygmentize_and_compare}
 781
 782You can also nest text beneath a silent comment.
 783None of this text will be rendered.
 784
 785
 786{pygmentize_and_compare::}
 787-----------------------------
 788scaml: example
 789-----------------------------
 790%p foo
 791-#
 792  This won't be displayed
 793    Nor will this
 794%p bar
 795-----------------------------
 796xml: renders to
 797-----------------------------
 798<p>foo</p>
 799<p>bar</p>
 800{pygmentize_and_compare}
 801
 802## Scala Evaluation
 803
 804### Binding Attributes `-@` {#bindings}
 805
 806When a Scalate template is rendered, the caller can pass an attribute map
 807to the template in charge of rendering. To bind the attribute to a Scala
 808variable, a Scaml template uses the hyphen character followed by an at sign 
 809and then a Scala variable declaration statement.
 810
 811For example To define an attribute use the following declaration
 812{pygmentize:: scaml}
 813-@ val foo: MyType 
 814{pygmentize}
 815
 816If the attribute map does not contain a "foo" entry, then a 
 817NoValueSetException is thrown when the the template is rendered.
 818
 819To avoid this exception, a default value can be configured.  For
 820example:
 821{pygmentize:: scaml}
 822-@ val bar: String = "this is the default value"
 823{pygmentize}
 824
 825The attribute is now available for use as an expression. 
 826
 827Its very common to have a template based on a single object who's members are
 828frequently accessed.  In these cases, it's convenient to import all the object's 
 829members.  This can be done by adding the import keyword to the attribute declaration.
 830
 831For example:
 832{pygmentize:: scaml}
 833-@ import val model: Person
 834%p Hello #{name}, what is the weather like in #{city}
 835{pygmentize}
 836
 837is the same as:
 838{pygmentize:: scaml}
 839-@ val model: Person
 840- import model._
 841%p Hello #{name}, what is the weather like in #{city}
 842{pygmentize}
 843
 844Which is the same as:
 845{pygmentize:: scaml}
 846-@ val model: Person
 847%p Hello #{model.name}, what is the weather like in #{model.city}
 848{pygmentize}
 849
 850
 851### Inserting Scala: `=`
 852
 853The equals character is followed by Scala code.
 854This code is evaluated and the output is inserted into the document.
 855
 856{pygmentize_and_compare::wide=true}
 857-----------------------------
 858scaml: example
 859-----------------------------
 860%p
 861  = List("hi", "there", "reader!").mkString(" ")
 862  = "yo"
 863-----------------------------
 864xml: renders to
 865-----------------------------
 866<p>
 867  hi there reader!
 868  yo
 869</p>
 870{pygmentize_and_compare}
 871
 872The default setting for the [`TemplateEngine.escapeMarkup`](http://scalate.fusesource.org/maven/${project_version}/scalate-core/scaladocs/org/fusesource/scalate/TemplateEngine.html) option is 
 873true.  When `TemplateEngine.escapeMarkup` is enabled, `=` will sanitize any
 874HTML-sensitive characters generated by the script. 
 875
 876{pygmentize_and_compare::wide=true}
 877-----------------------------
 878scaml: example
 879-----------------------------
 880= """<script>alert("I'm evil!");</script>"""
 881-----------------------------
 882xml: renders to
 883-----------------------------
 884&lt;script&gt;alert(&quot;I'm evil!&quot;);&lt;/script&gt;
 885{pygmentize_and_compare}
 886
 887`=` can also be used at the end of a tag to insert Scala code within that tag.
 888
 889{pygmentize_and_compare::}
 890-----------------------------
 891scaml: example
 892-----------------------------
 893%p= "hello"
 894-----------------------------
 895xml: renders to
 896-----------------------------
 897<p>hello</p>
 898{pygmentize_and_compare}
 899
 900### Running Scala: `-`
 901
 902The hyphen character is also followed by Scala code.
 903This code is evaluated but *not* inserted into the document.
 904
 905**It is not recommended that you use this widely;
 906almost all processing code and logic should be restricted
 907to the Controller, the Helper, or partials.**
 908
 909{pygmentize_and_compare::}
 910-----------------------------
 911scaml: example
 912-----------------------------
 913- var foo = "hello"
 914- foo += " there"
 915- foo += " you!"
 916%p= foo
 917-----------------------------
 918xml: renders to
 919-----------------------------
 920<p>hello there you!</p>
 921{pygmentize_and_compare}
 922
 923Or alternatively, if you have a large block of Scala code, you can
 924nest it under the hyphen character as demonstrated by the following example:
 925
 926{pygmentize_and_compare::}
 927-----------------------------
 928scaml: example
 929-----------------------------
 930-
 931  var foo = "hello"
 932      foo += " there"
 933  foo += " you!"
 934%p= foo
 935-----------------------------
 936xml: renders to
 937-----------------------------
 938<p>hello there you!</p>
 939{pygmentize_and_compare}
 940
 941#### Scala Blocks
 942
 943Scala blocks, like XHTML tags, don't need to be explicitly closed in Scaml.
 944Rather, they're automatically closed, based on indentation.
 945A block begins whenever the indentation is increased
 946after a Scala insertion or evaluation command.
 947It ends when the indentation decreases.
 948
 949{pygmentize_and_compare::}
 950-----------------------------
 951scaml: example
 952-----------------------------
 953- for(i <- 42 to 46)
 954  %p= i
 955%p See, I can count!
 956-----------------------------
 957xml: renders to
 958-----------------------------
 959<p>42</p>
 960<p>43</p>
 961<p>44</p>
 962<p>45</p>
 963<p>46</p>
 964<p>See, I can count!</p>
 965{pygmentize_and_compare}
 966
 967And,
 968
 969{pygmentize_and_compare::}
 970-----------------------------
 971scaml: example
 972-----------------------------
 973%p
 974  - 2 match
 975    - case 1 =>
 976      = "one"
 977    - case 2 =>
 978      = "two"
 979    - case 3 =>
 980      = "three"
 981-----------------------------
 982xml: renders to
 983-----------------------------
 984<p>
 985  two
 986</p>
 987{pygmentize_and_compare}
 988    
 989When inserting evaluated statements, it can also take advantage of Scala blocks. It can be handy
 990for passing partial functions.  
 991
 992For example:
 993{pygmentize:: scaml}
 994%p
 995  = List(1,2,3).foldLeft("result: ")
 996    - (a,x)=>
 997      - a+x 
 998{pygmentize}
 999
1000is the same as:
1001{pygmentize:: scaml}
1002%p
1003  = List(1,2,3).foldLeft("result: ") { (a,x)=> { a+x } }
1004{pygmentize}
1005
1006would be rendered to:
1007{pygmentize:: xml}
1008<p>
1009  result: 123
1010</p>
1011{pygmentize}
1012    
1013### Whitespace Preservation: `~` {#tilde}
1014
1015`~` works just like `=`, except that it preserves the white space 
1016formating on its input.
1017
1018Scaml always produces HTML source which is easy to read since
1019it properly indented.  Even dynamically generated output is 
1020properly indented. 
1021
1022{pygmentize_and_compare::}
1023-----------------------------
1024scaml: example
1025-----------------------------
1026%html
1027  %p
1028    = "line1\nline2\nline3"
1029-----------------------------
1030xml: renders to
1031-----------------------------
1032<html>
1033  <p>
1034    line1
1035    line2
1036    line3
1037  </p>
1038</html>
1039{pygmentize_and_compare}
1040
1041Sometimes you don't want Scaml to indent the dynamically generated content.
1042For example, tags like `pre` and `textarea` are whitespace-sensitive;
1043indenting the text makes them render wrong.
1044
1045When you use `~` instead of `=`,
1046Scaml will convert newlines to the XHTML newline escape code, `&#x000A;` and avoid
1047adding spaces for indentation.  
1048
1049{pygmentize_and_compare::}
1050-----------------------------
1051scaml: example
1052-----------------------------
1053%html
1054  %pre
1055    ~ "line1\nline2\nline3"
1056-----------------------------
1057xml: renders to
1058-----------------------------
1059<html>
1060  <pre>
1061    line1&#x000A;line2&#x000A;line3
1062  </pre>
1063</html>
1064{pygmentize_and_compare}
1065
1066
1067#### Ugly Preservation: `~~` {#tilde-tilde}
1068
1069Sometimes, you don't want Scaml to indent or apply the whitespace transformation on
1070the evaluated expression. When this is the case, use `~~` to use ugly whitespace
1071preservation.  We call it ugly because the produce HTML will not properly indented.
1072
1073{pygmentize_and_compare::}
1074-----------------------------
1075scaml: example
1076-----------------------------
1077%html
1078  %p
1079    ~~ "line1\nline2\nline3"
1080-----------------------------
1081xml: renders to
1082-----------------------------
1083<html>
1084  <p>
1085line1
1086line2
1087line3
1088  </p>
1089</html>
1090{pygmentize_and_compare}
1091
1092### Scala Interpolation: `#{}`
1093
1094Scala code can be interpolated within plain text using `#{}`.
1095
1096{pygmentize_and_compare::}
1097-----------------------------
1098scaml: example
1099-----------------------------
1100%p This is #{quality} cake!
1101-----------------------------
1102xml: is the same as
1103-----------------------------
1104%p= "This is "+(quality)+" cake!"
1105{pygmentize_and_compare}
1106
1107and renders to
1108{pygmentize:: xml}
1109<p>This is scrumptious cake!</p>
1110{pygmentize}
1111    
1112Backslashes can be used to escape `#{` strings,
1113but they don't act as escapes anywhere else in the string.
1114
1115{pygmentize_and_compare::wide=true}
1116-----------------------------
1117scaml: example
1118-----------------------------
1119%p
1120  A slash make a difference here: \#{name} is set to: \\#{name}
1121  But is ignored for: \# or \\
1122-----------------------------
1123xml: renders to
1124-----------------------------
1125<p>
1126  A slash make a difference here: #{name} is set to: \Hiram
1127  But is ignored for: \# or \\
1128</p>
1129{pygmentize_and_compare}
1130
1131<!--
1132Interpolation can also be used within [filters](#filters).
1133For example:
1134
1135    :javascript
1136      $(document).ready(function() {
1137        alert(#{message.to_json});
1138      });
1139
1140might compile to
1141
1142    <script type="text/javascript">
1143      //<![CDATA[
1144        $(document).ready(function() {
1145          alert("Hi there!");
1146        });
1147      //]]>
1148    </script>
1149-->
1150
1151### Escaping HTML: `&=` {#escaping_html}
1152
1153An ampersand followed by one or two equals characters
1154evaluates Scala code just like the equals without the ampersand,
1155but sanitizes any HTML-sensitive characters in the result of the code.
1156
1157{pygmentize_and_compare::}
1158-----------------------------
1159scaml: example
1160-----------------------------
1161&= "I like cheese & crackers"
1162-----------------------------
1163xml: renders to
1164-----------------------------
1165I like cheese &amp; crackers
1166{pygmentize_and_compare}
1167
1168
1169When the [`TemplateEngine.escapeMarkup`](http://scalate.fusesource.org/maven/${project_version}/scalate-core/scaladocs/org/fusesource/scalate/TemplateEngine.html) option is set
1170to true, `=` behaves identically to `&=`.
1171
1172`&` can also be used on its own so that `#{}` interpolation is escaped.
1173
1174{pygmentize_and_compare::}
1175-----------------------------
1176scaml: example
1177-----------------------------
1178& I like #{"cheese & crackers"}
1179-----------------------------
1180xml: renders to
1181-----------------------------
1182I like cheese &amp; crackers
1183{pygmentize_and_compare}
1184
1185### Unescaping HTML: `!=` {#unescaping_html}
1186
1187An exclamation mark followed by one or two equals characters
1188evaluates Scala code just like the equals would,
1189but never sanitizes the HTML.
1190
1191When the [`TemplateEngine.escapeMarkup`](http://scalate.fusesource.org/maven/${project_version}/scalate-core/scaladocs/org/fusesource/scalate/TemplateEngine.html) option is set to false, `=` behaves identically to `!=`.
1192
1193However, if the [`TemplateEngine.escapeMarkup`](http://scalate.fusesource.org/maven/${project_version}/scalate-core/scaladocs/org/fusesource/scalate/TemplateEngine.html) option is set to true, `=` will sanitize the HTML, but `!=` still won't.
1194
1195For example, if `TemplateEngine.escapeMarkup` is true:
1196
1197{pygmentize_and_compare::}
1198-----------------------------
1199scaml: example
1200-----------------------------
1201= "I feel <strong>!"
1202!= "I feel <strong>!"
1203-----------------------------
1204xml: renders to
1205-----------------------------
1206I feel &lt;strong&gt;!
1207I feel <strong>!
1208{pygmentize_and_compare}
1209
1210`!` can also be used on its own so that `#{}` interpolation is unescaped.
1211
1212{pygmentize_and_compare::}
1213-----------------------------
1214scaml: example
1215-----------------------------
1216! I feel #{"<strong>"}!
1217-----------------------------
1218xml: renders to
1219-----------------------------
1220I feel <strong>!
1221{pygmentize_and_compare}
1222
1223## Filters: `:` {#filters}
1224
1225The colon character designates a filter.
1226This allows you to pass an indented block of text as input
1227to another filtering program and add the result to the output of Haml.
1228
1229The syntax is a colon followed by an optional list of filter flags and then a colon
1230separated list of filter names.
1231
1232{pygmentize_and_compare::}
1233-----------------------------
1234scaml: example
1235-----------------------------
1236%p
1237  :markdown
1238    Markdown
1239    ========
1240    
1241    Hello, *World*
1242-----------------------------
1243xml: renders to
1244-----------------------------
1245<p>
1246  <h1>Markdown</h1>
1247
1248  <p>Hello, <em>World</em></p>
1249</p>
1250{pygmentize_and_compare}
1251
1252### Filter Interpolation
1253
1254If you use the `!` or `&` filter flags, you can have Scala code 
1255interpolated with `#{}` expressions.  It is invalid to use both
1256the `!` and `&` flags at the same time. 
1257
1258The `&` flag enables sanitized interpolations.  
1259
1260{pygmentize_and_compare::wide=true}
1261-----------------------------
1262scaml: example
1263-----------------------------
1264- var flavor = "<raspberry/>"
1265#content
1266  :&markdown
1267    I *really* prefer #{flavor} jam.
1268-----------------------------
1269xml: renders to
1270-----------------------------
1271<div id="content">
1272  <p>I <em>really</em> prefer &lt;raspberry/&gt; jam.</p>
1273</div>
1274{pygmentize_and_compare}
1275
1276The `!` flag enables non-sanitized interpolations.
1277
1278{pygmentize_and_compare::wide=true}
1279-----------------------------
1280scaml: example
1281-----------------------------
1282- var flavor = "<raspberry/>"
1283#content
1284  :!markdown
1285    I *really* prefer #{flavor} jam.
1286-----------------------------
1287xml: renders to
1288-----------------------------
1289<div id="content">
1290  <p>I <em>really</em> prefer <raspberry/>; jam.</p>
1291</div>
1292{pygmentize_and_compare}
1293
1294### Filter Whitespace Preservation
1295
1296The `~` filter flag enables preserves the white space of the content.
1297The indent level is left unchanged and newlines are converted to `&#x000A;`
1298
1299{pygmentize_and_compare::wide=true}
1300-----------------------------
1301scaml: example
1302-----------------------------
1303%html
1304  %p<
1305    :~plain
1306          Indentation levels are not enforced in filters.
1307        #{Interpolation} is disabled by default
1308      Last line
1309-----------------------------
1310xml: renders to
1311-----------------------------
1312<html>
1313  <p>    Indentation levels are not enforced in filters.&#x000A;  #{Interpolation} is disabled by default&#x000A;Last line</p>
1314</html>
1315{pygmentize_and_compare}
1316
1317### Filter Chaining
1318
1319More than one filter can be be used by separating each filter name with a colon.  When
1320this is done, the filters are chained together so that the output of filter on right, is
1321passed as input to the filter on the left.
1322
1323{pygmentize_and_compare::}
1324-----------------------------
1325scaml: example
1326-----------------------------
1327%pre
1328  :escaped :javascript
1329    alert("Hello");
1330-----------------------------
1331xml: renders to
1332-----------------------------
1333<pre>
1334  &lt;script type='text/javascript'&gt;
1335    //&lt;![CDATA[
1336      alert(&quot;Hello&quot;);
1337    //]]&gt;
1338  &lt;/script&gt;
1339</pre>
1340{pygmentize_and_compare}
1341
1342### Available Filters
1343
1344Scaml has the following filters defined:
1345
1346#### `:plain` {#plain-filter}
1347> Does not parse the filtered text.
1348> This is useful for large blocks of text or HTML.  Really handy when
1349> when you don't want lines starting with `.` or `-` to be parsed.
1350
1351#### `:javascript` {#javascript-filter}
1352> Surrounds the filtered text with `<script>` and CDATA tags.
1353> Useful for including inline Javascript.
1354
1355#### `:css` {#css-filter}
1356> Surrounds the filtered text with `<style>` and CDATA tags.
1357Useful for including inline CSS.
1358
1359#### `:cdata` {#cdata-filter}
1360> Surrounds the filtered text with CDATA tags.
1361
1362#### `:escaped` {#escaped-filter}
1363> Works the same as plain, but HTML-escapes the text
1364> before placing it in the document.
1365
1366<!--
1367#### `:ruby` {#ruby-filter}
1368Parses the filtered text with the normal Ruby interpreter.
1369All output sent to `$stdout`, like with `puts`,
1370is output into the Haml document.
1371Not available if the [`:suppress_eval`](#suppress_eval-option) option is set to true.
1372The Ruby code is evaluated in the same context as the Haml template.
1373
1374#### `:erb` {#erb-filter}
1375Parses the filtered text with ERb, like an RHTML template.
1376Not available if the [`:suppress_eval`](#suppress_eval-option) option is set to true.
1377Embedded Ruby code is evaluated in the same context as the Haml template.
1378-->
1379
1380#### `:sass` {#sass-filter}
1381> Parses the filtered text with [Sass](http://sass-lang.com/) to produce CSS output.  
1382Only works if you have the `scalate-jruby` module on the class path.  You normally 
1383want to combine with the `:css` filter.  For example `:css:sass`
1384
1385#### `:scss` {#scss-filter}
1386> Parses the filtered text with [Scss](http://sass-lang.com/) to produce CSS output.
1387Only works if you have the `scalate-jruby` module on the class path.  You normally 
1388want to combine with the `:css` filter.  For example `:css:scss`
1389
1390#### `:textile` {#textile-filter}
1391> Parses the filtered text with [Textile](http://www.textism.com/tools/textile).
1392Only works the scalate-wikitext module is found on the class path.
1393
1394#### `:markdown` {#markdown-filter}
1395> Parses the filtered text with [Markdown](http://daringfireball.net/projects/markdown).
1396Only works if [scalamd](http://scalamd.fusesource.org/) or [MarkdownJ](http://markdownj.org/) is found on the class path.
1397
1398<!--
1399### Custom Filters
1400
1401You can also define your own filters. See Haml::Filters for details.
1402-->
1403
1404## Global Scaml Options
1405
1406There  are several global options you can configure to customize how Scaml renders the
1407output.  You will need to configure these before any of your scaml templates are compiled
1408as they affect the generated scala template classes.
1409
1410### `ScamlOptions.indent`
1411
1412The `ScamlOptions.indent` option is used to control what kind of indenting characters to 
1413use in the rendered markup.  It defaults to two spaces but can be set to the tab character
1414or set to the empty string to disable indenting alltogether.
1415
1416{pygmentize_and_compare::}
1417-----------------------------
1418scaml: ScamlOptions.indent = ""
1419-----------------------------
1420%gee
1421  %whiz
1422    Wow this is cool!
1423-----------------------------
1424xml: renders to
1425-----------------------------
1426<gee>
1427<whiz>
1428Wow this is cool!
1429</whiz>
1430</gee>
1431{pygmentize_and_compare}
1432
1433### `ScamlOptions.nl`
1434
1435The `ScamlOptions.nl` option is used to control what kind of new line seperator to 
1436use in the rendered markup.  It defaults to `\n`.  Some folks may want to set it and the indent
1437to the empty string to reduce the generated document sizes.
1438
1439For example, if `ScamlOptions.indent = ""` and `ScamlOptions.nl = ""` then:
1440
1441{pygmentize_and_compare::}
1442-----------------------------
1443scaml: example
1444-----------------------------
1445%gee
1446  %whiz
1447    Wow this is cool!
1448-----------------------------
1449xml: renders to
1450-----------------------------
1451<gee><whiz>Wow this is cool!</whiz></gee>
1452{pygmentize_and_compare}
1453
1454### `ScamlOptions.ugly`
1455
1456Enabling the `ScamlOptions.ugly` option makes `=` statements work like `~~` statements.  The dynamic expressions
1457will not be indented and they the new line preservation transformation method will not be applied.  Enabling the
1458ugly option will significantly reduce the CPU overhead of processing dynamic expressions.
1459
1460{pygmentize_and_compare::}
1461-----------------------------
1462scaml: ScamlOptions.ugly = true
1463-----------------------------
1464%html
1465  %p
1466    = "line1\nline2\nline3"
1467-----------------------------
1468xml: renders to
1469-----------------------------
1470<html>
1471  <p>
1472line1
1473line2
1474line3
1475  </p>
1476</html>
1477{pygmentize_and_compare}
1478
1479## Other Resources
1480
1481* [User Guide](user-guide.html)
1482* [Documentation](index.html)
1483
1484