Web Development as Tag Soup

July 20, 2008

As we work with ASP.NET MVC on Stack Overflow, I find myself violently thrust back into the bad old days of tag soup that I remember from my tenure as a classic ASP developer in the late 90's. If you're not careful bordering on manically fastidious in constructing your Views, you'll end up with a giant mish-mash of HTML, Javascript, and server-side code. Classic tag soup; difficult to read, difficult to maintain.

I don't mean tag soup in the sense of badly formed HTML, or the malformed world we live in. I mean tag soup in the sense of mixing HTML markup and server-side code. Now you can double your pleasure: badly formed HTML, meet badly written code.

The tag soup problem seems to be endemic to all modern web development stacks. I see that Ruby on Rails apps have the same problem; here's a slice of representative RHTML from Typo, a Ruby blogging engine.

Ruby RHTML markup and code

Do you find this readable? Can you see where the code begins and the markup ends? Are you confident you could change the code structure without breaking the HTML, or change the HTML structure without breaking the code?

Sometimes editing this stuff makes me feel like I'm playing Operation. I have to ever so carefully maneuver my metal tweezers into one tiny slice of code or HTML and make my changes without touching the edges and setting off that blasted electrical buzzer.

Operation game

I'm not trying to single out Rails or Typo here; I could easily show you a ASP.NET MVC view that's just as confusing (or as "clear", if you think that's perfectly readable, I guess). Tag soup is everywhere; take a look at the Python Django framework templates:

<h1>Archive for {{ year }}</h1>

{% for date in days %}
    {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
    <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
{% endfor %}

Perhaps when it comes to mixing HTML and server-side code, some form of soup is unavoidable, a necessary evil. The soup can be quite palatable; maybe even delicious. It's certainly possible to write good tag soup and bad tag soup.

But I have to wonder: is there a better way? Is there something beyond RHTML, Views, and Templates? What examples would you point to of web development stacks that avoided degenerating into yet more hazardous, difficult to maintain tag soup? Is there anything truly better on the horizon?

Or is this year's newer, fancier, even-more-delicious iteration of tag soup as good as it ever gets for web development?

Posted by Jeff Atwood
267 Comments

The example you have feels a bit like a straw man put forward for your readers to tear apart - its full of logic that could have been elsewhere.

Templates (we are a PHP shop and use Savant) can reduce the issue of tag soup to insignificance if you can avoid the temptation of making them monolithic and full of logic. I think by and large thats been the response by posters above.

A declarative approach can also work - using XSLT is a declarative approach (with the option of some xpath logic).

wioota on July 22, 2008 8:00 AM

@Rob Conery
Unbelievable Rob are you still advocating that sloppy style of coding where you embed tons of code in your presentation view? Rob you're doing it wrong! :-)

o.s. on July 22, 2008 8:36 AM

Getting rid of code-soup is one of the reason I like ASP.net so much... my code doesn't look anything like that monstrosity.

Kris on July 22, 2008 8:58 AM

Vincent,

MVC has been around a lot longer than Rails.

And, within the constraints of MVC, there isn't a lot of room for interpretation.

Obviously, Data Model, View and Controller objects need to be created. And it needs an adapter/router/dispatcher (whatever you want to call it) to connect the web paradigm of URLs to a corresponding controller object.

So yes, it is similar to Rails. But no, it's not a copy per se.

Shane on July 22, 2008 9:03 AM


1 point by mattmcknight 1 minute ago | link | edit | delete

I like using the builder approach in Ruby.

x.html {

x.head

x.body {

for i in 1..5 {

x.div(:id = i) {

yo

...

but my designer likes the templating stuff better. With a good IDE, it does become pretty easy to tell the code from the template.

matt m on July 22, 2008 9:06 AM

Another advantage of having clean HTML code is that it is much easier to go from design mockups to actual templates and back again.

Many people are on the defense here, saying that the example is over the top, and that it would be easy to do much cleaner with a little more discipline/ another 'mvc' framework. That's true in theory, but in my experience in practice if people can take short cuts, they will (at least someone in the team will), so if technology doesn't enforce separating logic from presentation code, many projects will end up with tag soup.

Eelco on July 22, 2008 9:20 AM

Another advantage of having clean HTML code is that it is much easier to go from design mockups to actual templates and back again.

Many people are on the defense here, saying that the example is over the top, and that it would be easy to do much cleaner with a little more discipline/ another 'mvc' framework. That's true in theory, but in my experience in practice if people can take short cuts, they will (at least someone in the team will), so if technology doesn't enforce separating logic from presentation code, many projects will end up with tag soup.

Eelco on July 22, 2008 9:21 AM

Why just not use a framework like the Google web toolkit to avoid all this. Use Java to program a website, and use all the benefits Java has to offer. Let the compiler translate all that good to read and maintainable Java code to web code. Then just use Tomcat to host your site.

This avoids using place your technology here with html all together. Off course there are other methods and frameworks if you don't like Google ;)

Dude on July 22, 2008 9:28 AM

@Shane : for sure, I remember reading about MVC in a visual C++/MFC book back in '98 ! And that wasn't new already ... anyway, porting that paradigm to web applications can take several forms, design decisions, ... and I wouldn't say it's all about coincidences here ;-)

But if I mentioned it, it's more about setting the record straight, when I read microsoft kiddies saying, 'hooray, asp.net'MVC does it better than anyone else with its brand new concepts'. And guess what, the first thing they'll do is producing the very same code Jeff is mentioning in his article, that is, poorly written view code not using all the helpers available in their framework. And people will rant on MVC's tag soup while the problem is between the keyboard and the chair, starting the same cycle again ...

Vincent on July 22, 2008 9:34 AM


I agree. This is a poor strawman. This was 3 minutes of work, having to deal w/ the ___'s, and there's more we could do. I agree. HTML is crap, and it's all messed up, but it can be minimized.

% pages.each { |page|

____class = cycle(first_row,alt_row,)
____page_created_time = page.created_at.strftime('%d %b, %Y)
____link_title = (page.title == '' ? '[Untitled]' : page.title)
____link_url = Site.full_url + '/admin/pages/edit/' + page.id.to_s_______
____truncated_body = truncate(Post.strip_html(page.body), 50)
____delete_url = Site.full_url + '/admin/pages/destroy/' + page.id.to_s
%
____tr class=%= class %
________td class=first_col%= page_created_time %/td
________td%= link_to link_title, link_url %/td
________td%= truncated_body %/td
________td%= page.permalink %_/td
________td class=del_col
____________%= link_to 'X', delete_url,
____________:confirm = You are about to delete this page. This is perrnanent.\n\nAre you ABSOLUTELY sure? %
________/td
____/tr
% } -%

% if pages.length == 0 # This was a needless unless?!?! -%
____tr class=first row
________td class=first_col colspan=S
____________span class=gray
________________There are no pages at this time.
____________/span
________/td
____/tr
% end -%
% if page_pages %
____tr class=header
________th colspan=S
____________div class='pagination
________________div class=prev
____________________%= link_to 'laquo; Previous page',
________________________________{ :sort = params[:sort],
__________________________________:page = page_pages.current.previous }
________________________if page_pages.current.previous %
________________/div
________________div class=next
____________________%= link_to 'Next page raquo;',
________________________________{ :sort = params[:sort],
__________________________________:page = page_pages.current.next }
________________________if page_pages.current.next %
________________/div
____________/div
________/th
____/tr
% end %

Tim on July 22, 2008 10:20 AM

Drupal avoids this very, very well.

Mark on July 22, 2008 10:21 AM

Zope's TAL is the better way - it doesn't invent it's own tags, and doesn't add foreign markup. All template control is done in attributes, so HTML stays lean, readable, syntax highlighting works as usual.

TAL howto:
http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/AppendixC.stx

PHP implementation:
http://phptal.sf.net

TAL on July 22, 2008 10:21 AM

It could be that the real tax of the tag soup is the angle-bracket-tax. The inherant grossness of html makes hybridizing these things difficult.

Long story short I can't see us coming up with a better way of doing the same kinds of things. It helps to have a little of the functionality in with the markup. Keeps the designers aware of what's going on.

Even though you're playing Operation, at least you're not playing blind like you have to with regular asp.net.

Jethro Larson on July 22, 2008 11:20 AM

It is amazing how things stay the same, but with fancier tags.

For large applications, having most markup and javascript emitted from the server is safer. Perhaps the client side markup should just be targets for the emitted code.

steve on July 22, 2008 11:56 AM

I'm just glad you said all that because I, not being the most experienced, have always thought, huh? when it comes to MVC and templating. It always looked like so much mixed up. just because it wasn't server side code didn't make it more readable. You said a necessary evil, and that made me understand I wasn't alone in my thoughts. Thanks.

john on July 22, 2008 12:27 PM

Part of the problem you are having above is that the inline html/javascript is just strings as far as the compiler is concerned. Thus the compiler can't help you confirm that the syntax of the emitted html javascript is correct.

If you follow either the lispers or the smalltalkers (http://www.seaside.st/) you will see they both go in the direction of expressing their html in code, and thus the development environment can help the programmer keep it all straight.

In simple terms, what you have above is two language domains when you should have one.

Brett Morgan on July 22, 2008 1:01 PM

The only solution i see to this problem that is a little different is intermediate representation. Like generating an XML from the server side code and transforming it via a XSLT (But i think that it could apply to any intermediate representation of the data the view need and transformation language).

But i don't really know if it is better, only different.

virtualblackfox on July 22, 2008 1:30 PM

If you have low-level code mixed in with html markup you've already failed, you might as well dump your current technology stack and start over with perl print statements that include html. If your abstraction is that leaky it's probably not worth using at all.

Robin Goodfellow on July 22, 2008 1:53 PM

@Tim,

I simply used UltraEdit to convert my tabs into 4 underscores :)

Stephen Hill on July 23, 2008 2:45 AM

I think the use of left and right angle brackets do no ease the reading of RHTML, its syntax is also way to permissive.

Samori Gorse on July 23, 2008 3:26 AM

The only framework which trully separates HTML from the code is rife:
http://www.rifers.org

The templating engine only support putting/binding values/objects into the template, and appending blocks in a template.

No foreach/if_then_else or anything else.

Temnplate part Example:

table
tr
tdusernumber/td
tdfirstname/td
tdlastname/td
/tr
r:v name=results/
/table

r:bv name=result
tr
tdr:v name=RESULTBEAN:usernumber //td
tdr:v name=RESULTBEAN:firstname //td
tdr:v name=RESULTBEAN:lastname //td
/tr
/r:bv


In the java Code (an Element in rife) I would fetch the data from the DB, and foreach result would do an:
template.setBean(result, RESULTBEAN:);
template.appendBlock(results,result);

r:v name=RESULT:lastname / can also be written as ${v RESULT:lastname /}, somtimes this is clearer.

Huibert Gill on July 23, 2008 3:31 AM

Seaside works on the principles that components know how to draw themselves:

http://www.seaside.st/documentation/subcomponents

There was a very interesting talk/rant on the web recently by a guy who says that modern developers have forgotten some of the core principals of Object Orientated development - such as objects knowing how to render themselves onto a canvas - but I just can't find the link. It might have been by the same guy who claimed Object Orientated programming should have been named Message Orientated programming, to avoid people missing the point.

If you don't have the HTML made for you by a Web Designer (i.e. you have to generate it yourself and let them style it with CSS) then this approach could work:

http://erector.rubyforge.org/

which is based on Markaby.

James on July 23, 2008 4:55 AM

@Huibert Gill : what if you need to add first or odd and even css classes to your table's TR, for example ? I would guess that all that logic has to be in the controller, who does all the loops, conditionals, puts these in variables sent to the templates ... yeah, I've been doing that 8 years ago, and it makes the controller way too dependent on the view. Or you divide even more the processing with a controller for business logic, then a separate template-unroll method, then the template itself ( instead of having that template logic inside the template ). Great if it's working for some people, but while it's quite pure, for sure, such ways of processing templates have been abandoned for a reason ..

Vincent on July 23, 2008 5:45 AM

Why aren't we tired of discussing this problem already? Just use an engine like Haml if you don't actually want to write the HTML itself or want your designers to mess with it.

Use a templating engine like Smarty if you want to write the HTML and are having problems with separating concerns, Smarty will almost force you if you abstain from the {php} tag. Tiny but strong also looks neat even if I don't like the way the assignments are done per default.

A combination is also possible like the one I'm using with Pico Lisp: http://www.prodevtips.com/2008/07/17/templating-in-pico-lisp/

Henrik on July 23, 2008 5:57 AM

@Wayne M

I agree, the business logic should be in the controller. In the view you should have only the rendering logic: just loops, coditional show / hide, etc...

The best way to avoid that kind of tag soup is to balance the logic through the .aspx file and the codebehind file. For instance, if you need to render a table it is easier to concatenate strings in the codebehind and just call a protected method from the .aspx file.

Anyway, the real soup here is the comment soup, what a post reaction!!

Santi on July 23, 2008 8:35 AM

I'm completely confused by this post. Tag soup is not an issue in asp.net. Not just in version 2.0 onwards either. in 1.0 there was absolutely no need to write such confusing and messy code.

This makes me understand the reasoning behind the PHP sucks mentality. Whilst I am not a PHP coder, I have seen code written like the Tag Soup you have shown, I have also seen some extremely neat and easy to understand code.

We write all of our asp.net applications as if they were winforms applications. There is no need to embed the code within the visual layout of the page. You wouldn't be writing script tags like that within the layout of a winforms application, so why do it in a webform?

PHP sucks and ASP.NET sucks. No. Just a lot of PHP and ASP.NET developers only know how to write code that sucks.

Robin

Robin Day on July 23, 2008 9:08 AM

Take a serious look at GWT. I think its the most effective approach for web apps (but maybe not necessarily textual content-heavy sites that need to be indexed like a wiki, blog, or news site). I hate the tag soup too (in my case its JSP/JSTL I have dealt with), hence why I'm using GWT for my web apps.

There are also a lot of misconceptions about GWT leading to invalid criticisms. Take the time to study it before dismissing it.

n on July 23, 2008 10:05 AM

The solution to this is easy:

Use a new pseudo language.

One that is very close the how you think with web apps.

markus on July 23, 2008 12:56 PM

Many posts here claim that ASP.NET 2.0 nicely avoids tag soup. Although Jeff told us Do Not buy This Book (The ASP.NET 2.0 Anthology: 101 Essential Tips, Tricks Hacks, http://www.codinghorror.com/blog/archives/000971.html), I did, and I almost got crazy on pg. 126, where they praise the declarative nature of the GridView control.

What *I* see is an .aspx page, which is usually a HTML page (the soup) containing server side controls (the vegetables in the soup). For beauty's sake, they just printed the controls, but what *I* see is, besides a complicated GridView declaration: a literal SQL query in an asp:SqlDataSource with a special SQL parameter syntax!

What Microsoft sells as declarative programming at least to me looks like a morbid collapse of the database backend (SQL queries) into the the view frontent (the HTML page).

I learnt declarative programming at university with Prolog and layered architecture (database backend, object model, page controller, HTML template views) on the webapp dev job, and I did well with it.

As a variation of http://www.codinghorror.com/blog/archives/001147.html, all what comes into my mind on the ASP.NET 2.0 topic is No, I will not buy into asp:GridViews with asp:SqlDataSources. And no, I DO NOT NEGOTIATE WITH TERRORISTS.

tarnold on July 24, 2008 7:12 AM

The structure will be a lot clearer if you turn word-wrapping off. Then the indenting will not be interrupted with continued lines. Also, it helps to have proper syntax highlighting for the ruby code, instead of making it an orangey smear. Finally, it helps to have a syntax highlighting that mutes the angle brackets.

That said, are you sure this code is from Typo? I cannot find it anywhere there.

Matijs van Zuijlen on July 24, 2008 7:49 AM

You're always going to have server side code in your views... it's all a matter of intelligently writing your controllers to make sure that by the time your view loads it's mostly just variable placement.

I agree with the previous comment... if you find yourself knee deep in tag soup perhaps you should consider breaking your view into more / different pieces and doing your logic in your controller.

Keith on July 24, 2008 8:21 AM

Honestly, the best way AFAIK to avoid tag soup is to forego tags altogether, and produce any HTML programatically, ala Perl's CGI.pm:

http://search.cpan.org/~lds/CGI.pm-3.38/CGI.pm#CREATING_STANDARD_HTML_ELEMENTS:

Evan K on July 24, 2008 8:59 AM

@Tarnold: What Microsoft sells as declarative programming at least to me looks like a morbid collapse of the database backend (SQL queries) into the the view frontent (the HTML page).

All the problems you describe can be completely avoided in ASP.NET:

a) all the attributes in GridView declaration can be moved to codebehind so they no longer clutter-up the markup

b) SqlDataSource can also be moved to codebehind or better yet replaced with ObjectDataSource which is more flexible

What you criticize is some techniques which are best used for explaining programming concepts, for real production code there are better ways. As usually Microsoft gives you lots of choices and you apply it based on specific circumstances. If you do it right you can 100% avoid tag-soup.

Wheelwright on July 24, 2008 10:53 AM

The solution is the same as with normal code:

REFACTOR! :)

With server-side controls like in asp.net you can reduce all the mess into something like this:


HtmlHeadBodyAndAllOtherCrap
HeaderCodingHorror/Header
NavigationBar /
RoundCornerBoxGetBlogPostFromDB id=1/RoundCornerBox
RoundCornerBoxGetBlogPostFromDB id=2 //RoundCornerBox
/HtmlHeadBodyAndAllOtherCrap

Of course you can probably do the same with some custom made template engine.

Crazy Ivan on July 24, 2008 1:15 PM

xml+xslt will kill tag soup.
Unfortunatly there isn't good support to the twins

mithaelin on July 24, 2008 1:49 PM

in the ideal world i am occasionally guilty of slipping into, html is html with no server side influence. all dynamic portions of a page are introduced after the dom is loaded via ajax. everything is perfectly tieed.

unfortunately this ideal can not exist in the wild while users have js turned off and and any sense of commercial responsibility remains. your content must be indexed.

however, with care, a close approximation to this world is possible.

sean g on July 25, 2008 5:55 AM

In the Java world, almost all frameworks are not tag-soupers. Non-XML server-side code mixed to HTML practically doesn't exist on modern Java web development.

Rodrigo on July 25, 2008 7:09 AM

This has always driven me batty. Moreso now that I work primarily in PHP. It gnawed at me with ASP and Rails as well.

The comments: TLDR. I did a quick search for Enhydra-- I've worked extensively with it for years. One match! That guy knows the score. Absolute separation between markup and code was great. Java? Not my favorite codebehind. Ruby or Python would be glorious.

Allowance for both modes is what I'd like to see. Then it's all about balance. Your post on normalization vs. denormalization comes to mind. Salivary glands: Activate!

Chuck Rector on July 25, 2008 7:48 AM

I'm using CakePHP 1.2 now. I cannot begin to explain how good this framework is. You really need to use it to see all of the points where the mundane work and even slightly more difficult work is simply lifted off of your shoulders.

In your view thought you can use any number of the built in helpers to solve this issue. Since they are built in and not homegrown any Cake developer will be right at home with them. http://book.cakephp.org/view/181/built-in-helpers

Most notable are the HTML, Form, and JavaScript helpers. Also extremely helpful is the RSS helper.

Erik on July 25, 2008 9:20 AM

XML + XSLT works so well for this problem that I was naively doing web development for two years before I discovered that this tag soup thing was apparently a problem.

You're still left with the ugliness that is DHTML, but we're not quite ready to start building our web sites in WPF yet, are we?

It is perhaps not a coincidence that a person who finds XML to be useless also finds that tag soup urgently requires our attention.

Bob Rossney on July 25, 2008 10:37 AM

Django example doesn't have any server side code, it's all presentation code. Django uses templates that are not even Python itself, it's a simple markup like PHP's Smarty. No way to compare it with old ASP, or PHP, or embedded Ruby. Get your facts straight.

Henrique on July 27, 2008 2:36 AM

Staged Architectures.

Here you go:

http://st.inf.tu-dresden.de/Lehre/SS07/cbse/pdf/40-staged-architectures.pdf

M on July 27, 2008 9:49 AM

Have any of you checked out Lilu? http://www.infoq.com/news/2007/07/mockup-driven-dev-lilu

It's a templating engine for ruby which lets you leave the html produced by the design/front-end team more or less completely untouched, as pages are created by populate lists, form fields, etc, by using css selectors from within ruby.

Erlend on July 27, 2008 1:20 PM

Lasso is a good choice if your project warrants the expense. The templates you create with it are entirely human readable. Lassos own tags are delimited by square brackets so they stand out between angled brackets of html. Matter of fact it looks a lot like server-side includes - on steroids.

Handles any backend that accepts ODBC connections. Comes with a standalone click-clack template creator. If your database already exists you can point the tool to it and it will populate a drop-down with fieldnames from the database. After that its just drag-n-drop. Once you got the hang of it you can put together entire sites in an afternoon.

Drawback 1: the price BEGINNING at $650 for a basic license.
Drawback 2: The language guide is 850 pages - there are 1500 tags.

If you don't want to buy a license, there are some hosting providers who offer it as part of shared hosting packages, often together with FileMaker. The click-clack tool is a free download from Lassos website.

Bernhard on July 28, 2008 7:19 AM

OK, now I see your background. Enough said.

Good Point on July 30, 2008 5:15 AM

Another vote for Apache Wicket! The templating approach is the only one I've seen so far the really keeps any programming logic out of the HTLM template.

I've worked with Wicket for a few months now - so far the biggest drawback is Java's lack of closures, forcing me to write a lot of ugly anonymous inner classes.

The best thing, apart from the templating itself, is the component model. Writing components and writing applications is achieved with the same programming model, just pair a HTML template with a Java class and add some other components. Composing applications from components or new components from other components works extremely well. A ton better then in JavaServer Faces, where you have two seperate programming models for writing applications (works fine) and writing components (ugly as hell, echo-html all over the place).

Jrn Zaefferer on July 31, 2008 10:40 AM

Since the LISP-cat is out of the box anyway, have a look at Weblocks: http://common-lisp.net/project/cl-weblocks.

It has some very interesting aspects, although very alpha. Try turning of javascript, reload. Now turn of cookies, reload. It just works.

The commonality with GWT is that the HTML is encapsulated, which IMHBCO is certainly the way to go forward.

Guido on August 5, 2008 5:58 AM

Cool!

IVR on August 6, 2008 1:45 PM

Declarative development definitely tackles the soup problem.

However, it also changes the way that we have to approach development. If you take a declarative approach (e.g using Declarative XML) then the developer is only concerned with what the application should do - not how it should do it; in other words the focus is on building the application and NOT on solving technical issues.

So who solves the technical issues? The programmer does this (e.g. using C#) in a programming environment removed from the declarative layer.

In quick conclusion, the reason why soup exists at the moment is that developers are forced to tackle 'development/build' and technical issues on the same page - no wonder it's so difficult!

One person can still carry out both the programmer and developer roles - it's just that declarative development separates them very clearly; solve the build problems in XML, solve the technical problems in C#.

If anyone would like to look at our work give me a shout; we'd love to talk to people who feel passionate about efficient development.

Magnus on August 13, 2008 4:26 AM

Wikipedia templates (those withing Template: namespace) are also as messy (or evil) as the codes you pointed in your post. Actually, I think wikipedia templates' codes are really messy and ugly.

Remember LISP? Tons of parentheses...
Meet wikipedia templates: tons of curly braces!
(mixed with wiki-code and HTML code, with some embedded CSS style rules)

Denilson on August 17, 2008 12:40 PM

I suggest creating Html helpers

Steve` on August 25, 2008 5:45 AM

One of my best experiences with templating engines has to be PHPTAL.

http://phptal.motion-twin.com/

Andre on August 27, 2008 11:25 AM

The StringTemplate library (http://www.stringtemplate.org/about.html) aims to enforce strict model-view separation between model and text (of which HTML is a subset) generation.

StringTemplate (as I understand it) is a 'parser-in-reverse' generator - you specify rules as you would in a parser, but you generate, rather than parse, text with those rules.

Disclaimer: I've never tried StringTemplate, but Terence Parr also wrote the Antlr parser generator, which is splendid! And having seen that there's a Python port of StringTemplate, I may well have a quick go with it...

Stuart Dootson on February 6, 2010 10:38 PM

At a Microsoft Roadshow event I attended earlier this year, the presenters of ASP.NET MVC themselves mentioned that it wasn't for everyone; that half of the room would say what's the point?, and they weren't far off. I was in the undecided crowd, because on the one hand I could see the value in not having everything as a WebControl, but there was a lot to lose in not using the WebForms approach, too.

I guess it's a matter of which aspects of the code you want to focus on. Traditional WebForms deals with each area independently, breaks it all up into manageable chunks and provides the IDE to edit each, whereas MVC, PHP, Rails etc throw you into personally dealing with all aspects yourself. They are all leaky abstractions, and to this end I can only conclude that until the language fully understands the problem, just like LINQ is starting to do with ORM, we can never have the web development grail.

As the Html namespace in MVC and the programmatic-markup approach in dynamic languages go some way to the required solution, I think the ultimate answer is for the language to truly understand your HTML, CSS and scripts. With such a tool, you could implement generic controls in the order you wanted and your markup (and where relevant, CSS) could be auto-generated to match. Yes, we do kind of have this with some templated .NET controls, but not in the sense that the language actually knows what it's doing as it follows commands.

I'm sure it's possible, but jeez if that isn't a formidable project.

Andrew Cameron on February 6, 2010 10:38 PM

I've started to use the nvelocity: http://www.castleproject.org/others/nvelocity/index.html for my MVC views, it's pretty quick to pick up and get working with.

Here is a link to an article explaining how to use it with MVC that i found interesting: http://www.chadmyers.com/Blog/archive/2007/11/28/testing-scottgu-alternate-view-engines-with-asp.net-mvc-nvelocity.aspx

Keith Stenson on February 6, 2010 10:38 PM

I'm a big fan of XSLT to add a further layer of separation. Conversion to XML from an object model is frequently trivial, and XSLT makes proper nesting much more verifiable than ASP/JSP/PHP etc. tag soup.

I really wish a few big players would jump on XSLT2, however, since a slightly simpler-to-use transform stage could really help.

Eamon Nerbonne on February 6, 2010 10:38 PM

Can I read the Typo soup?
Yes. Though, I'm not sure that's good. ;)


A few have mentioned custom tags; one example from VLDR:
item name

By the way...isn't this still tag soup?!
So far, everyone that's celebrated custom tags has had this tone that implied they escaped the soup. No, you didn't.

Personally, I've never understood the advent of custom tags, let alone custom attributes. Don't get me wrong, I understand what they can do. But, I don't need code that's trying to be incognito and hiding from me.

Seriously, code highlighting should not be a requirement to read the code.

Jon L. on February 6, 2010 10:38 PM

item name ?!?!

Ok...well, there was supposed to be more to that.

Try this again...
li tal:repeat=item view/items tal:content=item/nameitem name/li

Jon L. on February 6, 2010 10:38 PM

ASP.Net Webforms!
I know asp.net webforms has its own set of issues (large viewstate, less than optimal html markup, some others...), but I think these things can be improved on. I have been working on a large asp.net web application for a couple of years now and don’t really have a problem with tag soup.

One of my concerns with the asp.net MVC is this very problem of tag soup. The MVC pattern helps to separate your project into a model view controller pattern. Shouldn’t we also be trying to separate the html markup from any code?

Just my two cents.

Douglas Hammon on February 6, 2010 10:38 PM

I know you probably consider your StackOverflow code to be private, but I wish you had just posted your ASP.NET MVC example page with the tag soup in it. The reason is because you've misled everyone into thinking that ASP.NET MVC forces you to write garbage like your example Typo code. And that just isn't true. A well-written ASP.NET MVC view will not have a lot of conditional logic in it, that will be in the controller or the services backing up the controller. The view should really only have some iteration code and variable echoes. You're going a long way to fuel people's misunderstanding and fears about ASP.NET MVC here with this post. But seeing some of your other comments and posts about working with ASP.NET MVC, I think maybe you are in the learning stage and havent figured out how to write a clean view yet. There are other examples out there, you should study them before you spend a lot of effort creating bad code.

Jon on February 6, 2010 10:38 PM

There is another option many have forgotten, ColdFusion. Now in version 8 with Adobe set to release version 9 sometime in 2009. CF has always embraced the tag syntax and yet does allow the traditional script approach if desired. So the tag soup disappears making the markup code within the view layer much easier to read. E.g.

cfloop from=1 to=10 index=i
divdo something..../div
/cfloop

And now there are 2 open source engines for those who stayed away from using it previously due to the cost.

Just some food for thought...

Jason Daiger on February 6, 2010 10:38 PM

I haven't figured out which is worse.

a) The horror of mixing multiple languages into HTML, which already tends to be badly formatted. Emacs (even milti-mode) is horrible at auto-indenting.

b) or, MVC (Model-View-Controller) models which tend to lead to file proliferation. In my currently project, it takes at least 5 files to create a single page: 3 JSPs (using Tiles), 1 servlet, and 1 bean. So, I have to open 5 files just to make certain types of changes to a page.

I can see each having their advantage and place. But, IMHO, neither is ideal.

Carleton on February 6, 2010 10:38 PM

After a quick Ctrl-F through for Flex, I see only three references - I think that the signal to noise ratio (noise presumably being PHP, ASP and any % % stuff [Python Server Pages etc] is low enough for me to have to give Flex a fourth nod. The reason Flex (and similar things like Silverlight) can get around the tag madness is that they don't do HTML, so they define UIs declaratively in a manner much more akin to normal (desktop) application development. Since the page production doesn't consist of a top-to-bottom evaluation (basically a big Main function) you can write proper event-driven code and perform all the user interaction on the client, where it belongs, without having to deal with Javascript browser incompatibilities.

Without wanting to sound too much like a Flex fanboy, I have to say that it's a lot easier to write good code in Flex / Actionscript than it is in ASP/C#, HTML/PHP, or any other server-side framework. Write web services / REST services to deal with the server-side stuff and design a nice event-driven UI for the client. You shouldn't be worrying about transmitting forms over the wire in HTML. Try it, you might like it :)

Eric Greveson on February 6, 2010 10:38 PM

Vote 1 nhaml

Simon on February 6, 2010 10:38 PM

Vincent sees 20 lines of blog and immediately concludes everything should be thrown in the wastebasket, without even wondering if there was more to the point.

Such as mentioning the existence of 'good spaghetti code' and postulating if there IS indeed a better way of doing things. Question (partially) answered I'd say from the reaction/comments received.

Josh Smeaton on February 6, 2010 10:38 PM

I have always liked the seperation using XSLT/XML, but never had a real opportunity to explore it.
However given how verbose xml is and how XSLT never caught on in the main stream, it is a pity!

Rendering engines are the new craze, however it is a new syntax/construct to learn :-(

George Gonsalves on July 19, 2010 10:26 PM

thanks for giving nice instruction in coding related to web and ASp.net
====================
SEO Bolton

Elena Lee9 on July 22, 2011 10:37 PM

«Back

The comments to this entry are closed.