Embedded Ruby and Tag Libs

Hey guys,

I've been dabbling with ruby on and off for a year or so and recently more often. At work we do Java development and I keep thinking that it would be nice to be able to bring some of the stuff I designed there into my own work, which I want to do in ruby.

I was wondering if anyone had thought about adding something like the Java TagLibs to ruby (I guess it would embedded ruby). In my case, it would make long term maintenance of files MUCH easier as I can give it to a non-technical person without much documentation. In most cases people who don't understand programming do understand parts of HTML markup. If I could hide what is currently inline code behind things that look like tags, its easier to give maintenance over to non-technical folks.

Here's a simple example. Often you want to do tiger striping on tables (alternate background color on each row). Because there isn't sufficiently wide spread support for CSS2 and CSS3 selectors, you tend to do the following:

<table>
         <tr class="odd"><td>...</td></tr>
         <tr class="even"><td>...</td></tr>
         <tr class="odd"><td>...</td></tr>
         <tr class="even"><td>...</td></tr>
         <tr class="odd"><td>...</td></tr>
         <tr class="even last"><td>...</td></tr>
</table>

Unfortunately, if you want to add something between rows 4 and 5 you need to reset all your classes. This can get complicated. However, if I had a taglib I could ask my content authors to write the following:

<av:table>
     <av:trow><td>...</td></av:trow >
</av:table>

And leave the generation up to the code.

I can think of hundreds of specific tags I might create, depending on the situation, which would make authoring content easier and would give me better control over the rendering of a page. It could also make writing code easier in general. It would also be useful to have many of the tags defined in the JSTL.

Just a thought I had.
Adam

Frankly, I think that TagLibs are overblown nonsense :wink: You can
implement much of this with Amrita, I think, which completely separates
code from data. Even with erb/eruby, though, you could do something
like:

<table>
  <% max = data.size
     data.each_with_index do |el, ix| %>
    <tr class="<%= (((ix % 2) == 0) ? "even" : "odd") +
       ((ix == max) ? " last" : "") %>">
    <td><%= el %></td>
  </tr>
  <% end %>
</table>

There's other ways to do this, but as I don't really do a lot of stuff
that needs this, this is simple enough.

-austin

···

On 9/26/05, Adam Van Den Hoven <mail@adamvandenhoven.com> wrote:

I've been dabbling with ruby on and off for a year or so and recently
more often. At work we do Java development and I keep thinking that it
would be nice to be able to bring some of the stuff I designed there
into my own work, which I want to do in ruby.

I was wondering if anyone had thought about adding something like the
Java TagLibs to ruby (I guess it would embedded ruby). In my case, it
would make long term maintenance of files MUCH easier as I can give it
to a non-technical person without much documentation. In most cases
people who don't understand programming do understand parts of HTML
markup. If I could hide what is currently inline code behind things
that look like tags, its easier to give maintenance over to
non-technical folks.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Hi, Adam,

First, DHH's opinion on this matter might be of interest to you:
http://www.loudthinking.com/arc/000408.html
(DHH = The Rails Guy, btw)

Second, the best way I can think of to achieve something like what you're talking about in ERB would look like this:

class AvTable
  def initialize(out)
    @out = out; @side = :odd
  end
  def trow
    @out << %Q{<tr class="#@side">}
    yield
    @out << "</tr>\n"
    @side = (@side == :odd) ? :even : :odd
  end
end

def av_table(out)
  out << "<table>\n"
  yield AvTable.new(out)
  out << "</table>\n"
end

a = ERB.new <<RHTML
<% av_table(_erbout) do |av| %>
  <% av.trow do %><td>...</td><% end %>
<% end %>
RHTML

a.result.display

Not sure how you would take care of "last", though (without writing an internal iterator for your data), but I'm no expert, and this is probably a crappy way of achieving what you're after. (I, for instance, am not a fan of passing around _erbout.)

Devin

Adam Van Den Hoven wrote:

···

Hey guys,

I've been dabbling with ruby on and off for a year or so and recently more often. At work we do Java development and I keep thinking that it would be nice to be able to bring some of the stuff I designed there into my own work, which I want to do in ruby.

