# \[ANN\] yhtml plugin

**URL:** <https://www.ruby-forum.com/t/ann-yhtml-plugin/99913>\
**Category:** Rails\
**Created:** [July 26, 2006, 5:25am UTC](https://www.ruby-forum.com/t/ann-yhtml-plugin/99913 "2006-07-26T05:25:15Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![wycats](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/eb9ed0/32.png) [@wycats](https://www.ruby-forum.com/u/wycats)\
**Post date:** [July 26, 2006, 5:25am UTC](https://www.ruby-forum.com/t/ann-yhtml-plugin/99913/1 "2006-07-26T05:25:15Z")

</div>

I have released a yhtml plugin, which is available at  
[http://http](http://http)://svn.visualjquery.com/admin\_console/trunk/admin\_console/vendor/plugins/yhtml

You can also get my other plugins, specificlly: the pre-alpha  
administrative console (AJAX-based scaffolding engine),  
acts\_as\_automatic, which allows you to define associations in a single  
yaml file, and not need to define has\_many, has\_one, belongs\_to, or  
acts\_as\_list at  
[http://svn.visualjquery.com/admin\_console/trunk/admin\_console/vendor/plugins/](http://svn.visualjquery.com/admin_console/trunk/admin_console/vendor/plugins/)

Incidentally, the code in the plugins directly is my own, with the  
exception of the Engines plugin, which is needed for the admin console  
engine, as well as file\_column, which I stuck in the engine to provide  
future file\_column support. The time\_select lib that I included in the  
admin console plugin is cannibalized from a number of sources, but is  
substantially my own.

The yhtml plugin adds a rendering engine based on yaml.

# Example yhtml

NOTE: The controller defines @hello as “- Title”

- html:
  - head:
    - title: My Title \<%= @hello %\>
    - style: |  
body { font-family: verdana, sans-serif }  
p { font-weight: bold }  
li { list-style-type: none }

  - body:
    - ul:
      - li:
        - {!id: One, !class: One T.}
        - Text  
\<% 1.upto(10) do |count| %\>

      - li: \<%= count %\>  
\<% end %\>
      - li: Text
      - li: [{!id: Two, !class: One T., !style: “height: 30px; width:  
20px”}, LI]
      - li:
        - img: {  
!src:  
[http://ec1.images-amazon.com/images/G/01/nav2/images/skins/teal/logo-on.gif](http://ec1.images-amazon.com/images/G/01/nav2/images/skins/teal/logo-on.gif)  
}

    - p: Some More Text
    - table:
      - {!border: 1}
      - tr:
        - td: 1,1
        - td: 1,2

      - tr:
        - td: 2,1
        - td: |  
\<%= 10.days.ago %\>

# Result from the yhtml renderer
 My Title - Title body { font-family: verdana, sans-serif } p { font-weight: bold } li { list-style-type: none } 
- Text

```
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>

  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
  <li>Text</li>
  <li class="One T." id="Two" style="height: 30px; width: 

```

20px"\>LI

```
  <li>
    <img 

```

src=“[http://ec1.images-amazon.com/images/G/01/nav2/images/skins/teal/logo-on.gif](http://ec1.images-amazon.com/images/G/01/nav2/images/skins/teal/logo-on.gif)”  
/\>

  

Some More Text

  
  
  

```
    <td>12</td>
  </tr>
  <tr>
    <td>21</td>
    <td>Sat Jul 15 23:09:43 Eastern Standard Time 2006</td>
  </tr>
</table>

```

# Discussion

The yhtml parser converts the hash returned by the YHTML parser into a  
tree of YamlNodes.

A YamlNode contains:

- A tag name (html, body, head, li, etc.)
- Text contents
- Parameters
- Children that are YamlNodes

The parser then recursively parses the YamlNode tree, creating HTML with  
appropriate indents.

You can put plain text into the YAML, which will not be parsed, by using  
YAML’s “|” operator  
for literals. The example above uses the operator.

# Limitation

A YamlNode cannot contain both plain-text contents and child YamlNodes.  
At the moment, this  
will cause strange issues. If you want plain text and child nodes, wrap  
the text in span, or  
other tags. This limitation will be resolved in a future version.

The limitation is the result of the fact that the parser stores content  
as an attribute, and  
children as another (to make the recursive parsing easier), so the HTML  
builder has no way of  
knowing where in the list of children to put the content.

| 11 |

---

<div class="post-metadata">

**Author:** ![wycats](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/eb9ed0/32.png) [@wycats](https://www.ruby-forum.com/u/wycats)\
**Post date:** [July 26, 2006, 6:27am UTC](https://www.ruby-forum.com/t/ann-yhtml-plugin/99913/2 "2006-07-26T06:27:04Z")

</div>

> I have released a yhtml plugin, which is available at

Don’t take this the wrong way, but I have to ask … what’s the use-case  
for  
this?

Just curious, thanks.

---

<div class="post-metadata">

**Author:** ![wycats](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/eb9ed0/32.png) [@wycats](https://www.ruby-forum.com/u/wycats)\
**Post date:** [July 26, 2006, 2:30pm UTC](https://www.ruby-forum.com/t/ann-yhtml-plugin/99913/3 "2006-07-26T14:30:23Z")

</div>

Brittain wrote:

> > I have released a yhtml plugin, which is available at
> 
> Don’t take this the wrong way, but I have to ask … what’s the use-case  
> for  
> this?
> 
> Just curious, thanks.

First up, it was an excercise in (and an example of) a simple  
alternative renderer, as well as using a recursive function to generate  
HTML-like structures.

Second off, the resulting template is a far sight more readable than  
regular HTML, because it enforces sane indenting, and doesn’t require  
closing tags. In essence, the YAML template is a good representation of  
a _node-map_ in the HTML tree, which I think can be pretty useful  
sometimes.

The plugin also generates much cleaner HTML than the normal rhtml  
templates, because it automatically indents raw text (by converting line  
breaks in literals into properly indented line-breaks), and because of  
the indenting strictness, it’s very easy to create nice-looking,  
well-indented HTML.

It also makes it much harder to create non-validating HTML (although  
it’s certainly still possible to put things in contexts they don’t  
belong). I forsee future versions of this project doing things that the  
helpers already do (like adding alt’s in images that don’t have them and  
what have you).

The bottom line is this: It was mainly a proof of concept (for myself  
more than anyone) but the format definitely has its advantages.

---

<div class="post-metadata">

**Author:** ![wycats](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/eb9ed0/32.png) [@wycats](https://www.ruby-forum.com/u/wycats)\
**Post date:** [July 27, 2006, 10:26am UTC](https://www.ruby-forum.com/t/ann-yhtml-plugin/99913/4 "2006-07-27T10:26:35Z")

</div>

Yehuda K. \<wycats@…\> writes:

> The bottom line is this: It was mainly a proof of concept (for myself  
> more than anyone) but the format definitely has its advantages.

Gotcha, nice work. Thanks.

---

<div class="post-metadata">

**Author:** ![wycats](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/w/eb9ed0/32.png) [@wycats](https://www.ruby-forum.com/u/wycats)\
**Post date:** [July 27, 2006, 8:06pm UTC](https://www.ruby-forum.com/t/ann-yhtml-plugin/99913/5 "2006-07-27T20:06:22Z")

</div>

I love it how people start to think the same.

I’ve been working the last couple months on HAML which is _not_ YAML  
but is something similar in spirit to what you’ve created here, with a  
few major differences in semantics.

I’ve applied to RailConf Europe to do a presentation revealing HAML,  
so we’ll see when it gets released.

I’m just glad to see that I’m not the only one who is sick and tired  
of living in 1996 with all the inline-html rendering. Beautiful markup  
is not just a last-minute detail!

-hampton.
