Scott Hanselman

The Weekly Source Code 20 - A Web Framework for Every Language

March 19, '08 Comments [15] Posted in Javascript | PHP | Programming | Ruby | Source Code
Sponsored By


vt102

We just keep oscillating back and forth between thin clients and chubby clients. We started with basic terminals receiving text from the server and displaying it, then added control codes and more smarts until we got into things like VT102 and beyond. We pushed all the User Interface over to the client for rendering.

Now that the Web is squarely here to stay, we've got islands of activeness in the form of browser plugins like Flash and Silverlight, some of which are cross platform and some less-so, but for now my quad-processor machine spends a lot of time either:

  • Waiting for markup to show up
  • Rendering markup

There's a thousand different ways to generate your UIs and send them down to the browser/client for rendering. Turns out there are as many ways as there are languages. If you've got a programming language, there's a web framework for it.

I don't know why this surprises me. Folks love their programming language, whatever it is, and it makes sense that the "ultimate" proof of their language's awesomeness would be the "ultimate web framework."

That said, it still seems funny to me that the greatest (er, most overtly visible) example of a language's superiority is how well it works as a Web Framework angle-bracket generator.

For example, Arc is Paul Graham's new LISP dialect that a number of people are talking about (with varying degrees of enthusiasm).  A tutorial on Arc is available here and there's an "Arc Challenge" being discussed here as folks try to this slightly more complex Hello World example:

"First generate a page with an input field and a submit button. If the user clicks on submit, he gets a second page with a link saying "click here." If he clicks on that, he gets a third page saying "you said: ..." where ... was whatever he put in the input field. This has to happen without the value being passed in the url; it should not be possible to change the behavior of the third page by editing the url in the second."

In Arc/LISP it looks like this:

  (defop said req
    (aform [w/link (pr "you said: " (arg _ "foo"))
             (pr "click here")]
      (input "foo")
      (submit)))

It's pretty terse to look at if you're used to doing things in more conventional languages. There's a lot of fun solutions like this entirely client-side one in JQuery:

$('body').append('<input id = "myInput" /><input type = "submit" />')
    .find('input[@type=submit]').click(function() {
       val = $('#myInput').val();
       $('body').html('<a href = '#'>click here</a>').find('a').click(function() {
          $('body').html('You said: ' + val);
       });
    });

Other examples include:

#!/usr/bin/env ruby
  require "ramaze"
  class MainController < Ramaze::Controller
    def index
      if f = session['foo'] then "you said #{f}"
      elsif session['foo'] = request['foo'] then A("click Here", :href => '/')
      else '<form><input name="foo" /><input type="submit"></form>'
      end
    end
  end
  Ramaze.start :port => 7001
  __END__ 

Then Rails:

def said
    if request.method == :post
      session[:said] = params[:said]
      render :action => "clickhere"
    else
      render :action => "result" if session[:said]
    end
  end

  default template said.rhtml:
  <% form_tag do %><%= text_field_tag "said", "" %><%= submit_tag %><% end %>

  clickhere.rhtml:
  <%= link_to "click here", "" %>
  
  result.rhtml:
  You said <%= session[:said] %>
| something |	
something := self request: 'Say something'.	
self inform: 'Click here'.	
self inform: something
serveAs "said" $ hasIndex $ \x -> "click me" `linksTo` (text ("You said " ++ x))
<%@ Page Language="C#" ClassName="WebApplication1._Default" %>
  <script runat="server">
    // C# and ASP.NET
    protected void SubmitButton_Click(object sender, EventArgs e)
    {
        MultiView1.ActiveViewIndex = 1;
    }
    protected void ClickHereButton_Click(object sender, EventArgs e)
    {
        SaidLabel.Text = string.Concat("You said: ", SayTextBox.Text);
        MultiView1.ActiveViewIndex = 2;
    }
  </script>

  <html>
  <head runat="server">
    <title></title>
  </head>
  <body>
    <form id="form1" runat="server">
      <asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="0">
        <asp:View runat="server">
          <asp:TextBox ID="SayTextBox" runat="server" />
          <asp:Button ID="SubmitButton" runat="server" Text="Submit" OnClick="SubmitButton_Click" />
        </asp:View>
        <asp:View runat="server">
          <asp:LinkButton ID="ClickHereButton" runat="server" Text="Click Here" OnClick="ClickHereButton_Click" />
        </asp:View>
        <asp:View runat="server">
          <asp:Label ID="SaidLabel" runat="server" />
        </asp:View>
      </asp:MultiView>
    </form>
  </body>
  </html>

Shorter but not-typical ASP.NET:

Shorter but non-idiomatic C#/ASP.NET:

    <%@ Page Language="C#" %>
    <html>
    <head>
    <title>Said</title>
    </head>
    <body>
        <form id="form" runat="server">
            <% if (!IsPostBack) { %>
                <input name="foo" />
                <input type="submit" />
            <% } else if (Request.Form["foo"] != null) {
                Session["foo"] = Request.Form["foo"]; %>
                <a href="javascript:form.submit()">click here</a>
            <% } else { %>
                you said: <%=Session["foo"]%>
            <% } %>
        </form>
     </body>
    </html>