I was wondering if anyone had thought about adding something like the Java TagLibs to ruby (I guess it would embedded ruby). In my case, it would make long term maintenance of files MUCH easier as I can give it to a non-technical person without much documentation. In most cases people who don't understand programming do understand parts of HTML markup. If I could hide what is currently inline code behind things that look like tags, its easier to give maintenance over to non-technical folks.

Here's a simple example. Often you want to do tiger striping on tables (alternate background color on each row). Because there isn't sufficiently wide spread support for CSS2 and CSS3 selectors, you tend to do the following:

<table>
        <tr class="odd"><td>...</td></tr>
        <tr class="even"><td>...</td></tr>
        <tr class="odd"><td>...</td></tr>
        <tr class="even"><td>...</td></tr>
        <tr class="odd"><td>...</td></tr>
        <tr class="even last"><td>...</td></tr>
</table>

Unfortunately, if you want to add something between rows 4 and 5 you need to reset all your classes. This can get complicated. However, if I had a taglib I could ask my content authors to write the following:

<av:table>
    <av:trow><td>...</td></av:trow >
</av:table>

And leave the generation up to the code.

I can think of hundreds of specific tags I might create, depending on the situation, which would make authoring content easier and would give me better control over the rendering of a page. It could also make writing code easier in general. It would also be useful to have many of the tags defined in the JSTL.

Just a thought I had.
Adam

Austin.

I think you missed my point.

I used the example of a table only because it was an easy example, not because its not solvable in other ways.

In general, you're right; all three of those technologies CAN do exactly what I'm trying to do. Its very trivial for you or I to write that markup and I would be inclined to do it if I was going to be the person responsible for maintaining the site. The thing is I really hate maintaining clients sites for them. Its a lot of overhead for a change that they can do themselves. I tend to build a site once then provide a style guide and show them how to update their content. There is no way I'm going to be able to document for my client the mechanic how to create a table on some arbitrary page using the code you have below. I can just tell him what markup to use but the amount of markup he has to remember far exceeds the data he want to add. A taglib is an EXCELLENT way of hiding that complexity. It also allows me to change the behaviour of that tag after the fact, as requirements change, without editing content.

Or lets say that the site I'm making is about the history of salmon fishing in British Columbia. For various reasons, I want to markup photographs as follows:

<div class="photo">
     <div class="title">Fishermen at the Steveston docks, circa 1843</

     <img href="..." />
     <div class="caption"><p>Yadda yadda yadda.</p><p>Blah blah blah</

</div>

     <div class="cite"><spand class="photographer">James Tyson</

<span class="publication">Steveston Chronicle</span><span

class="year">1983</span></div>
</div>

Now, I could ask my content authors to simply write that out every time. The problem is that I perhaps I want to do something a little different in certain circumstances, add a different class if its the first one on the page, for instance. Now I have to write out a lot of rules for authors to remember. Its a lot simpler, IMHO, if I just told them to write the following:

<x:photo imghref="someurl">
     <x:title>Fishermen at the <a href="/steveston.rsp">Steveston docs</a>, circa 1843</x:title>
     <x:caption><p>Yadda yadda yadda.</p><p>Blah blah blah</p></x:caption>
     <x:cite photographer="James Tyson" publication="Steveston Chronicle" year="1983" />
</x:photo>

I can then write my markup from that.

Now lets say that it was decided to change the format so that the citations were all done in foot notes. pretty much all I'd have to do is change the behavior of my <x:photo> and <x:cite> tags and the change would be made.

In my opinion tag libraries are most useful when they are used to reduce complexity for content authors.

Adam

···

On 26-Sep-05, at 1:59 PM, Austin Ziegler wrote:

On 9/26/05, Adam Van Den Hoven <mail@adamvandenhoven.com> wrote:

I've been dabbling with ruby on and off for a year or so and recently
more often. At work we do Java development and I keep thinking that it
would be nice to be able to bring some of the stuff I designed there
into my own work, which I want to do in ruby.

I was wondering if anyone had thought about adding something like the
Java TagLibs to ruby (I guess it would embedded ruby). In my case, it
would make long term maintenance of files MUCH easier as I can give it
to a non-technical person without much documentation. In most cases
people who don't understand programming do understand parts of HTML
markup. If I could hide what is currently inline code behind things
that look like tags, its easier to give maintenance over to
non-technical folks.

