Post on 09-May-2015
description
copyright(c) 2010 kuwata-lab.com all rights reserved.
How to Make Designer-Friendly Template Engine- Keep Template as pure HTML -
makoto kuwatahttp://www.kuwata-lab.com/
RubyKaigi 2010
1
copyright(c) 2010 kuwata-lab.com all rights reserved.
README.txt✤ For template engine users: get correct knowledge
✤ For template engine desingers: get an ideal solution
✤ Want correct wrong explanations related to template engine
✤ Want to insist that eRuby is not an ideal solution
✤ Template engine users and designers
Goal
Motiv.
Target
2
copyright(c) 2010 kuwata-lab.com all rights reserved.
I must apologize...
✤ I would talk about...✤ How to keep html design of template files✤ What are performance bottole necks of engine✤ What is wrong about existing template engines✤ How to design engine which is designer-friendly, very fast, and easy to implement in any languages
✤ But I only have 30 minutes✤ I can talk about the first issue
3
copyright(c) 2010 kuwata-lab.com all rights reserved.
Reference✤ Rubyist Magazine - Guide to Template System
✤ http://jp.rubyist.net/magazine/?0024-TemplateSystem✤ http://jp.rubyist.net/magazine/?0024-TemplateSystem2
4
copyright(c) 2010 kuwata-lab.com all rights reserved.
Agenda
✤ Fundamental section:✤ Business Layer and Presentation Layer✤ Existing Issues and the Cause✤ Think about Presentation Logic
✤ Kwartz section:✤ Introduction to Kwartz template engine✤ Presentation Logic Pattern
5
copyright(c) 2010 kuwata-lab.com all rights reserved.
Fundamental section:Business Layer & Presentation Layer
6
copyright(c) 2010 kuwata-lab.com all rights reserved.
Business layer and Presentation layer
✤ Business layer✤ WHAT should be displayed?✤ by main program
✤ Presentation layer✤ HOW to display it?✤ by template engine, template file
7
copyright(c) 2010 kuwata-lab.com all rights reserved.
Data and Logic
✤ Both layers have each data and logic
Business layer(main program)
Presentation layer(template engine)
Data Business Data Presentation Data
Logic Business Logic Presentation Logic
separated by template engine
8
copyright(c) 2010 kuwata-lab.com all rights reserved.
Applicaiton Example
✤ Select top 20
✤ of book sales
✤ by <table> tag
✤ with toggling bgcolor
Business logic
Business data
Presentation logic
Presentaion data
9
copyright(c) 2010 kuwata-lab.com all rights reserved.
Frequent Misunderstandings (1)
✤ Template engine separates presentation from logic.
✤ Template engine separatin presentation layer from business layer.✤ Presentation layer have own logics.
Mis:
Truth:
common mistake in Japan...
10
copyright(c) 2010 kuwata-lab.com all rights reserved.
Frequent Misunderstandings (2)
✤ Presentation layer shouldn't contain any logics.
✤ Presentation layer should contain presentation logics.✤ "HTML template shouldn't contain any presentation logics" and "Layers should be separated" are different things.
Mis:
Truth:
11
copyright(c) 2010 kuwata-lab.com all rights reserved.
Add-up
✤ Business layer✤ WHAT should be displayed?✤ By main program
✤ Presentation layer✤ HOW to display it?✤ By template engine and template file
✤ Both layers have each data and logics
12
copyright(c) 2010 kuwata-lab.com all rights reserved.
Fundamental section:Existing Issues and the Cause
13
copyright(c) 2010 kuwata-lab.com all rights reserved.
Templates Annoys Designers
<table><% @arr.each { %> ....<% } %></table>
<table><forEach items=""> ....</forEach></table>
<table><?php foreach() { ?> ....<?php } ?></table>
ProjectA: Rails
ProjectB: JSP
ProjectC: PHP
Designer: Why I must master so much langs?
14
copyright(c) 2010 kuwata-lab.com all rights reserved.
Edit & Update the same file
<table><% @arr.each { %> ....<% } %></table>
template file
Designer Programmer
edit HTMLedit presentaion logic
Conflict!
15
copyright(c) 2010 kuwata-lab.com all rights reserved.
The Cause of Issues
<table><% i = 0 %><% @arr.eachx do ¦x¦ %><% i += i %><% c = i.odd ? %><% 'odd':'even' %> <tr class="<%=c%>"> <td><%= x %></td> </tr><% end %></table>
template file
pure HTML is the solution
✤ It is the cause that presentation logics are embedded in template file
16
copyright(c) 2010 kuwata-lab.com all rights reserved.
Pure HTML Template is Great✤ Easy to preview by browsers✤ No need to learn a lot of template langs!✤ Easy to validate by HTML validator✤ Allow to use their favorite HTML editor
✤ Avoid edit confliction✤ Remove whitespaces to reduce traffic✤ Transform template files for mobile phones
forDesigner
forProgram
mer
17
copyright(c) 2010 kuwata-lab.com all rights reserved.
The Question which bothered Matz
✤ So, where is presentation logics?
(Summary)When view layer needs some logics,where should I put it in?I don't want it to be in HTML template...
Matz diary (2004-08-24)http://www.rubyist.net/~matz/20040824.html#p01
18
copyright(c) 2010 kuwata-lab.com all rights reserved.
Add-up
✤ Presentation logics in template files causes a lot of problems
✤ Pure HTML template is great✤ Where is presentation logics?
19
copyright(c) 2010 kuwata-lab.com all rights reserved.
Fundamenta section:Think about Presentaion Logic
20
copyright(c) 2010 kuwata-lab.com all rights reserved.
Where should be Presentation Logics?
Presentation Logic+ Presentaion Data Business Logic & Data
Presentation Data Presentation Logic+Business Logic & Data
Presentation LogicBusiness Logic & Data
Presentation Data
A. In template file (eRuby, JSP, Kid)
B. In main program (Amrita2, XMLC, HTML::Template)
C. In independed file (Kwartz, Tapestry, Mayaa)
template file main program21
copyright(c) 2010 kuwata-lab.com all rights reserved.
A. In Template File (1)
<table><% odd = false %><% for item in @list %><% odd = ! odd<% cls = odd ? 'odd' : 'even' %> <tr class="<%= cls %>"> <td><%=h item %></td> </tr><% end %></table>
ex: eRuby (Ruby)
•HTML and non-HTML are mixed→ never pure HTML !
22
copyright(c) 2010 kuwata-lab.com all rights reserved.
A. In Template File (2)
<table> <c:forEach var="item" items="${list}" varStatus="loop"> <c:set var="klass" value="${loop.count%2==0?'odd':'even'}" /> <tr class="${klass}"> <td><c:out value="${item}" /></td> </tr> </c:forEach></table>
ex: JSP with custom tags (Java)
•Even if you use custom tags, presentation logics are mixed into HTML (just same as eRuby).
23
copyright(c) 2010 kuwata-lab.com all rights reserved.
A. In Template File (3)
<table> <tr py:for="i, item in enumerate(items)" class="${i % 2 and 'even' or 'odd'}"> <td py:content="item">dummy</td> </tr></table>
ex: Kid template engine (Python)
•Using HTML tags and attributess, Kid aquired designer-friendly template!•But notice that presentation logics are still embedded into templates
24
copyright(c) 2010 kuwata-lab.com all rights reserved.
A. In Template File (4)✤ Presentation layer (= template file) is compretely separated from business layer.
✤ Easy to uderstand, easy to implement
✤ Hard to keep pure HTML✤ Designer and programmer will edit the same file at the same time, and conflicted in the result
✤ Designer may break presentation logics in template files accidentally
Pros.Cons.
25
copyright(c) 2010 kuwata-lab.com all rights reserved.
Where should be Presentation Logics?
Presentation Logic+ Presentaion Data Business Logic & Data
Presentation Data Presentation Logic+Business Logic & Data
Presentation LogicBusiness Logic & Data
Presentation Data
A. In template file (eRuby, JSP, Kid)
B. In main program (Amrita2, XMLC, HTML::Template)
C. In independed file (Kwartz, Tapestry, Mayaa)
template file main program26
copyright(c) 2010 kuwata-lab.com all rights reserved.
B. In Main Program (1)
<table> <tr id="list" class="odd"> <td id="item">dummy</td> </tr></table>
ex: Amrita2 temlate file (Ruby)
•Just to place "mark" (= id attr in Amrita2) into template file•Pure HTML template (because no presentation logics in it)
27
copyright(c) 2010 kuwata-lab.com all rights reserved.
B. In Main Program (2)
## business data to displaylist = [ 'A', 'B', 'C' ]## presentation logiclist2 = []; odd = falsefor x in list cls = (odd = !odd) ? 'odd' : 'even' item2 = a(:class=>cls) { {:item=>x} } list2 << item2endcontext = { :list=>list2 }## read template and render with datatmpl = Amrita2::TemplateFile.new('ex1.html')tmpl.expand(html='', context)print html
ex: Amrita2 main program (Ruby)
•Necessary to "process" bussiness data for presentation layer
28
copyright(c) 2010 kuwata-lab.com all rights reserved.
B. In Main Program (3)✤ Just embed "mark" into template✤ pure HTML template (in most cases)✤ No conflicts when editing files✤ No accidental change of logics by designer
✤ Business layer and Presentation layer are NOT separated! (*)
✤ Confusable usage (because logic should be represented by data)
(*) devisable to avoid (ex. define dedicated class)
Pros.Cons.
29
copyright(c) 2010 kuwata-lab.com all rights reserved.
Where should be Presentation Logics?
Presentation Logic+ Presentaion Data Business Logic & Data
Presentation Data Presentation Logic+Business Logic & Data
Presentation LogicBusiness Logic & Data
Presentation Data
A. In template file (eRuby, JSP, Kid)
B. In main program (Amrita2, XMLC, HTML::Template)
C. In independed file (Kwartz, Tapestry, Mayaa)
template file main program30
copyright(c) 2010 kuwata-lab.com all rights reserved.
C. In Independed File (1)
<table> <tr id="mark:list" class="odd"> <td id="mark:item">dummy</td> </tr></table>
ex: Kwartz presentation data file (Ruby)
•Just place "mark" (= id attr in Kwartz) in template file
31
copyright(c) 2010 kuwata-lab.com all rights reserved.
C. In Independent File (2)
#item { ## id="mark:item" value: x; ## display value of x}#list { ## id="mark:list" logic: { ## iterate over element for x in @list _elem end }}
ex: Kwartz presentation logic file (Ruby)
•Write your presentation logics just like CSS•No presentation logics in HTML !
32
copyright(c) 2010 kuwata-lab.com all rights reserved.
HTML(Document Structure)
CSS(Visual Design)
JavaScript(Client-side
Logic)
Kwartz(Presentation
Logic)
33
copyright(c) 2010 kuwata-lab.com all rights reserved.
C. In Independent File (3)✤ Business layer and Presentation layer are completely separated!
✤ Presentation data (=HTML) and Presentation logic are also separated!
✤ Pure HTML template✤ No conflicts when editiong files✤ No accidental modification of logics
✤ Number of files are increased
Pros.Cons.
34
copyright(c) 2010 kuwata-lab.com all rights reserved.
Important thing, More Important thing
✤ Important thing✤ Template format is pure HTML
✤ More important thing✤ Presentation logic should be separated (or independent) from others!
✤ Pure HTML template is just derivation from it
35
copyright(c) 2010 kuwata-lab.com all rights reserved.
Frequent Misunderstanding (1)
✤ My template is pure HTML, so presentation layer is separated!
✤ "Template is pure HTML" doesn't mean "Presentation layer is separated"✤ Probably she/he misunderstands "No logics in template" as "Presentation layer is separated"
Mis.:
Truth:
36
copyright(c) 2010 kuwata-lab.com all rights reserved.
Frequent Misunderstanding (2)
✤ Web designer may write buggy logic in raw PHP, so I introduced Smarty!
✤ Smarty can't prevent buggy logic nor accidental logic modification.✤ The root cause of the problem is that desginer can access to presention logic
✤ A radical solution is to separate presentation logic from template file
Mis.:
Truth:
37
copyright(c) 2010 kuwata-lab.com all rights reserved.
Add-up
✤ Presentation logic can be...✤ In template file (non-html, conflictions)✤ In main program (layers are not separated)✤ In independent file (ideal)
✤ Pure HTML template is important✤ Separation of presentation logic is more important
38
copyright(c) 2010 kuwata-lab.com all rights reserved.
Kwartz section:Introduction to Kwartz
39
copyright(c) 2010 kuwata-lab.com all rights reserved.
Kwartz Overview
✤ What is Kwartz?✤ A template engine which can separate Presentation logic from Presentation data (=HTML)
✤ Pure HTML template✤ Implemented in Ruby, PHP✤ http://www.kuwata-lab.com/kwartz/
40
copyright(c) 2010 kuwata-lab.com all rights reserved.
Example: Presentation Data
<table> <tr id="mark:list"> <td id="mark:item">Foo</td> </tr> <tr id="dummy:d1"> <td>Bar</td> </tr></table>
ex.html
Add "marking" (=id attr) to where you want to manipulate dinamically
`id="dummy:xxx"' means dummy elelment
41
copyright(c) 2010 kuwata-lab.com all rights reserved.
Example: Presentation Logic
#list { logic: { for x in @list _stag ## start-tag _cont ## content _etag ## end-tag end }}#item { value: x;}
ex.plogic Write presentation logic for each elements
Repeat <tr> element
Display value of x as content of <td> element
42
copyright(c) 2010 kuwata-lab.com all rights reserved.
Example: Compilation
<table><% for x in @list %> <tr> <td><%= x %></td> </tr><% end %></table>
•Attribute `id="mark:xxx"' is removed automatically(not removed if `id="xxx"')
•Element which has `id="dummy:xxx"' is also removed
$ kwartz -l eruby -p ex.plogic ex.html > ex.rhtml
Compile files into a eRuby file
ex.rhtml (compiled by Kwartz)
43
copyright(c) 2010 kuwata-lab.com all rights reserved.
Example: Main Program
## business data to be displayedlist = ['A', 'B', 'C']context = { :list => list }
## load template and render it with datarequire 'erubis'eruby = Erubis::Eruby.load_file('ex.rhtml')html = eruby.evaluate(context)print html
Main program doesn't require Kwartz
Main program
44
copyright(c) 2010 kuwata-lab.com all rights reserved.
Pros and Cons✤ pure HTML template✤ Very fast✤ Supports eRuby, PHP, JSP, and so on✤ Available with non-HTML text file
✤ Messy compile (should be automated)✤ Runtime error is reported with line number AFTER compiled code, not original source code
✤ Pros.
✤ Cons.
45
copyright(c) 2010 kuwata-lab.com all rights reserved.
Practical Examples (1)
#list { logic: { for item in @list _stag # start-tag _cont # content _etag # end-tag end }}
repeat over element#list { logic: { _stag for item in @list _cont end _etag }}
repeat only content
Useful to repeat <dt> and <dd>
46
copyright(c) 2010 kuwata-lab.com all rights reserved.
Practical Examples (2)
#list { logic: { if @list.size > 0 _stag _cont _etag end }}
display only when#list { logic: { _stag if @name.blank? print('World') else _cont end _etag }}
display default value
47
copyright(c) 2010 kuwata-lab.com all rights reserved.
Practical Examples (3)
#list { logic: { #_stag _cont #_etag }}
remove dummy tag
#list { logic: { _element(list2) }}
replace by other
#list { logic: { }}
remove dummy element
reuse a certain element
48
copyright(c) 2010 kuwata-lab.com all rights reserved.
Practical Examples (4)
#list { attrs: "class" cls; # attribue logic: { odd = false for x in @list odd = !odd cls = odd ? 'odd' : 'even' _elem end }}
より複雑なプレゼンテーションロジック
No need to touch HTML at all even if you change presentaion logic dramatically
Presentation logic is separated from HTML file
49
copyright(c) 2010 kuwata-lab.com all rights reserved.
Add-up
✤ Kwartz tempate engine✤ Separates presentation logics from presentation data (=HTML)
✤ Pure HTML Template✤ No need to touch HTML file at all even if you change presentation logics
50
copyright(c) 2010 kuwata-lab.com all rights reserved.
Kwartz section:Presentation Pattern
51
copyright(c) 2010 kuwata-lab.com all rights reserved.
Overview
✤ What is Presentation Pattern?✤ Best practices in presentation layer (data & logic)✤ (Notice that this is my original term and not popular at all)
✤ Very easy to understand, compared to GoF!✤ http://www.kuwata-lab.com/kwartz/kwartz3ruby-pattern-catalog.html
52
copyright(c) 2010 kuwata-lab.com all rights reserved.
List of Patterns✤ Replacement
✤ Replace Element with Value Pattern
✤ Replace Content with Value Pattern
✤ Default Content Pattern ✤ Replace Element with Element/Content Pattern
✤ Replace Content with Element/Content Pattern
✤ Deletion ✤ Delete Element Pattern ✤ Delete Tag Pattern
✤ Iteration ✤ Iterate Element Pattern ✤ Iterate Content Pattern
✤ Selection ✤ Select Element/Content Pattern
✤ Pick-up Element/Content Pattern
✤ Extract Element/Content Pattern
Today's menu
53
copyright(c) 2010 kuwata-lab.com all rights reserved.
Select Element Pattern
<div id="mark:message"> <div id="error"> ERROR! </div> <div id="warning"> Warning: </div> <div id="noerror"> No error. </dvi></div>
Add different id for each elems
✤ Req: Want to change data according to condition
#message { logic: { if status == 'error' _element(error) elsif status == 'warn' _element(warning) else _element(noerror) end }}
Select an elem according to condition
54
copyright(c) 2010 kuwata-lab.com all rights reserved.
Pick-up Element Pattern
<ol id="mark:list"> <li id="mark:item"> Item1 </li> <li>Item2</li> <li>Item3</li> <li>Item4</li> <li>Item5</li> <li>Item6</li></ol>
add id to non-dummy elements
✤ Req: Want to include a lot of dummy elems (for preview)
#list { logic: { _stag _element(item) _etag }} Pick up only non-
dummy elems, and dummy elems are removed in the result
55
copyright(c) 2010 kuwata-lab.com all rights reserved.
Extract Element Pattern
<html id="mark:whole"> <body> <form id="form"> <input ... /> <input ... /> <input ... /> </form> </body></html> Add id attr to
document root elem (=<html>)
✤ Req: Want to extract a certain elem form a document
#whole { logic: { _element(form) }}
#DOCUMENT { logic: { _element(form) }}
Replace document by a certain elem
Kwartz provides special id name for this purpose
56
copyright(c) 2010 kuwata-lab.com all rights reserved.
Add-up
✤ Presentation pattern✤ Best practices for presentation layer (data & logic)✤ Select Element Pattern: select only a elemement according to condition
✤ Pick-up Element Pattern: use only necessary element, and remove others
✤ Extract Element Pattern: replace document by a certain element
57
copyright(c) 2010 kuwata-lab.com all rights reserved.
questions?
58
copyright(c) 2010 kuwata-lab.com all rights reserved.
thank you
59