Fluently Construction HTML (ASP.NET MVC)

1 view
Skip to first unread message

Ikhwan Hayat

unread,
Jan 6, 2009, 8:47:40 PM1/6/09
to altn...@googlegroups.com
Assalamu'alaikum,

Biasanya dlm ASP.NET MVC, utk tulis view kita akan buat something mcm ni:

<div class="formcontainer">
<% Html.BeginForm() %>
Your Name : <%= Html.TextBox("Name") %><br />
Your Age: <%= Html.TextBox("Age") %><br />
<%= Html.SubmitButton() %>
<% Html.EndForm() %>
</div>

Aku sebenarnya tak berapa suka campur aduk HTML dgn codes mcm ni,
walaupun cara ni dah diguna sebegitu lama dari zaman ASP, dan masih
digunakan dgn meluas dlm PHP, Rails, etc. Terlalu byk angle brackets
yg mencucuk mata, susah nak baca code dgn noise2 yg byk mcm ni.

Aku suka konsep NHaml
(http://andrewpeters.net/2007/12/19/introducing-nhaml-an-aspnet-mvc-view-engine/)
yg ringkas, tapi tak mahu leceh2 add reference to another view engine.

Inspired by cl-who (http://weitz.de/cl-who/), dan beberapa framework
lain mcm Nitrogen (http://nitrogenproject.com/), aku terfikir utk
buang sama sekali (almost) HTML dan gunakan C# shj utk construct
views. Something like this:

<%
Html.Div(new { @class="formcontainer" }).
Form().
Label("Your Name", "Name").TextBox("Name").
Br().
Label("Your Age", "Name").TextBox("Age").
Br().
SubmitButton().
%>

Nice huh? Ada idea mcm mana nak buat? Rasanya tak susah sgt, maybe
boleh extend a class dari HtmlHelper (atau copy code buat class lain,
source is opened).

Kelebihannya
- Code yg lebih bersih
- Kita stay in C#, malahan boleh tulis code ni dlm controller instead of view
- Probably tak perlukan new view engine, ini guna ASP.NET view engine yg biasa
- Less mental hurdle utk create widget (webcontrol) sendiri. Maybe mcm
eg Label("D.O.B", "Dob").Calendar("Dob", new {
dateFormat="dd/MM/yyyy", autoSelectToday=false });
- Aku expect code ni akan nampak lebih cantik dlm F#, atau dlm C# 4.0
sbb ada named parameter.

ryzam

unread,
Jan 6, 2009, 9:08:10 PM1/6/09
to ALTNETMY
Aku rase the first thing kau kena browse NHaml source code repository
atau tgk kat sini

http://www.singingeels.com/Articles/Creating_a_Custom_View_Engine_in_ASPNET_MVC.aspx

Ikhwan Hayat

unread,
Jan 6, 2009, 9:19:36 PM1/6/09
to altn...@googlegroups.com
Masalahnya kita bukan nak create view engine yg baru. Sbb view engine
ialah mcm templating system, tapi ini bukan.

Kita nak something yg mcm HtmlHelper, tapi fluent. Aku suspect
masalahnya kat sini ialah mcm mana nak simpan generated html tu,
probably kena ada stack, sbb kita kena track start tags dgn its
matching end tags, eg:

Div().
Form().
Label("A label", "SomeControl").TextBox("SomeControl");

Mcm mana kita nak tahu bila nak tutup form tu dgn </form>.

Cara lebih mudah ialah kita boleh buat someting mcm ni (tapi kurang cantik):

Div().Inner(
Form().Inner(
Label("A label", "SomeControl").TextBox("SomeControl")
)
)

Aku rasa benda2 ni dah ada somewhere dlm Xml punya namespace, tapi tak
research lagi.


2009/1/7 ryzam <irwa...@gmail.com>:

Ikhwan Hayat

unread,
Jan 6, 2009, 9:30:11 PM1/6/09
to altn...@googlegroups.com
Ack. Subject should read "Fluently Constructing HTML", not "Fluently
Construction HTML"

Noticing a lot of typo in my writing lately :P

Ikhwan Hayat

unread,
Jan 7, 2009, 7:12:27 AM1/7/09
to altn...@googlegroups.com
Okay, I got something working.

Target output yg dimahukan ialah

<table border="1">
<tr>
<td style="font-weight:bold">Name</td>
<td><input id="txtName" type="text" /></td>
</tr>
<tr>
<td style="font-weight:bold">Age</td>
<td><input id="txtAge" type="text" /></td>
</tr>
</table>

Cara ASP.NET MVC biasa ialah

<table border="1">
<tr>
<td style="font-weight:bold">Name</td>
<td><%= Html.TextBox("txtName") %></td>
</tr>
<tr>
<td style="font-weight:bold">Age</td>
<td><%= Html.TextBox("txtAge") %></td>
</tr>
</table>

Guna cara yg aku buat ni, aku panggil HtmlFlow (ikut style name HtmlHelper)

<%= Html.BeginFlow()
.Table(new { border = "1" }).Push()
.Tr().Push()
.Td("Name", new { style = "font-weight:bold" })
.Td().Push()
.TextBox("txtName")
.Pop()
.Pop()
.Tr().Push()
.Td("Age", new { style = "font-weight:bold" })
.Td().Push()
.TextBox("txtAge")
.Pop()
.Pop()
.Pop()
%>

BURUK GILER! Haha. Tak tau lah... Nampak tak lawa sbb ada Push() and
Pop() sbg indicator kat mana inner HTML bermula/berakhir supaya dia
tak directly close tags. Cuba kalau buang:

<%= Html.BeginFlow()
.Table(new { border = "1" })
.Tr()
.Td("Name", new { style = "font-weight:bold" })
.Td()
.TextBox("txtName")
.Tr()
.Td("Age", new { style = "font-weight:bold" })
.Td()
.TextBox("txtAge")
%>

Looks a bit better :P Tapi tak tahu mcm mana nak buat.. Kalau boleh
nak override operators, tapi takde operators yg sesuai. Something like

<%= Html.BeginFlow()
.Table(new { border = "1" }) <
.Tr() <
.Td("Name", new { style = "font-weight:bold" })
.Td() < .TextBox("txtName") >
>
.Tr() <
.Td("Age", new { style = "font-weight:bold" })
.Td() < .TextBox("txtAge") >
>
>

%>

Kat sini operator "<" dan ">" dah dioverride sbg Push() dan Pop().
Tapi tak dapat la buat mcm ni.

C# is sooo not suitable for making DSL.

Khairul

unread,
Jan 7, 2009, 9:01:13 PM1/7/09
to ALTNETMY
I have gone through this stage before, selalu aku buat website/apps
aku tengok, "Woah, code ni tak clean", pastu cuba nak buat helper/
abstraction untuk generate form, etc supaya memudahkan kerja (DRY).
Akan tetapi kembali juga ke pangkal jalan akhirnya.

Memanglah code mcm ni tak nampak clean (form ni pun tak berapa
flexible sebab takde container untuk setiap element).

<div class="formcontainer">
<% Html.BeginForm() %>
Your Name : <%= Html.TextBox("Name") %><br />
Your Age: <%= Html.TextBox("Age") %><br />
<%= Html.SubmitButton() %>
<% Html.EndForm() %>
</div>

Tapi ia memberikan kita flexibility yang kita perlukan untuk buat
sesuatu form. Selalunya dibuat begini.

<div class="formcontainer">
<% Html.BeginForm() %>
<div><label for="name">Your Name:</label> <%= Html.TextBox("Name")
%></div>
<div><label for="age">Your Age:</label><%= Html.TextBox("Age") %></
div>
<div><%= Html.SubmitButton() %></div>
<% Html.EndForm() %>
</div>

Senang nak tambah tag tag lain, javascript effects/functions, ajax,
etc.

Maybe you like the code to be clean, with all the DRY stuffs in the
concept, etc. But the practicality is not there.

Ikhwan Hayat

unread,
Jan 8, 2009, 12:50:41 AM1/8/09
to ALTNETMY
"Clean" apa yg dimaksudkan kat sini? Bukan cakap "clean design" skrg,
tapi tentang "clean syntax", sorry sbb maybe aku tak sebut dgn jelas
dlm post yg first.

UI yg menggunakan widgets/components/controls (dlm contoh kat atas,
Html.TextBox(), albeit a very simple one) is a nice concept, you can
get a higher abstraction rather than doing the <input type="text" />
all the time. Tapi usually kita kena campur adukkan HTML markup dgn
server-side code, usage of <% ... %> or <? ... ?>

Ada org create new language, a template language, a DSL which outputs
to HTML markup, mcm HAML http://haml.hamptoncatlin.com/ dan lain
template language yg lain. Sangat menarik sbb we dont have to deal
with the angle brackets. Tapi this introduce a new learning curve, a
new language to learn.

What if we can create a DSL (or lebih kurang la) with the language
that we already knew. So mcm dlm contoh ni, nak cuba cara utk dptkan
DSL ni in C#. Which at this point, nampak mcm lagi terabur je :P

Konsep mcm balik semua ke zaman dulu, instead of parsing a template
mcm cara sekarang ni, kita "hard code" the HTML dari server-side code
(kalau interpreted language, takde masalah sbb interpreted on the
fly).

Tapi instead of hard coding HTML mcm biasa Response.WriteLine("<input
type=\"text\" id="theid" />"), kita gunakan function TextBox("theid"),
dan dlm contoh code kat atas, nak gunakan cara "fluent interface"
supaya code tu nampak natural.

As comparisons, mari tgk contoh dari Nitrogen Project, which use
Erlang tuples to contruct the view
http://github.com/rklophaus/nitrogen/tree/master/Quickstart/src/samples/web_samples.erl
http://nitrogenproject.com/web/samples/viewsource?module=web_samples_simplecontrols

Or cl-who, which allow you to stay in Lisp.
http://weitz.de/cl-who/#example

Lisp has flexible syntax, sbb tu jadi mudah. Erlang got tuples, tu yg
dia guna dlm Nitrogen. That's why I said earlier, F# might be better
than C# sbb syntax dia pun lebih flexible dan ada tuple jugak.

Ikhwan Hayat

unread,
Jan 8, 2009, 11:16:52 PM1/8/09
to ALTNETMY
Anybody interested, code is here
http://code.google.com/p/ikhwanhayat/source/browse/misc/HtmlFlow.cs

Very crude and experimental tho :P

Reply all
Reply to author
Forward
0 new messages