Frankly, I think that TagLibs are overblown nonsense :wink: You can
implement much of this with Amrita, I think, which completely separates
code from data. Even with erb/eruby, though, you could do something
like:

<table>
  <% max = data.size
     data.each_with_index do |el, ix| %>
    <tr class="<%= (((ix % 2) == 0) ? "even" : "odd") +
           ((ix == max) ? " last" : "") %>">
    <td><%= el %></td>
  </tr>
  <% end %>
</table>

There's other ways to do this, but as I don't really do a lot of stuff
that needs this, this is simple enough.

-austin
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

I agree with DHH for the most part (I have to read it in more detail but for now, I'll grant the argument). However, he's talking about web applications that follow a MVC pattern. As it turns out, that's not the ONLY type of problem to solve with ruby.

My problem is primarily one of content management. I have a client who sells widgets. They're not selling widgets online they're just doing promotional marketing pieces. Normally you'd just write the HTML directly and be done with it. However, sometimes, as a web developer, you have to write fairly complex markup in order to make things work out the way you want to. Unless you want to maintain the site yourself, a general pain in the neck, you need some mechanism to hide complexity from your clients yet allow them to edit the content themselves. In some ways this is what textile does (hiding the complexity of HTML from authors) but I need to be able to create more complex behaviors than what textile does.

Actually DHH says something that I think supports my point:

Extracting complex view logic is painful: With tag libraries, it's possible to be a good programmer and rid the views of complex logic by extracting code and replace it by tags. That is a noble and right path to follow. The problem is when the effort required to do the right thing is so intense that its basically a project in itself. Then its not something you're gently invited to do. It's a huge barrier and easy source of procrastination ("I'll extract later...") and guilt ("If only I had extracted sooner...").

I simply have a different view of complexity. I want to extract those things that are simple from my point of view but complex from the point of view of content authors.

Adam

···

On 26-Sep-05, at 2:53 PM, Devin Mullins wrote:

Hi, Adam,

First, DHH's opinion on this matter might be of interest to you:
http://www.loudthinking.com/arc/000408.html
(DHH = The Rails Guy, btw)

Second, the best way I can think of to achieve something like what you're talking about in ERB would look like this:

class AvTable
def initialize(out)
   @out = out; @side = :odd
end
def trow
   @out << %Q{<tr class="#@side">}
   yield
   @out << "</tr>\n"
   @side = (@side == :odd) ? :even : :odd
end
end

def av_table(out)
out << "<table>\n"
yield AvTable.new(out)
out << "</table>\n"
end

a = ERB.new <<RHTML
<% av_table(_erbout) do |av| %>
<% av.trow do %><td>...</td><% end %>
<% end %>
RHTML

a.result.display

Not sure how you would take care of "last", though (without writing an internal iterator for your data), but I'm no expert, and this is probably a crappy way of achieving what you're after. (I, for instance, am not a fan of passing around _erbout.)

Devin

Adam Van Den Hoven wrote:

Hey guys,

I've been dabbling with ruby on and off for a year or so and recently more often. At work we do Java development and I keep thinking that it would be nice to be able to bring some of the stuff I designed there into my own work, which I want to do in ruby.

I was wondering if anyone had thought about adding something like the Java TagLibs to ruby (I guess it would embedded ruby). In my case, it would make long term maintenance of files MUCH easier as I can give it to a non-technical person without much documentation. In most cases people who don't understand programming do understand parts of HTML markup. If I could hide what is currently inline code behind things that look like tags, its easier to give maintenance over to non-technical folks.

Here's a simple example. Often you want to do tiger striping on tables (alternate background color on each row). Because there isn't sufficiently wide spread support for CSS2 and CSS3 selectors, you tend to do the following:

<table>
        <tr class="odd"><td>...</td></tr>
        <tr class="even"><td>...</td></tr>
        <tr class="odd"><td>...</td></tr>
        <tr class="even"><td>...</td></tr>
        <tr class="odd"><td>...</td></tr>
        <tr class="even last"><td>...</td></tr>
</table>

Unfortunately, if you want to add something between rows 4 and 5 you need to reset all your classes. This can get complicated. However, if I had a taglib I could ask my content authors to write the following:

<av:table>
    <av:trow><td>...</td></av:trow >
</av:table>

And leave the generation up to the code.

I can think of hundreds of specific tags I might create, depending on the situation, which would make authoring content easier and would give me better control over the rendering of a page. It could also make writing code easier in general. It would also be useful to have many of the tags defined in the JSTL.

Just a thought I had.
Adam

Devin Mullins wrote:

Hi, Adam,

(I, for instance, am not a fan of passing around _erbout.)

I cleaned up the syntax, btw, with a dependency on my favorite Rails support class:

require 'rubygems'
require 'binding_of_caller'

class AvTable
  def initialize(out)
    @out = out; @side = :odd
  end
  def av_trow
    @out << %Q{<tr class="#@side">}
    yield
    @out << "</tr>"
    @side = (@side == :odd) ? :even : :odd
  end
end

def av_table(&blk)
  Binding.of_caller do |b|
    out = eval '_erbout', b
    out << "<table>"
    AvTable.new(out).instance_eval &blk
    out << "</table>"
  end
end

ERB.new( <<RHTML ).result.display
<% av_table do %>
  <% av_trow do %><td>...</td><% end %>
<% end %>
RHTML

__END__

And, of course, you can replace do ... end with { ... } if you prefer.

Yeah, you might need/want a different templating framework than yet exists for Ruby. I dunno. I hope somebody else responds who has experience in some of the other templating systems, 'cause I'm pretty much clueless. :slight_smile:

Devin

I tend to build a site once then provide a style guide and show them how to update their content. There is no way I'm going to be able to document for my client the mechanic how to create a table on some arbitrary page using the code you have below.

I bet you could use ERb and some helper methods to great affect for something like this.

Its a lot simpler, IMHO, if I just told them to write the following:

<x:photo imghref="someurl">
    <x:title>Fishermen at the <a href="/steveston.rsp">Steveston docs</a>, circa 1843</x:title>
    <x:caption><p>Yadda yadda yadda.</p><p>Blah blah blah</p></x:caption>
    <x:cite photographer="James Tyson" publication="Steveston Chronicle" year="1983" />
</x:photo>

I can then write my markup from that.

An example of what I'm thinking:

<%= photo :imgref => "someurl",
           :title => "Fishermen at the...",
           :caption => "<p>Yadda yadda yadda...",
           :photographer => "James Tyson",
           :publication => "Steveston Chronicle",
           :year => 1983 %>

That's trivial to implement as a simple Ruby method call where you will have the full language at your command to build up whatever return value you need.

Just a thought.

James Edward Gray II

···

On Sep 26, 2005, at 4:25 PM, Adam Van Den Hoven wrote:

That's excellent.

Now "all" we need is a parser to convert

<av_table> ...</av_table>

into

av_table do

...

end

···

On 26-Sep-05, at 3:39 PM, Devin Mullins wrote:

Devin Mullins wrote:

Hi, Adam,

(I, for instance, am not a fan of passing around _erbout.)

I cleaned up the syntax, btw, with a dependency on my favorite Rails support class:

require 'rubygems'
require 'binding_of_caller'

class AvTable
def initialize(out)
   @out = out; @side = :odd
end
def av_trow
   @out << %Q{<tr class="#@side">}
   yield
   @out << "</tr>"
   @side = (@side == :odd) ? :even : :odd
end
end

def av_table(&blk)
Binding.of_caller do |b|
   out = eval '_erbout', b
   out << "<table>"
   AvTable.new(out).instance_eval &blk
   out << "</table>"
end
end

ERB.new( <<RHTML ).result.display
<% av_table do %>
<% av_trow do %><td>...</td><% end %>
<% end %>
RHTML

__END__

And, of course, you can replace do ... end with { ... } if you prefer.

Yeah, you might need/want a different templating framework than yet exists for Ruby. I dunno. I hope somebody else responds who has experience in some of the other templating systems, 'cause I'm pretty much clueless. :slight_smile:

Devin

I'm not sure, but I *think* what you want is a Content Management System (CMS). They
enable non-techies to maintain their websites. See:


http://www.cmswatch.com/
http://sourceforge.net/search/?type=soft&exact=0&q=content+AND+management&offset=25

To see if I've guessed right.

Warren Seltzer

···

-----Original Message-----
From: Adam Van Den Hoven [mailto:mail@adamvandenhoven.com]
Sent: Tuesday, September 27, 2005 12:26 AM
To: ruby-talk ML
Subject: Re: Embedded Ruby and Tag Libs

... Stuff about salmon fishing and Tag Libs elided...

James,

I agree, except that it starts to fall apart as you get more complex.

Lets take an example from rails that REALLY annoys me: form_tag. It follows largely the same form you suggest.

Right now to make a form in rails you do the following:

<%= form_tag :controller=>"foo" :action=>"bar" %>
    Name:
     <%= text_field "person", "name", "size" => 20 %>
     Password:
     <%= password_field "person", "password", "maxsize" => 20 %>
     Single?:
     <%= check_box "person", "single" %>
     Description:
     <%= text_area "person", "description", "cols" => 20 %>
     <input type="submit" value="Save">
<%= end_form_tag %>

There's no easy way to encapsulate this into a single method, although Devin (as I'm writting this) has some good suggestions.

