Hacker News new | past | comments | ask | show | jobs | submit login

But I have to wonder: is there a better way?

The answer is a language that can use a unified syntax for both generating markup and server-side functionality at the same time. There's probably only one candidate at the moment, and that's Lisp with a special set of macros that translate to HTML tags on output. The beauty of it is that S-expressions nicely map to markup and can execute stuff on the server. This macro library does exist and I think I saw it here at YCnews. It was a video and unfortunately I can't find it now.

There's one bit missing in this solution though: the client side. Can Lisp be translated to JavaScript? Something suggests that's perfectly possible.




Lisp is hardly the only answer. Smalltalk does this just fine in the Seaside framework, which threw out templates to get rid of this exact mess. We write our html, server side code, and client side ajax code pretty much entirely in Smalltalk.

    renderContentOn: html
        50 timesRepeat: 
            [ html div 
                class: #SomeStyle; 
                onClick: (html element hide);
                with: 'Who needs HTML?' ]


What I don't like about this approach is that it forces me to learn a new language just to create HTML. I don't mean Smalltalk, but the specific "HTML generation API".

I have to know HTML anyway (because eventually I will have to debug it), so it seems preferable to me to also code the output in HTML.

Another approach against tag soup I have seen is xmlc, which manipulates the DOM tree of the HTML template. The xmlc project doesn't seem to be very active anymore, though.


Every web framework uses some sort of template engine. You're going to need to know the way it works and what syntax it uses and any gotchas that are there.

Also, the logic is going to bleed over into the HTML anyway. Why burden yourself with ugly line noise?

    renderContentOn: html
        50 timesRepeat: 
            [ html div 
                class: #SomeStyle; 
                onClick: (html element hide);
                with: 'Who needs HTML?' ]
vs.

    <% for x in range(50) %>
        <div class="SomeStyle"
             onclick="javascript:hide(this);">
            Who needs HTML?
        </div>
    <% endfor %>
In the above example, I'm mixing the JavaScript with the HTML and I also see Python code (the last template engines I've used were Python-based). Three languages mixed into one template.

The Seaside/Smalltalk example, on the other hand, has one language with code that generates another language (which I don't have to touch at all, it knows how to generate a valid DIV element). So I just have to analyze the logic of the Smalltalk code and not the HTML or JavaScript unless there is a specific reason for me to do so (such as adding a new type of HTML element).


Just curious: how is xmlc not an extra "HTML generation API" that you have to learn?

I mean, it seems we're stuck here. Either we use tag soup templates, or we use some abstraction to express the structure of the page in the language of the generator code. The former requires less training and discipline, but complicates maintenance. The latter is a framework to which you'll need to adhere. No free lunch.


You have a point. I guess whatever you do, you need something to output HTML, and something to code logic. What I like about xmlc is that it stays within the standards. DOM is maybe too much to know for HTML developers, but still. It actually worked quite well to have "designers" create HTML templates and manipulate them in the servlet. The designer doesn't need to know anything but HTML, except that he has to use id tags where values in the template have to be manipulated.

Overall, I guess web development is always ugly :-(


The obvious alternatives to string templates are:

- embedding client-side markup as a DSL in the language to generate HTML (Markaby/Seaside)

- component/control-based systems (ASP.NET, JSF I guess)

I prefer the first.


Seaside also has components. But they aren't as brain-dead as the ones in ASP.NET. It's much cleaner and better-designed (I haven't dug into Seaside completely yet, but so far, very clean)


I think Hacker News is using the component/control-based approach with Arc? Just curious.


I thought it was macro-based HTML generation, which is typical of Lisp web libraries.


macro-based alone doesn't imply one approach or the other, or does it? There could be macros for all the HTML tags (table => <table>), or there could be macros for "widgets".


Right, IIRC UCW is (was?) using both components with either html templates or html generation.


But I have to wonder: is there a better way?

And 20 years from now, when Microsoft releases an ASP.NET with the better way ("say goodbye to templates with the new Unity Code Components (UCC)™"), Atwood will be blogging about it.

Edit: Jeff is no doubt a nice guy and it's clear he means well. Yet every time I read his stuff I feel driven to burst out with sarcasm. I think it's an allergic reaction: I know the world he represents, I spent too much time in it for my own good, and now I'm hypersensitive.


What world does he represent?


The adhere-closely-to-the-middle-of-the-road developer world. With a bias toward the population whose brains were shaped by Microsoft.


Can Lisp be translated to JavaScript?

Check out ParenScript (http://common-lisp.net/project/parenscript/).


Another option: get a language where markup itself is first-class syntax. JavaScript with E4X has XML built-in, which of course means XHTML if you like, which itself can be trivially translated to HTML if you prefer (as I do).

So just like regular expressions have first-class syntax, i.e., in JavaScript you can write either of:

  myRx = /somePattern/g;
  myRx = new RegExp('somePattern','g');
So with E4X you can write either of:

  greeting = <b>Hello, {user.name}!</b>;
  greeting = new XML("<b>Hello, "+user.name+"!</b>");
Though those really aren't equivalent since the second might be a XSS vulnerability, whereas the first is automatically escaped.

E4X only works in Mozilla-based browsers, but it also works just fine in Rhino, so you can use it in Helma (http://helma.org/) or any of the other Rhino-based frameworks or in Jaxer (http://aptana.com/jaxer).


F# and the WebDevelopment toolkit offers one language (OCaml) that can be used both client and server-side, including continuations and such across the client-server boundary. The OCaml code translates seamlessly into JavaScript.


Mixing HTML-generation and logic, no matter how nicely the languages mesh together, is still a mess. This is coming from someone who's done a few sizeable Common Lisp projects using tools like YACLML and CL-WHO, and then went back to using separate templates for HTML-generation. I'm not sure what Atwood is going on about in this article (probably he just felt he needed to write something, anything) -- separating out views/templates is not really much of a challange in my experience.


The code will not really be simpler just because you turn the pointy brackets into round parentheses. It would be made simpler however, by separating concerns: abstracting presentational and styling info from data. You can do that in any framework.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: