= Kashmir Kashmir is an advanced templating engine for Ruby featuring an easy, pragmatic syntax and efficient generated code. Kashmir tries to walk on the narrow path between the mess of raw evaluated Ruby like ERB and the clinical sterileness of data-driven templating like Amrita. Kashmir encourages you to define a Model for your View and call its methods, but allows you as well to evaluate any code you want (though you *never* have to). Kashmir can provide automatic escaping of generated output to lower the possibility of cross-side scripting attacks. Kashmir is output-format agnostic, it can be used to generate all kind of text files. Kashmir ships with Elusion, an easy to use helper-library to realize Amrita2-like active templates. == An example The following ERB: <% for member in member_list do %> <% end %>
<%= member %>
would be this in Kashmir: ^member_list.each{ }
^to_s
The following Amrita: require "amrita2/template" include Amrita2 class PO def array_data [1, 2, 3] end def nested_struct Time.gm(2005,2,23, 4,5,6) end def nested_structs [Time.gm(2005,2,23, 4,5,6),Time.gm(2005,2,24, 4,5,6) ] end end tmpl = TemplateText.new <<-END

array data

nested struct

::

array of nested struct

END tmpl.expand(STDOUT, PO.new) would be this in Kashmir (this will generate the same output as the Amrita template; you can simply drop the unneeded spans if you want): require 'kashmir' tmpl = Kashmir.for_XML <<-END

array data

^array_data.each{^to_s}

nested struct

^nested_struct.with{^hour:^min:^sec}

array of nested struct

^nested_structs.each{

^day

} END tmpl.expand(PO.new, STDOUT) Now you could say you have a fair lot of logic in your code, and use Elusion to keep it outside: require 'kashmir' require 'elusion' tmpl = Kashmir.for_XML <<-END

array data

^array_data.each{^to_s}

nested struct

^nested_struct

array of nested struct

^nested_structs.each{

^to_s

} END po = PO.new elusion = Elusion.new { |e| e.array_data po.array_data e.nested_struct [po.nested_struct.hour, po.nested_struct.min, po.nested_struct.sec].join(":") po.nested_structs.each { |s| e.nested_structs s.day } } p elusion.array_data tmpl.expand(elusion, STDOUT) == Command reference All Kashmir commands are introduced with ^. A normal string will be sent to the object. The method may not take any parameters. You can chain several method calls at once: ^to_s Common case when iterating ^time.hour Method chaining The more ^ you prefix your command with, the higher the scope of the reciever will be. ^first_loop{ ^foo Called in the scope of the current loop ^second_loop{ ^bar Called in the scope of the current loop ^^foo Like ^foo outside the loop ^^^quux Same scope as where the outer loop was called } } You can instance_eval any code when you put it in parentheses after the ^. Please note that the parenthesis *inside* the code need to match. ^(2+2) 4 ^(Time.now.strftime("%H:%M:%S")) 17:53:15 You can pass blocks if you place the braces *directly* after the method. Then the template will be made a block and given to the method. The first parameter will always get the default object of the scope (acessible with ^whatever), but you can also access the objects yielded to the block by their position: ^({:a => 1, :b => 2}.each){ ^0 -> ^1 } a -> 1 b -> 2 Finally, you can place comments which last till the end of the line (including newline) with ^#: ^# everyone ignores me *sniff* For various special purposes, you can define Kashmir Instructions that can do things a simple method call does not allow. Instructions are called just like methods with ^(). Currently, there are these instructions: ^(raw body.to_html) Emit the result of the code without sanitation ^(ignore weirdcall) Evaluate the code, but do not generate any output ^(call tag) Get the code for the template `tag', and call it Taglibs provide an flexible way to structure large templates. You can pass a taglib as the second parameter to Kashmir.new. A taglib can be any object that returns a Kashmir template string when called with taglib[tag], e.g. a Hash or some special object to read templates from files. == History March 18, 2005:: First public release 0.2. == Copyright Copyright (C) 2005 Christian Neukirchen This work is licensed under the same terms as Ruby itself. Please mail bugs, feature requests or patches to the mail addresses above or use IRC[irc://freenode.net/#ruby-lang] to contact the developers.