···

On 26-Sep-05, at 2:49 PM, James Edward Gray II wrote:

On Sep 26, 2005, at 4:25 PM, Adam Van Den Hoven wrote:

I tend to build a site once then provide a style guide and show them how to update their content. There is no way I'm going to be able to document for my client the mechanic how to create a table on some arbitrary page using the code you have below.

I bet you could use ERb and some helper methods to great affect for something like this.

Its a lot simpler, IMHO, if I just told them to write the following:

<x:photo imghref="someurl">
    <x:title>Fishermen at the <a href="/steveston.rsp">Steveston docs</a>, circa 1843</x:title>
    <x:caption><p>Yadda yadda yadda.</p><p>Blah blah blah</p></x:caption>
    <x:cite photographer="James Tyson" publication="Steveston Chronicle" year="1983" />
</x:photo>

I can then write my markup from that.

An example of what I'm thinking:

<%= photo :imgref => "someurl",
          :title => "Fishermen at the...",
          :caption => "<p>Yadda yadda yadda...",
          :photographer => "James Tyson",
          :publication => "Steveston Chronicle",
          :year => 1983 %>

That's trivial to implement as a simple Ruby method call where you will have the full language at your command to build up whatever return value you need.

Just a thought.

James Edward Gray II

If you can count on valid XML, REXML (a standard Ruby library) makes everything you are asking for pretty easy.