There are so many ways to generate the same result. Big thanks to Ted Glaza for his indirect help on this post.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Wednesday, March 19, 2008 10:06:46 PM UTC
I dare you to look at the ARC one, and make some simple but useful similar scriptblock based functions in powershell and then make a powershell solution. Would love to see how it would look beside the above ones. I know for a practical purpose powershell wouldn't do the job in this context because its a different type of framework (and slow) but it is interesting.
Wednesday, March 19, 2008 10:45:45 PM UTC
For Rails I find haml prettier than erb

For example

said.haml:
- form_tag do
= text_field_tag "said", ""
= submit_tag

clickhere.haml:
= link_to "click here", ""

result.haml:
You said
= session[:said]
Thursday, March 20, 2008 8:16:07 AM UTC
Those samples need HTML output encoding, don't encourage bad behaviour!

[)amien
Thursday, March 20, 2008 10:24:21 AM UTC
Dude! You missed Django!

Seriously though, why does the web still draw in such attention? Why is HTML still king? Why not use WF XBAP clients, or Click-Once apps on the web? Should I redo my app in Silverlight or stick to HTML?

I wonder what the advantage of HTML and JavaScript is over Silverlight and Flash. People have already mentioned the SEO problems with Flash, but for applications, that's not usually a big deal.

I think it has more to do with user experience and immediacy. If you alway send down a definition of everything the user will see, format plus data, the page is displayed quickly. If the user has to install something or even wait to download a flash app, it puts them off, and they quickly go elsewhere.

If that is the case, HTML and angle-bracket generators are going to be here for a long, long time still.

Will we ever see XAML-frameworks for generating XAML for Silverlight?
Thursday, March 20, 2008 1:27:17 PM UTC
I'm guessing the Struts version runs to 6000 lines of code :-)
Matt
Thursday, March 20, 2008 2:14:59 PM UTC
> [strike]Web Framework[/strike] angle-bracket generator

that's brilliant scott. best half-line summary of the 'web framework' movement i've ever seen.
Thursday, March 20, 2008 2:38:11 PM UTC
Someone throw up 5 pages to show the EJB 2 version w/ xdoclet templates.
Dave
Thursday, March 20, 2008 2:42:05 PM UTC
CodeIgniter for PHP looks cool, i just saw it today.
Thursday, March 20, 2008 3:52:20 PM UTC
What in the Seaside version defines the url to be said?
Thursday, March 20, 2008 4:25:10 PM UTC
As a Product Manager in Marketing (and part time Rails guy), I can give you a few bits on why markup is still king:

- You are absolutely right on client side runtime issues with Flash, etc. If Silverlight, etc. has to install something, has to install something in different browsers (some people use more than one) and has to install something with each new version, that's just more work for the user.
- Markup-based apps, although they can be done poorly, have inherent consistency within a given browser. Control consistency, some behavioral consistency. Flash-based apps are more open to variance, which hits up against the average user's learning curve. I'm sure this can be minimized or it's over-stated, but it's valuable to consider.
- Markup approaches are open standards. Flash and Silverlight are proprietary to some extent.
- There is a glut of people who can build markup-based web apps (poorly or not) so it's pragmatic from a staffing, retention and turnover standpoint for many organizations.
- View source. Yup. View source. Think about it :-)
Thursday, March 20, 2008 5:03:38 PM UTC
Scott, don't overlook ColdFusion. The basic version would be some inline HTML much your basic ASP.NET example, a nicer written single page would turn out with a combo of that and the rails example, and a nicely frameworked version (depending on your framework) would be along the lines of a 3-10 file program with XML definitions, listeners and a bean factory as options.

ColdFusion gets no love.
Thursday, March 20, 2008 8:06:31 PM UTC
What about Erlang?
Friday, March 21, 2008 4:59:36 AM UTC
Paul Graham - In the Seaside example, there is no URL, just a sequence of "informs" as you move forward in the process. The URL stuff is all under the covers. One of the tenets of Seaside is "we don't use meaningful URLs."
Thursday, April 03, 2008 4:19:00 PM UTC
So nearly 20+ years later, we're back to sending the presentation layer code with the data for each screen refresh?! Talk about advances in technology... or lack thereof. HTML over HTTP was a horrible tangential diversion in "application development". I can't believe we're still putting so much weight into this technology? Oh well, at least Silverlight is on the horizon. Funny thing is we had everything Silverlight 2 has and more back in the original release of the JDK over 10 years ago. I can't help but thinking this is all some big joke played on the software developers.
Eric
Thursday, April 24, 2008 5:40:15 PM UTC
Thanks for the sneaky link. :) Its good to see that people I respect are finding and enjoying the site.
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.