Never satisfied with a 'simple' templating language, i really wanted to be able to |VARIABLE| and have it translate to <%= @object.variable %>, since that is what is printed most often.

I also allowed [% %] as aliases of <% %> (sometimes you want it to show up in a WYSIWYG editor).

And conditionals bothered me, so xif means cross-if.  Cross meaning crosses the precedding line of text...  These are all just handled as simple regexes on the code.  The controller name to use for @article is guessed from the directory the source file is in.

<pre>
Print this text maybe <% xif @article.title =~ /the/ %>
</pre>
will translate to:
<pre>
<% if @article.title =~ /the/ %>Print this text maybe<% end %>
</pre>

On a similar note, 
* hif = has_attribute cross if
* dif = defined cross if
* eif = empty? cross if

Add to /vendor/actionpack/lib/action_view/erb_template.rb

<pre>
    def preprocess(template_path, html)
      #$stderr.puts "Template_path is #{template_path}"
      
      #figure out controller name
      if template_path =~ %r{([^/]+)/([^/]+)/?$}
        controller = $1
      end
      
      #guess if it needs an 's' or not?
      #controller << 's' if $2 =~ /list/
      
      html.gsub!('[%','<%')
      html.gsub!('%]','%>')
  
      html.gsub!('|end|', '<% end %>')
      
      #BUMMER: this matches {|a,b| } for ruby blocks. or do |a|.  any way to tell the difference?  require uppercase?  Sure...
      html.gsub!(/\|([^@\s][^\|a-z]+)\|/) { # |VAR|, that don't contain a @ (so add current object)
        name = $1; name.downcase! if name == name.upcase
        "<%= @#{controller}.#{name} %>"
      }
      
      html.gsub!(/\|([^\|a-z]{1,30})\|/) { # other |VAR|
        name = $1; name.downcase! if name == name.upcase
        "<%= #{name} %>"
      }
      
      #xif = cross-if
      #<% xif @article.syndicated %> -> wrap line in <% if %>
      html.gsub!(/^(.*?)<%=? xif (.*?)%>\s*$/) {
        "<% if #$2%> #$1<% end %>"
      }
      
      # has? = has_attribute if
      html.gsub!(/^(.*?)<%=? hif (.*?)%>\s*$/) {
        "<% if @#{controller}.has_attribute? '#$2' %>#$1<% end %>"
      }
      
      # dif? = defined if
      html.gsub!(/^(.*?)<%=? dif (.*?)%>\s*$/) {
        "<% if @#{controller}.#$2 %>#$1<% end %>"
      }
      
      #eif = empty if
      html.gsub!(/^(.*?)<%=? eif (.*?)%>\s*$/) {
        "<% if @#{controller}.#$2.empty? %>#$1<% end %>"
      }
      html
    end
</pre>

Then change read_template_file to be:

<pre>
 def read_template_file(template_path)
        preprocess template_path, IO.readlines(template_path).join
      end
</pre>

And the first line of source_extract re-loads the file instead of using the source thats passed to it, so fix that:
<pre>
 def source_extract
      source_code = @source.split "\n"#IO.readlines(@file_name)
</pre>

Enjoy! :)


category:Howto