James Edward Gray II

···

On Sep 26, 2005, at 5:57 PM, Adam Van Den Hoven wrote:

That's excellent.

Now "all" we need is a parser to convert

<av_table> ...</av_table>

into

av_table do

...

end

Adam Van Den Hoven wrote:

That's excellent.

Thanks.

Now "all" we need is a parser to convert

<av_table> ...</av_table>

into

av_table do ... end

You're on your own for that one. I don't really see the light of making them XML tags, myself, outside of that they're punctuationally cleaner in this example. It doesn't seem to me like "web developers" are going to have any more difficulting learning the second syntax than the first.

It was pretty wacky to write that thing, though. I can see the benefit of a higher-order abstraction in a templating language, but I doubt you're going to find that in ERb any time soon, as it caters to much more than HTMLers.

You might want to take a look at Amrita. It takes an entirely different approach to your problem, but does solve it. http://amrita.sourceforge.jp/

Devin

Yes.

I've been working with Content Management Systems for 6 years, both developing them and in deploying them for clients.

If I had a way to use tags instead of code, I would be a long way towards building a simple CMS.
     ==> SFTP & Text Editor for authoring.
     ==> RSP & Taglibs for rendering

Adam

···

On 27-Sep-05, at 7:32 AM, Warren Seltzer wrote:

I'm not sure, but I *think* what you want is a Content Management System (CMS). They
enable non-techies to maintain their websites. See:

http://www.eweek.com/article2/0,1895,1855201,00.asp
http://www.cmswatch.com/
content AND management free download - SourceForge

To see if I've guessed right.

Warren Seltzer

-----Original Message-----
From: Adam Van Den Hoven [mailto:mail@adamvandenhoven.com]
Sent: Tuesday, September 27, 2005 12:26 AM
To: ruby-talk ML
Subject: Re: Embedded Ruby and Tag Libs

... Stuff about salmon fishing and Tag Libs elided...

