ROEL voor RoR: Gewoon Ruby voor je HTML

Door Gamebuster op vrijdag 27 september 2013 01:40 - Reacties (4)
Categorie: if(post.relatedTo("programming")), Views: 2.914

In mijn eerdere blogpost besprak ik het idee om in plaats van HAML of ERB een plain-ruby syntax te gebruiken. In mijn welbekende naïviteit dacht ik dat de implementatie met wat method-missings wel zou lukken.

Er zat echter 1 fatal flaw in mijn implementatie-idee: In combinatie met bestaande helpers zou dat nooit goed werken, aangezien die ontworpen zijn om een string te return'en. Zo zou bijv. de volgende code een ongewenst resultaat geven:


Ruby:
1
2
3
4
div {
  content_tag :foo
  bar
}



Het verwachte en gewenste resultaat is hier:

HTML:
1
2
3
4
<div>
  <foo></foo>
  <bar></bar>
</div>



... maar in de realiteit zou de foo-tag nooit meegenomen worden, omdat alleen de return-value van de laatste method in het block meegenomen kan worden. Dit is op te lossen door overal een +je tussen te plaatsen, maar dit heeft een sterk negatieve impact op het gemak van de syntax.

Ik heb daarom in de huidige implementatie ervoor gekozen om met een Ruby parser de templates te "hercompilen" naar de gewenste functionaliteit, met name door overal +jes tussen te plaatsen. Dit maakt het dan ook mogelijk om bijv. dit te doen:


Ruby:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
"<!DOCTYPE html>"
html lang: I18n.current_locale do
    head do
        title @title
        meta charset: "utf-8"
        stylesheet_link_tag "application"
        javascript_include_tag "application"
    end
    body id: "#{params[:controller]}_#{params[:action]}".gsub(/^[a-z0-9_]+/, "-") do
        render "head"
        div class: "container", &content
        render "foot"
    end
end



Het resultaat van mijn huidige "hercompiler" is:


Ruby:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
"<!DOCTYPE html>" +
html({ :lang => I18n.current_locale }){
  head{
    title(@title) +
    meta({ :charset => "utf-8" }) +
    stylesheet_link_tag("application") +
    javascript_include_tag("application")
  } +
  body({ :id => (params.[](:controller).to_s+"_"+params.[](:action).to_s).gsub(/^[a-z0-9_]+/, "-") }){
    render("head") +
    div({ :class => "container" }, &content) +
    render("foot")
  }
}



Ik heb de resulterende code nog niet getest omdat ik nog geen "enviroment" met de gewenste method-missings heb om deze uit te voeren. De code lijkt er zover al wel goed uit te zien: De resulterende code wordt gegenereerd door het parser-resultaat in te lezen en om te zetten in Ruby.

In de toekomst zou dit misschien als Gem in een RoR project gezet worden. Deze zal automagisch iedere template eenmalig compilen als een class, welke dan aangeroepen wordt met de huidige context om de pagina te renderen.

Bron van mijn huidige "compiler": http://pastebin.com/hs6tJYM0
Ik ben me ervan bewust dat mijn compiler vast nog bomvol bugs zit: Ik heb deze vlugjes geschreven om mijn idee werkend te krijgen.

Volgende: ROEL voor RoR: Toch maar wat anders 10-'13 ROEL voor RoR: Toch maar wat anders
Volgende: Videobewerking 09-'13 Videobewerking

Reacties


Door Tweakers user Jogai, vrijdag 27 september 2013 15:45

vital flaw = fatal flaw denk ik? :Y)

Voor de rest geen verstand van ruby, maar het lijkt mij een onnodig omslachtige manier om html te schrijven.

Door Tweakers user Gamebuster, vrijdag 27 september 2013 15:49

Jogai schreef op vrijdag 27 september 2013 @ 15:45:
vital flaw = fatal flaw denk ik? :Y)
Lol, ja. vaal.
Voor de rest geen verstand van ruby, maar het lijkt mij een onnodig omslachtige manier om html te schrijven.
Waarom?

[Reactie gewijzigd op vrijdag 27 september 2013 15:49]


Door Tweakers user Helmet, zaterdag 28 september 2013 11:34

Waarom kijk je niet eens naar slim (http://www.slim-lang.org) of haml? Volgens mij doen deze ongeveer wat jij zoekt ?

Door Tweakers user Gamebuster, zaterdag 28 september 2013 13:41

Helmet schreef op zaterdag 28 september 2013 @ 11:34:
Waarom kijk je niet eens naar slim (http://www.slim-lang.org) of haml? Volgens mij doen deze ongeveer wat jij zoekt ?
Niet helemaal.
- Voor zowel Slim als HAML moet je een nieuwe syntax leren.
- Het is geen ruby.

Mijn oplossing is bedoeld om de grens tussen helpers en (losse) HTML tags te verkleinen, zodat het geen belemmering vormt om helpers toe te voegen. Zo kan je je layout voornamelijk opmaken met helpers.

Reageren is niet meer mogelijk