Would you mind showing how you would clean this up with an XML syntax?

I personally find XML very wordy.

James Edward Gray II

···

On Sep 26, 2005, at 5:56 PM, Adam Van Den Hoven wrote:

James,

I agree, except that it starts to fall apart as you get more complex.

Lets take an example from rails that REALLY annoys me: form_tag. It follows largely the same form you suggest.

Right now to make a form in rails you do the following:

<%= form_tag :controller=>"foo" :action=>"bar" %>
   Name:
    <%= text_field "person", "name", "size" => 20 %>
    Password:
    <%= password_field "person", "password", "maxsize" => 20 %>
    Single?:
    <%= check_box "person", "single" %>
    Description:
    <%= text_area "person", "description", "cols" => 20 %>
    <input type="submit" value="Save">
<%= end_form_tag %>

There's no easy way to encapsulate this into a single method, although Devin (as I'm writting this) has some good suggestions.

The problem is that I LOVE XML, and find it easy to work with, mostly because its easy to abstract complex things with it... which is how I think.

Without thinking of MUCH better ways to do this, I submit the following:

<av:form model="person">
     <av:field name="name" />
     <av:field name="password" />
     <av:field name="single" />
     <av:field name="description" />
</av:form>

I would then do much the same thing that rails does now where you would assume (but provide ways to explicitly set) things like localization key for the label, the controller to call etc. I would look at the model, "figure out" that name is a string, password is secret, person is boolean and description is text and render the correct markup that I define for each of those field types. Look to see if a Person is already provided (and assume an update) otherwise create one (and assume a New).

In rough hand waving.

Keep in mind that I'm looking for a way to define my tag, not for someone to define my tag.

I'm assuming that whatever parser converts <%= ... %> in to ruby code can just as easily be setup to do the same thing with tags, maybe using REXML (or what ever its called). It just needs to be more precise.

Adam

···

On 26-Sep-05, at 4:30 PM, James Edward Gray II wrote:

On Sep 26, 2005, at 5:56 PM, Adam Van Den Hoven wrote:

James,

I agree, except that it starts to fall apart as you get more complex.

Lets take an example from rails that REALLY annoys me: form_tag. It follows largely the same form you suggest.

Right now to make a form in rails you do the following:

<%= form_tag :controller=>"foo" :action=>"bar" %>
   Name:
    <%= text_field "person", "name", "size" => 20 %>
    Password:
    <%= password_field "person", "password", "maxsize" => 20 %>
    Single?:
    <%= check_box "person", "single" %>
    Description:
    <%= text_area "person", "description", "cols" => 20 %>
    <input type="submit" value="Save">
<%= end_form_tag %>

There's no easy way to encapsulate this into a single method, although Devin (as I'm writting this) has some good suggestions.

Would you mind showing how you would clean this up with an XML syntax?

I personally find XML very wordy.

James Edward Gray II

The problem is that I LOVE XML, and find it easy to work with, mostly because its easy to abstract complex things with it... which is how I think.

Oh well. I'm fine with it if with disagree on that. I really am only trying to help, not rob you of your favorite tool, I promise. :wink:

Without thinking of MUCH better ways to do this, I submit the following:

<av:form model="person">
    <av:field name="name" />
    <av:field name="password" />
    <av:field name="single" />
    <av:field name="description" />
</av:form>

My offer to that would be similar to my last one, though I think this one is much easier:

<%= person %w{name password single description} %>

We don't have to do things the Rails' way. :wink: I don't know about you, but I know which one of those I would rather be typing a lot of.

I'll stop trying to convince you now though and see if I can't provide some information you would consider useful...

I'm assuming that whatever parser converts <%= ... %> in to ruby code can just as easily be setup to do the same thing with tags

No, I don't think ERb is going to meet your needs here.

, maybe using REXML (or what ever its called). It just needs to be more precise.

I really believe REXML is what you are looking for. Everything you have asked for is pretty easy with it. It will let you do all these transformations with a combination of XPath and Ruby which I assume you will find quite comfortable. You can learn more from the documentation:

http://www.germane-software.com/software/rexml/docs/tutorial.html

Hope that helps.

James Edward Gray II

···

On Sep 26, 2005, at 6:47 PM, Adam Van Den Hoven wrote: