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.
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.
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?
Toss in another vote for wicket. It's seriously by far one of the best, if not the best framework I've worked with. There is no tag soup, your logic peanut butter doesn't get into your html chocolate, and everything is nice. No, seriously. Go try it now.
Luke on July 21, 2008 2:12 AMOuch, Dave... this reminds me of one of your classics You can write VB in any language
Now you are not taking your own advice... tag soup is completely avoidable in ASP.Net... but it's also accessible. Your choice.
Jasmine on July 21, 2008 2:17 AMFor those concerned about MVC replacing Web Forms...
http://www.misfitgeek.com/Will+ASPNET+MVC+Be+The+Main+Web+UI+Platform+For+ASPNET.aspx
If I'm served tag soup as a starter, I would expect the main course to be spaghetti code.
(And by main course I mean the rest of the application)
But done well, a nice template language beats WebForm's runat=server all the way.
I don't think Jeff understands webforms ASP.NET paradigm, if he did he would have noticed that it is the ONLY web framework which managed to completely eliminate tag soup. And it is actually old news because Microsoft did it in 2002 with the first release of ASP.NET.
All those pieces have to be present to get rid of tag soup:
a) codebehind
b) html/server/web controls (for abstracting html and referencing/changing it in codebehind)
c) event-driven page-rendering pipeline
Ruby Envy my ass.
The code is for the machine, not for the person. As always, there is an uneasy balance between readability, scalability, performance, and well-formedness.
Mattkins on July 21, 2008 2:41 AMPersonally I think using a custom-tag based approach to develop reusable components a la JSP taglibs, faces and ASP.Net controls... You convert something like this:
lt;tablegt;
{for (Row row : rows) }
lt;trgt;
lt;td%gt;{row.value1}lt;/tdgt;
lt;/trgt;
{endfor}
lt;/tablegt;
Into something like this:
lt;grid col=rowsgt;
lt;col field=value1gt;Value1 Headerlt;/colgt;
lt;/gridgt;
It really simplifies things and it centralizes a lot of the html (esp. if you use things like JSP-based taglibs written as JSPs--very easy to modify).
Having the ability to introduce macros (which is essentially what sorts of controls are) can really clean up the UI code. And if you've got a halfway decent web guy it's also something they can be comfortable working with using their familiar toolset.
Sam on July 21, 2008 2:42 AMI think if you want to do this properly, you will end up at parts of compiler construction. If you really want to get rid of some tag-soup-stuff, you basically need a code generator with HTML (or XHTML) being the target language.
That basically implies that you define yourself a certain intermediate language. This language definately depends on your application, but in general, it ends up being some sort of sequence of lists of trees (and all that recursively).
This page would probably be a sequence of a blog entry (which consists of a list of paragraphs, which consists of marked up words, and so on)m a list of comments (which consist of paragraphs, and so in) and a way to input data.
I am not entirely sure how abstract you can get, and how abstract you want to get.
This abstract representation is generated by some database layer and passed to a code generator.
This codegenerator then just works like assembly generators or similar things. At first, it has to output a certain prelude, that is, CSS, the header of the page, news, blogroll, CSS, Javascript and all this nonsense. After this, it generates the proper HTML for the text, the comments, and generates a form for user inputs. AFter that, a certain exit code must be generated, in this case, it would be the body end, html end-tags.
That way, the abstraction from HTML would be as large as possible - it would be no problem to generate plain text, or even a certain UI-application.
I just think the problem with such a model is that its pretty much different from what most people think if they build web applications. Most say I pull this statistical data from a database and generate that and that code in order to output, instead of Right, I need a certain HTML-Generator that translates an abstract tree into HTML, and then, I need something that turns my relational data into such an abstract tree in order to output things. Oh well, its like that all the time if you apply compiler-internal ideas to other problems, even though the solution looks nice currently.
Greetings, Hk
Hk on July 21, 2008 2:53 AMI currently work, as a designer, for a large e-commerce site in the UK, and they don't use a template system like this. All the html is coded in functions within the web application.
The result of this is that the HTML and css is coded, by the design team, separate from the main application. This is then passed to the development team who must then rip it apart and stick it all in functions.
Not only is this wasted effort, the developers often get it wrong and break the html structure. Which then has to be ran past the design team again to figure out what the problem is.
Another problem is that if there is not development resource, then there can be no changes to the sites html. This means you can't get your design team to freely change the interface, as you require.
Not good. Templates are a much better solution for large sites, where you are likely to need a design team.
dbuttar on July 21, 2008 3:13 AMI hate even more frameworks that make you pretend you're writing a desktop GUI app and then generate a lot of convoluted and malformed HTML full of Javascript that happens to look like what you wanted.
Everything under my domain name passes validator.w3.org. With the exception of some extensions from the Web Forms 2.0 spec, which no browser supports anyway (but I want to avoid chicken-n-egg: browsers not supporting it because websites don't use it; I take the first step).
Nicolas on July 21, 2008 3:16 AMI only saw one reference to Flex, and no mention of Silverlight, but
I believe our only hope is that these next generation technologies
can free us from the chains of our real enemy, the browser
environment itself!
I will third Flex. Haven't used Silverlight yet, but the promise seems the same.
I only found web programming platible once I could approach it like regular app development, with regular compiler and debugging support.
No tags at all, and one develops a distinct app that happens to run in the browser and communicate with the server -- a nice clean separation that is easy to program with.
Now whether the user likes it that much is another thing, depends on the app really.
Ray on July 21, 2008 3:21 AMI've always found it ass-backwards to have the code embedded in the HTML instead of the other way around. I can write a readable program that emits HTML.
---scott
I usually don't use code like that.
In PHP (Jeff, I know you hate that :-) I usually write a block of code at the beginning of the file, and then I set up some variables to print in the page template, just like this:
?php
$title = getTitle();
?
html
head
title?=$title?/title
/head
body
...
/body
/html
You chose a very bad example for python. Python supports templates by default. I tried them using pylons, you have simply to create a template like this:
html
head
title$title/title
/head
body
...
/body
/html
As you have the model, the controller and the view separated (MVC), when you call a template you can replace the variables on the fly:
t = getTitle()
render('/template.mako', title=t)
Things are very separated here, aren't they?
Andrea on July 21, 2008 3:31 AMWell, I guess that's the price you pay for jumping on the MVC bandwagon... You could have avoided that by using the out of the box, event driven ASP.Net.
But then this post would probably be a rant about viewstate or unreadable/non-css compliant id attributes.
Rob on July 21, 2008 3:31 AMIt always surprise me how some can call their solution the right solution for web development.
Some people argue that too much logic is in the code that Jeff posted above. But have you actually read the code? It shows page number, empty list text, etc. That is not logic, that is just user interaction and usability. Try writing the same code with asp.net form controls without using GridView, ListView, etc. For me logic is the Create Product and the Calculate Income methods.
ASP.Net is great, but ASP.Net forms is just terrible for anything but microsoft only standard asp.net forms. You tend to worry more about page cycle, viewstate, etc. then the actual pages.
anyway I would probably for the sport implement my own template system if that I could find did not satisfy me. A framwork does not have to be brain surgery.
Peter Palludan on July 21, 2008 3:33 AMI third the Haml recommendation. Jeff - try Haml (NHaml, in your case: http://andrewpeters.net/category/nhaml/) . Just write a single page and see what you think. The syntax weirds people out at first but once you've tried it, it is hard to go back.
Casey on July 21, 2008 3:40 AMHere, briefly, are the basic options in ASP.NET. (only looking at inline versus server controls and code-behind)
I never minded the inline for the output of simple values that are only for viewing. e.g. label controls and viewstate are overkill. It makes easy stuff quite easy to read what the layout is with
h1%= _movie.Title %/h1
h3%= _movie.Director %/h3
span class=description%= _movie.Spoiler %/span
and alternative can be, when databound (asp.net)
h1%# Eval(Title); %/h1
h3%# Eval(Director); %/h3
span class=description%# Eval(Spoiler); %/span
or another alternative is to use server controls when you need more control and keep the markup readable.
h1asp:Label id=lblTitle runat=server //h1
h3asp:Label id=lblDirector runat=server //h3
asp:Label id=lblSpoiler runat=server CssClass=description /
in the 'code behind' file, at some point in the page life-cycle, you'd write....
lblTitle.Text = movie.Title;
lblDirector.Text = movie.Director;
if( string.IsNullOrEmpty(movie.Spoiler) )
{ lblSpoiler.CssClass=missing; lblSpoiler.Text = Resources(MissingSpoilerText); }
else
{ lblSpoiler.Text = movie.Spoiler; }
The reason for the inline styles is allowing for non-coders to change the markup without knowing the code. Obviously this can go too far when there's too much tweaking that needs to be done, but the idea is flexibility. Personally I don't dig Eval, because it's always better to catch errors at compile time, but sometimes easy works just fine. Not every page will get your undivided attention, and it does have the utility of showing what is being used.
The other benefit of inline styles in ASP.NET is (usually) you can alter the output on a live system. If you do everything code-behind then you have to recompile and redeploy. [I say 'usually' because in Web Deployment Projects you can specify that pages are not updatable at runtime]
The problem is that real websites, with real logic, get messy quickly no matter where the logic goes. But when things get messy, it's easier to refactor in code than it is to refactor in html.
%# (Eval(Prop) != null ? (Eval(Prop)) : Resources(PropNotFound); %
One thing in ASP.NET that I still find a bit persnickety is single and double quotes inside inline tags, and obviously this following is quite hard to read. I can't remember examples offhand, but there are still times inlining fails inside of some tags, but not others.
a href='%# Eval(Url) %' title='%# Eval(Title) %'%# Eval(Name) %/a -- watch ' versus !
At least MS, to their benefit, does allow flexibility. You don't always have to do it the same way, which is very handy. You can embed the name of events in the aspx file, but you don't have to (you can attach the delegate at runtime). You can just make a normal tag runat=server and then it becomes a member of the page. It can be a source of errors and frustration (knowing exactly where something is done) but that's an issue of DRY and following good coding practices.
Sometimes I curst that it's harder to write some forms of javascript because all the control names are mangled (based on the container they live in), but I get over it.
hombre on July 21, 2008 3:43 AM@Wheelwright: I don't think Jeff understands webforms ASP.NET paradigm, if he did he would have noticed that it is the ONLY web framework which managed to completely eliminate tag soup.
ASP.NET not only isn't the only framework that can avoid tag soup, the example provided shows that it didn't eliminate it; it made it possible to avoid (mostly). Many of the current books on ASP.NET still show tag soup examples.
@mj1531: WebObjects (which inspired Tapestry) solved the server-side tag soup problem ...
WebObjects is an incredible web application framework, with a thriving community. It does eliminate tag soup. And it does so many things so well. Thanks for bringing it up.
But regarding tag soup in general. ASP.NET has the tools to avoid tag soup in most cases. There are a few instances where dropping code into HTML would be hard to avoid, but it's definitely the exception, not the rule.
So, if you find yourself doing tag soup, realize that you're probably doing yourself more harm than good. Sometimes going back and refactoring to avoid tag soup is harder than doing it right in the first place.
Even languages that seem to promote tag soup, such as PHP, can avoid the mess if good decisions are made up front.
John B. on July 21, 2008 3:51 AMCoding horror cliff notes 2008-07-20:
Look, there is a problem. I don't know the solution, do you?
James A. on July 21, 2008 3:53 AMHere's the solution: learn HTML and quit relying on frameworks to do something that you can't do yourself. http://agilology.blogspot.com/2008/07/tag-soup-sucks-hey-jeff-heres-better.html
Jeff Tucker on July 21, 2008 4:04 AMThere's another scripting language that I've found that Falcon (http://www.falconpl.org/) to be interesting. I haven't gotten to use it yet (other things are getting in the way :/ ), but the site uses Falcon and you you can see the source of any page. I think it's very clean. Of course, anything can be made ugly, so it still has to be done right.
MathStuf on July 21, 2008 4:26 AMA number of people mentioned XSLT. We have used it quite well for a number of years with some large clients. I try to make a small case for it in Views here:
http://www.onenaught.com/posts/8/xslt-in-server-side-web-frameworks
In short, it is not for everyone, but it can be very useful and encourages good application design.
A couple of comments also talked about how verbose XSLT is. Some of the example above were quite verbose themselves and can be a lot shorter making the XSLT far easier to read (e.g. instead of xsl:attribute, just write the attribute itself and use curly brace short hands, e.g. div class={$someVariableName}.
What is nice about the XSLT approach is that you can create a master-template/nested master template kind of thing as well, letting you reuse templates even more.
Anup on July 21, 2008 4:35 AMYou're right in that the main example presented is pretty horrible. The syntax coloring makes it somewhat more readable, but you obviously don't want to rely on that.
I mostly do Django when it comes to web development, which several people have already mentioned as generally having a clean template language. A nice feature of it is the ability to extend templates and override some or all of the various sections.
For example, a sub-template might have:
{% extends base_generic.html %}
{% block title %}{{ section.title }}{% endblock %}
...
Whereas the base_generic.html template would have:
...
head
title{% block title %}Default title text{% endblock %}/title
...
This allows you to at least break up and abstract the tag soup slightly.
Eugene Kogan on July 21, 2008 4:54 AMThis isn't just an HTML problem... this is also a code generation problem in general. I've been working on an open source project called NBusiness (http://www.codeplex.com/NBusiness) and it is a DSL that uses templates to generate code for you. The templates I am making by default will use NVelocity (http://nvelocity.sourceforge.net/) to generate code for you and it suffers from the exact same problem (perhaps worse because you can't really make controls).
The other obvious option is to generate all of your code using the CodeDom which sucks so bad it makes tag soup seem wonderful.
Honestly, I think this only becomes a preferable solution when you NEED to control your output precisely. I mean, yes tag soup in ASP MVC is painful but so is designing CSS that is compatible with the crap HTML output of most of the default ASP controls... so it becomes preferable only when you need to control your HTML output.
I think the statelessness of the web really plays a part into the difficulty of generating HTML too.
Justin Chase on July 21, 2008 4:55 AMI'm surprised you're reporting this issue. I honestly am. I actually thought this is one of the problems reasonably solved pretty much everywhere by now. At least my daily work perception is that way.
I've searched through the responses on your blog entry for Zope and found a couple of references (some of them wrong, some of them enthusiastic but not directly on the point).
I'm a core developer and 'user' of the Zope framework and 'we' usually have the perception issue that we're solving problems that no-one has or providing tools for complexity levels nobody goes to.
We've had a technology call (Zope) Page Templates since about 2003 which allows to create pull templates by:
- Annotating the HTML/XML with attributes and tags from a separate namespace
- Have a parser/interpreter for those attributes that modifies the DOM of the HTML/XML
- Serializes it back.
Here's an example:
p tal:content=string:foo/
li
ul tal:repeat=x python:[1,2,3]
tal:content=x /
/li
The language is probably turing complete (although that's not its purpose) and allows for more complexity than is usually wanted.
The expressions are written in TALES, the Template Attribute Language Expression Syntax which allow simple statements of various
(registerable) types.
Within the expressions, a few top level variables can be defined. Ususally those correspond to your application's current model and/or view class.
Using view classes you typically avoid putting complex Python code into the template but reduce the attribute expressions to shorter attribute/function lookups:
dl
ddUser name/dd
dt tal:content=view/current_user/
/dl
This has been the standard of my work environment for about 5 years now.
Christian on July 21, 2008 5:04 AMShouldn't tag soup in MVC be less of a problem/excusable because we have server side controls ?
In ASP.NET Forms there is still the possibility of making up a batch of tag soup but we don't because we use controls.
Or am I missing something important about MVC here?
Kev on July 21, 2008 5:14 AMI think there are two answers here:
1) Write better markup. In the typo example you could move lots of that code to a model or helper, especially the URL concats, date format, etc. If you move all that to the model it is much more readable.
2) Get rid of the HTML part. I love a simple markup technology called HAML. It started on Ruby but there is a NHaml as well. Here is an example from my MVC app using HAML:
#roomdetails
-foreach(Model.Vip vip in room.Vips)
#roomdetail
%a{href=vip.Url,class=borderit}
%img{src=Network.Current.StaticPublisherAddress + vip.Image, class=left}
.viptitle
%a{href=vip.Url}
= vip.Title
.vipdesc
= vip.Bio
.clearleft
HAML has to be indented correctly btw, the spaces/tabs were removed from my comment though, you can see it properly here:
http://infozerk.com/averyblog/new-lounge-front-end-now-with-asp-net-mvc-and-nhaml/
James Avery on July 21, 2008 5:27 AMpersonally, I'm a PHP developer when it comes to webstuff and my (terrible) solution to this problem is to write a pure block of PHP code which outputs the page without using the (convenient) functionality of writing HTML with PHP interspersed. It makes the HTML harder to read in the PHP code file, but all I need to do is view the page source with a browser or other tool once the page is up if I need to see the HTML. I generally insert tabs and new lines to help this... although I will admit I am a bit lazy as doing a view source on the pages on my website will reveal.
So from my perspective, tag soup is a problem the developer makes for himself... at least for PHP. I'd actually need to know something about ASP to comment on it though....
jheriko on July 21, 2008 5:29 AMI've been working on an internal web application for a client for some time now in php.
I've found the easiest way to remove tag soup is write each page entirely in php, using functions like:
property(one, Email, element_input_text(email, $inspector-email))
This function returns all the html tags required to display a nice input for entering an inspector's email address.
I string all these functions inside functions together inside the function template(), which creates all the html for the basic framework of each page (title, breadcrumbs, menus, header, footer, and buttons).
I indent these functions in much the same way as I use to indent html so it's easy to see how deep in the html I am.
No tag soup and parenthesis matching in my IDE ensures I don't leave out close tags.
This is one place I think shows a great strength of using an MVC pattern. If you put your data in a presentation model, you can put most of your view logic in there, then (using ASP.NET MVC syntax here) the only thing you have in your HTML is %= ViewData.Model.SomeProperty % and perhaps an if using a boolean property of the model or a loop using an IEnumerableT property of the model.
John Meyer on July 21, 2008 5:30 AMI don't think mixing HTML and server code is a problem in general ; in fact, if your site isn't trivial you end up with some complex logic about loops, attributes, content, conditionals, and so on. Using even more abstraction is just plain wrong, because:
1) you generally want to control what the output HTML will look like, so forget about a 'builder' tool, like a series of doc.addParagraph(...), or doc.addTag(P,content,attributes) ... it's Ok for passing data through some XML markup, but HTML documents are generally to complex to keep a clear idea of what the output will be this way. Customizing the layout is going to be a real mess.
2) You want to use a 'template' library to avoid using too much logic inside your markup. This ends up being a joke, because you still want some logic, and you end up re-inventing a worse language that has to do loops, conditionnals, formatting, while your base language has certainly a better, more elegant syntax ( that's why I think Smarty is generally a waste of time ).
3) simpler intermediary language, like some XML markup then transformed to HTML through XLST leads you to the same pitfalls. You think you can avoid having logic in your markup, you end up reinventing another language, having to learn that language, learn some other technologies, to find out you get even more complexity.
The problem with tag soup is just the very same of any language in any situation when you lazily prefer writing spaghetti code than creating meaningful functions, explicit variable names, clear indentation, well divided problem solving, and so on. Any programming language embedded in HTML is OK for me, anything else is most probably a waste of time. What you really need is to do all the complex stuff outside that embedded HTML file : do the business stuff and read all the records you need in the controller, and when you need complex formatting or logic rules, do it in helper functions that you'll define in a library accessible from your embedded html. In that embedded HTML, use your primary language, except everything must be very concise and trivial. Anything non-trivial as to be in outside helper functions with meaningful names. How do we program in general ? When we write a method we make sure all the code is about the microproblem you're trying to solve through that method, and anything too complex has to be in other methods, right ? That's just the exact same thing happening here. Being in the middle of HTML markup doesn't mean you can forget those programming rules. It's lame to blame your programming language when you put yourself in a mess, and that applies here too.
So, for your typo example, it's not that bad, really. The first row and even/odd rows are recurrent problems that can be replaced by simpler helper functions, where counting and choosing the right string happen. Using ruby blocks it can even be rather more elegant than any half-broken template engine with poor syntax. Those temp variables could have been moved to helper functions. Generating links and labels could have been done more concisely, too.
That typo example is quite messy, fair enough, but that doesn't mean you can't clean it up. Don't throw out the baby with the bath water.
Your room is messy ? Hey, just buy some shelves. Burning everything isn't a solution, if you don't get the lesson you'll just get in the same mess again and again, burying your lazyness in layers and layers of dirty stuff you never wanted but that at least you can blame.
If we have a ton of logic mixed in with an html (or rhtml or phtml or whatever) file, it might be time to start thinking about giving some of that logic back to the controller and splitting some of your potential view options into separate files, instead of trying to make one template file the do-all for a particular part of your site. If you have a bunch of conditionals in your template file, maybe you need multiple template files, and the code that they have in common can be put into one reusable file. Many times, it seems like we do the opposite.
Brian Warshaw on July 21, 2008 5:31 AMThere's only so much form factor in text-based source code, that you either take a tag soup (as in ASP/JSP), or attribute soup (as in TAL). Lispish language offers the quasiquote, which comes pretty close to ASP/JSP, but maintaining some semblance of syntax sanity.
If only HTML5 is more like WPF, we'd have a clean separation of machine readable data and templates being processed on the client-side.
Ditto on HAML. It's HTMLegant! ;-)
Ted on July 21, 2008 5:34 AMTo the PHP guys suggesting that you let your PHP spit out your markup:
This is fine if you're the only person who's ever going to adjust the view, but it makes the web developer the bottleneck, and it turns something that should be a fairly simple, mostly-static operation into a task for your application instead of a simple import.
Brian Warshaw on July 21, 2008 5:35 AMNormally to get around the tag soup I use literals and programmatically add the code there, you can then easily add a literal to a panel and presto, properly structured code without having to inject html in your code behind or inject code in your html.
Mauro on July 21, 2008 5:37 AMA lot of tag soup can be eliminated by using functions instead of coding every last thing onto every last HTML element/attribute.
Matt on July 21, 2008 5:38 AMEver since I read it, I've sworn by 4 Layers of Separation (http://particletree.com/features/4-layers-of-separation/) - Now I put all my content in XHTML files, headers, footers and the like in XSLT files, transformation code in PHP, and JavaScript / CSS in separate files. It's extremely flexible.
Victor Engmark on July 21, 2008 5:38 AMWhen it comes to messy mixes of markup and template code, HTML forms can be about the worst case.
In our codebase at work, we write forms in pure XHTML - with little or no template code in them. Then in the controller code, we extract the form from the view output and parse it into a form-centric DOM-like structure. From there, the request parameters can be loaded into the form, the DOM can be freely altered to change input values, add select options etc, and validation rules can be attached to fields. The resulting DOM is then serialized back into HTML and injected into the view - with validation errors when relevant.
I find this is an excellent way to deal with some of the worst culprits of the kind of tag/code soup you're talking about. It's pretty much the reverse of the more common form builder approach, which I've never found fun or productive to work with.
Paul Annesley on July 21, 2008 5:42 AMTwo things which work better than the tag soup tools you mention:
GWT -- create your UI programatically, rather as you would with a GUI toolkit, getting all the type safety, reuse and refactoring support you expect.
Tapestry -- You still have HTML templates with expressions in an expression language embedded into them, but the emphasis on creating reusable, parameterised components, and the matching of view components in your HTML to model components in your server side actions makes your pages much cleaner (http://tapestry.apache.org)
Tom Davies on July 21, 2008 5:43 AMJeff,
I feel you with the tag soup, especially in classic ASP. However, I just do not run into that in .NET 2.0 and later. I find that after combining user-controls, web custom controls, and judicious use of the render method that I've eliminated most server code from my HTML.
I'm so adamant about server code being mixed with my HTML that I've gone on a mission to make my teammates abandon the practice. Overall, our project may contain more user-controls but ever since we've found better ways to utilize web custom controls these multi-filed pieces have been removed.
The only time I'm finding myself using server-side code is when I'm working with JavaScript. Even now, though, I'm coming up with ways to build a set of best practices for our team to eliminate this server tagging.
I think you just need to revisit why you are needing these tags. If you're building a list or table, would this not be better done using XSL and XSLT (hopefully on the client; offload that work to the browser!)?
Mike G on July 21, 2008 5:43 AMIt does seem that the two approaches are to either output html with functions, or to intersperse it. I generally use PHP or perl at work, which means for the most part I do the interspersing.
Moving everything into functions will make the view look cleaner, but I've found that you can still end up with a situation where making the markup valid requires knowledge of what is inside those functions, so that ends up making the problem more difficult in the end, or it can.
Reducing it to just loops and printing helps.
I do find the lisp approach interesting though:
(dashes mean spaces)
(yaclml:with-yaclml-output-to-string
--(:html (:head (:title Hello, world))
----(:body (:h1 Hello, world)
------(:p Hello, world!!!!!!)))
It's not possible to get the nesting incorrect, but it's also very, very similar to what the output will actually be, so it's not just confusing things by requiring the use of helper functions that aren't immediately clear. You could manipulate or generate this with the same general utilities used to make other lists.
I haven't used it in production myself, so maybe it's terrible in practice. I find it interesting.
A small amount of tag soup is unavoidable (but done right, it *is* delicious soup!)
My solution when it comes to things like a CMS is to write a simple (although fairly crude) scripting language within the HTML that is the page content - this way the PHP/HTML soup is minimal, elegant and stupid and the logic is folded into the data.
To some extent, I do this in other areas, such as a navigation menu with sub menus displayed as a list. I will create a simple (not XML!!!) way to store the menu items in a plain text file, and parse that with PHP. An entry might look like:
# text | tooltip | url | sub-menu filename | rule
Home | Return to home page | ./ | index.nav | group = any
Admin | Administer the website | ./admin/ | admin.nav | group = admin
And in the end, as long as you are clever with your CSS, tag soup is really only a few small a/ul/li/p/div elements here and there - if you're overwhelmed by messy code, it's probably a sign that your HTML is to blame.
Ben on July 21, 2008 5:51 AMSome thoughts on view language design (interesting mostly only if you're designing frameworks): http://lhorie.blogspot.com/2008/07/designing-maintainable-view-code.html
Leo Horie on July 21, 2008 5:51 AMHi guys, here is what your're looking for : TinyButStrong PHP template engine system. The best template system i've ever know.
Look at the article Doing PHP templates of the 3rd kind : http://www.tinybutstrong.com/article_3rd_kind.html
The syntax is clear and powerful, it really SEPARATE the program (php) from the view (html+tbs syntax).
It's under GPL, and way faster than smarty. Powerful modules, great help, ... a must have.
Take a look at the Examples and Why use it? and 5 Golden Rules (http://www.tinybutstrong.com/support.php#goldenrules) and of course Manual.
I'm actually writing a tuto about PHP 5 Objects with TBS, stay tuned !
(structured website)
And I've recently receive my CodingHorror Tee-shirt, sweet !
TiTi from FRANCE.
XML+XSLT /could/ be an answer to this tag soup stuff. Or some XML-based template engine.
Still, I think formatting your templates correctly will help a lot, even if you put in snippets of PHP/ASP/whatever.
That HAML stuff is scary. Is it supposed to be readable? =)
Jani Hartikainen on July 21, 2008 5:54 AMI second the comment on GWT...it truly is the best way I've seen to do a non-trivial web application developed by a team. You can brute force any framework/style on a trivial application and we've all written code that you're the only one who's ever going to see. GWT forces you to abandon all the bad behavior that we somehow accepted when we switched over to the web back in the old days. Traditional heavy GUI application development has all the right implementations, but the web forced us all to bail on them. Interestingly, I've seen very, very strong web developers struggle with GWT since it forces a rigor and style of thinking that they've never been accustomed to. If you've written apps in Swing, SWT or any of the traditional Microsoft UI tools, it's the way to go.
Mike Shaffer on July 21, 2008 5:55 AMThis is exactly why I've been so keen on placing as much of my code in the code behind files as possible while developing ASP.NET applications. For example, even though you can insert tags that show what value a control should be bound to, or what method should be called when I click a button, I want those declarations done in C# (or VB.NET) to provide clearer separation, and in my opinion easier reading.
There still is a code behind file for the view in MVC isn't there? It's been a while since I've taken a look at it. Couldn't that provide a way to ease some of this pain?
John Chapman on July 21, 2008 5:58 AMOne of the more elegant-looking solutions to this problem that I've found is PhpSprockets (http://code.google.com/p/phpsprockets/). It generates valid X/HTML in PHP so it becomes much easier to write your entire page in PHP. I haven't used it, though, so I can't say how good it is in practice.
Ian Potter on July 21, 2008 5:58 AMI don't think that flex and/or silverlight fix the problem of effectively marrying code to html, because they don't output html. It's not an apples to apples comparison, and not relevant.
The problem, you see, is html! I don't need another syntax that will, if it's to be as powerful (or broken) as html, will end up being almost, but not quite html.
It's very hard to create html that uses javascript (ie ajax) and proper css that really does work cross browsers for a decent sized web application while keeping everything easy to maintain / change and standards compliant and localized/globalized.
hombre on July 21, 2008 6:08 AMThere are also TAL markups ( http://www.zope.org/Documentation/Books/ZopeBook/2_6Edition/AppendixC.stx, http://phptal.motion-twin.com/introduction.html) wich make the xhtml code to look like real xhtml.
PiotrN on July 21, 2008 6:09 AMI found Amrita (http://amrita.sourceforge.jp/docs/QuickStart.html) to be quite interesting approach. Didn't try it yet though.
Miika on July 21, 2008 6:15 AMI use jquery's taconite plugin to avoid getting code into the presentation layer.
Goran on July 21, 2008 6:17 AMHave a look at smalltalk seaside. I don't know if it's a better way, but it's at least a different way.
Philippe on July 21, 2008 6:18 AMHmm... Java lets me easily define my own custom tags (parameterized and all) which cleanly separates the code out of the way. No need to mix tags and code (the older versions were doing this since they copied the MS ASP approach, thankfully that is no longer the case).
JL on July 21, 2008 6:19 AMLook, it's programming 101. Break up the routine into smaller, saner chunks. Partials and user controls work fine.
Matt on July 21, 2008 6:21 AMOn the java side, have a look at Wicket (wicket.apache.org).
Cleanly separated view template from code, small reusable visual/logical components, no tag soup at all.
Dave on July 21, 2008 6:21 AMJeff, you may be interested by the TAL or Kid/Genshi approaches: instead of creating a new template language mixed in with the markup (or putting raw code directly as RHTML or JSPs do), they augment existing markup with custom attributes.
This has the following advantages:
* Usually, they mandate xml well-formedness, which means your output should always be well-formed
* Browsers ignore custom attributes (usually), which means you can preview the raw template code... most other template languages don't allow that
* They have access to existing XMLy technologies (e.g. Genshi uses XInclude for fragment inclusion)
I do prefer Django's approach though (a very restricted template language, forcing the logic either in custom template tags or in the controller/view code)
Masklinn on July 21, 2008 6:24 AMWe've extended our PHP5 framework to auto-generate XML output. It also expects processing instructions and apply the linked XSL docs accordingly.
We've found it greatly reduced the amount of code we had to write - its now down to some form-processing logic, a bit of SQL, and XSL.
Using XSL as the templating language has other benefits too - we can call back to the framework and grab rendered XML for other pages (shopping carts and tag-clouds, for example), we can use the XPath doc() function to request page fragments from other sites, and we can easily switch output from HTML to JSON by switching the stylesheet.
Phillip Oldham on July 21, 2008 6:24 AMThere is also Java annotation based HTML template system which uses 100% clean html templates. It ensures the same separation between code and template as the StringTemplate system by Terence Parr.
http://jabhts.org
The binding between the html and the java code is done using java annotations, so the coding overhead is minimal. It's not fundamentalistic, so you can still output raw html if you want to.
It uses inner-classes in Java for providing extra scopes so your code doesn't end up as one huge class, but enables dragging in sub-modules by creating derived inner-classes.
I second the nomination for TAL: it's a very elegant templating language. But, as others have pointed out, the problem with your example isn't the templating language (it almost never is) but rather a failure to enforce a separation of concerns by overloading the view.
James on July 21, 2008 6:29 AMI have used PHP (awful for this problem) and Common Lisp, using a couple of different libraries (see http://www.weitz.de/ and Parenscript). The Lisp method as mentioned previously is much cleaner than any other tool I've seen used.
Taliesyn on July 21, 2008 6:29 AMHi Jeff,
Apparently the ASP.net MVC is working on cleaning up the views, so you're stuck with the poor templating code for now.
Have you seen what Genshi (http://genshi.edgewall.org/) are doing in comparison? They extend the HTML namespace with their custom attributes for for-loops, if-statements, etc. It's python based though.
It reads like a charm and is easy to work with in an XML IDE.
Ciao,
Shaun
Apache Wicket (and from what I understand, Tapestry and JavaServer Faces) avoids this problem pretty well:
Most of the HTML is loadable without any server running, and special tags in the HTML represent server-side components that have their own markup that is also loadable without a server.
Jim on July 21, 2008 6:30 AMThis is why I'm a fan of attribute based templating such as with TAL, where you can do things like:
h1 tal:content=view/titleTitle goes here/h1
ul
li tal:repeat=item view/items tal:content=item/nameitem name/li
/ul
You always end up with valid html and you're somwhat enforced to have a strict model/view/controller separation - you simply can't do anything fancy in the template and are forced to embed it in a view class (which is plain code)
I second (or third?) NHaml.
We're using the NHaml view engine with the MVC framework on a very large website and it's an absolute dream to work with compared to the default webforms view engine.
- JD
John-Daniel Trask on July 21, 2008 6:31 AMJSF can really help minimize this in java. I've written JSF pages with little to no regular HTML at all in them using pure JSF tags instead and using CSS to take care of the look and feel. GWT also seems like a good solution, though I've not had much experience with it yet.
If you do have to embed code into a page, really try to move as much of it as possible out to utility methods that can be unit tested outside of the page.
Alb on July 21, 2008 6:31 AMI think the bigger a project gets, the more important it becomes to strictly separate code and presentation. Mixing code and markup is fine for smaller web applications, but it get messy soon.
Java's JSF with Facelets (https://facelets.dev.java.net/nonav/docs/dev/docbook.html) is another MVC framework that uses plain XHTML for view construction. The only code is in the EL-expressions that bind page components to the model.
Daniel on July 21, 2008 6:32 AMI'd second the call for Seaside. It's a whole new way of working!
Rob on July 21, 2008 6:32 AMTag soup is indeed a big problem and you can find examples of it in every language and framework but the Rails code you posted seems absolutely amateurish to me, and I'm an amateur! All of the loop logic can be removed by using a partial with a collection, Rails *has* a method (cycle) to accomplish the even/odd row magic, and those absurd link_to calls can be cleaned up by a few lines in the routes file. These aren't advanced expert tricks either, these are the things pretty much any introductory Rails book teaches.
Personally I hate seeing variable declarations or any other script tags in my view code. I try to write my views with a complete non-programmer in mind; someone who doesn't even understand simple decisions or loops. Your views become a lot easier to read and it forces you to truly separate view from controller.
devonrtucker on July 21, 2008 6:34 AMWhat amazes me about Tag Soup as a problem is its longevity. Everyone knows it's a problem. There were some kick ass holy wars over the past decade in the JSP community surrounding it. The decision trended towards, avoid as much as possible and move the logic into HTML-like tags.
Of course, this didn't actually solve the problem, it just made it more readable....or so they said. It's obvious this wasn't the solution. If it was, PHP, Ruby, etc. wouldn't be making the same mistakes trying to solve the same problem years later.
This makes me wonder how much of a problem it actually is. Certainly move your logic outside of the tags whenever possible. But:
c:if test=blah is really not much better than % if (blah) { %
The solution chosen will gravitate towards the familiarity of the programmer. An HTML designer may gravitate towards c:if while a Java programmer would pick the pure Java construct.
Mike Cornell on July 21, 2008 6:35 AMI should make clear i meant outputting the HTML with printf type functions (echo) and not using the functions like the property one recommended above. (Although this may be a good idea for some)
My HTML is still inside my PHP, its just well enough wrapped to not be confusing... at least for me. Comments help too. :)
After looking at it a bit, ASP allows a similar method of writing a code module... it all comes down to personal preference at the end of the day, and there are a number of ways to make this problem manageable judging from the comments.
Jheriko on July 21, 2008 6:37 AMJeff buddy - this post falls into the category of I don't know WTF I'm doing so it must be THEIR FAULT. And while some of that is true - it's also a bit on you friend. HELPERS are core to centralizing your View Logic. Rails, Django, blah blah framework - they all share this philosophy.
You can rewrite your mess quite easily and make it a ton more readable. This post is fail.
Rob Conery on July 21, 2008 6:37 AMI'm not a Django expert, but I believe their philosophy is that template engine only fills the template with properties of objects provide as context. Last I looked, Django's template engine didn't, by design, even support obvious language features like assignment. However, it does provide simple ways to do presentation specific things like time and date formatting.
In my humble opinion, you can't solve tag soup problem any better than that (perfectionist, pedantic and practical). In the real world web developers have to have direct access to the html/css so that they can apply hacks that allow 70% of browsers so render the pages correctly. That throws out all forms of light markup languages like markdown. Throwing more programming at the problem is unfeasible for the same reason and because then only programmers can make chances that should be doable for programming challenged web designers.
Bloodboiler on July 21, 2008 6:40 AMJani, XSLT is also a mess. It's a bit more readable because you use the same kind of markup to write html as well as to write xslt xml. The benefit here is that this setups really separates view from business logic. But it's still hardly readable:
code
xsl:template match=article
div class=article
h2
xsl:attribute name=classxsl:value-of select=category //xsl:attribute
xsl:value-of select=title/
/h2
div class=body
xsl:value-of select=body disable-output-escaping=yes /
/div
div class=info
span class=commentSent: xsl:value-of select=created //span
xsl:if test=string-length(updated)br /span class=commentUpdated: xsl:value-of select=updated //span/xsl:if
/div
div class=options
axsl:attribute name=hrefxsl:textindex.php?m=articlesamp;a=viewamp;id=/xsl:textxsl:value-of select=@id//xsl:attributekomentarze/a,
axsl:attribute name=hrefxsl:textindex.php?m=articlesamp;a=editamp;id=/xsl:textxsl:value-of select=@id//xsl:attributeedytuj/a
/div
/div
/xsl:template
/code
Dear. God. WTF?!
Tag soup is Eeeeeevil. This is the whole reason I switched to .NET, to get away from that crap. Now you're telling me tag soup is back in action on ASP.NET MVC? I guess I'll be skipping THAT beta test program.
Ivan on July 21, 2008 6:48 AMAnother vote for looking at HAML here. Just being able to lose closing tags is a boon for readability.
Another idea that Rails has (quite possibly borrowed/copied from somewhere else) is the helper function, where logic can be extracted to a proper code location.
With a few pretend helper functions thrown in (and there are other obvious ones left as an exercise for the student) I translate, the Typo Coding Horror above something like this:
- c, f = 1, 1
- for page in @pages
%tr{:class=tr_class_for(page)}
%td.first_col= page.created_at.strftime('%d %b, %Y) #
%td= title_link_for(page)
%td= truncate(Post.strip_html(page.body), 50)
%td= page.permalink
%td.del_col= destroy_link_for(page)
- c = (c == 1 ? c + 1 : c = 1)
- f += 1
-unless @pages.length 0
%tr.header
%th{:colspan = 5}
.pagination
.prev
- if @page_pages.current.previous
=link_to 'laquo; Previous page', { :sort = params[:sort], :page = @page_pages.current.previous }
nbsp;
.next
nbsp;
- if @page_pages.current.next
=link__to 'Next page raquo;', { :sort = params[:sort], :page =? @page_pages.current.next }
(If the spacing doesn't come out, then it's better-indented here: http://pastie.org/237819 )
Now I'm no Rails or HAML expert. Honest. But that looks a hell of a lot better to me, and I'd bet the effect would be similar in an ASP.NET environment. I'd like to see it, anyway.
Mike Woodhouse on July 21, 2008 6:54 AMXML + XSLT certainly helps, but if done naively you still wind up with XSLT code sprinkled throughout your HTML which can be hard to read. We eventually built lots of XSLT templates for the most common HTML that we produce, which at least localises the problem. See https://dev.youdevise.com/YDBlog/index.php?title=hiding_xslt_tag_soup for more details.
Douglas Squirrel on July 21, 2008 7:00 AMI'm surprised that no one seems to have mentioned Hpricot (which is included in the Camping microframework, both by the inimitable genius that is why the lucky stiff). It leverages Ruby to produce a really nice little domain-specific language specific to producing HTML. The code at http://pastie.org/238265 produces the following HTML: http://pastie.org/238267
Jeff Pants on July 21, 2008 7:01 AMOne solution to the problem is to write your own HTML preproccess markup which will be changed into html before the page is being outputed to the client.
For example:
[row]
HTML_ROW
[field_one] [field_two] [field_three]
END_HTML_ROW
[/row]
The [row] tag represents a fictionall row object which will be edited and modified before the html is being loaded, then coverted to html and then insereted into the template.
Jeff,
I'm not that familiar with .Net web technologies, but this is one area where I love Java (and I assume .Net has something similar). Use XSLT as your primary view technology. You can add custom tags by defining a new namespace in your stylesheet.
Process the whole thing with the SAX api (SAX Source and Result on your XSLT). That way all of your logic can be in your .Net/Java code, and you can develop tags that are at the correct level of abstraction for your application. As a bonus, no tag soup in your XHTML output.
This is not as trendy as the current frameworks, but for programmers very flexible.
GWT seems like a good answer for programmers too, but I think there questions about accessibility. And of course 100K of Javascript is not always the first thing that comes to mind when people talk about REST.
Mark on July 21, 2008 7:08 AMJeeze, replace those % XXX % with ?PHP XXX ? and that looks just like my crappy php.
LOL
Allen on July 21, 2008 7:12 AMRails solves this problem with partials to put logic as close to the beginning and end of the content (eg, wrapping the content in just a slightly different kind of tag, so as not to clutter up the actual content), the whole thing then gets placed into a larger template.
The downside to this, of course, is that you have to constantly be rendering multiple partials and that can be slow. But hopefully you're caching stuff anyway.
dude on July 21, 2008 7:15 AMI'm a j2ee dev that works on a form fill enterprise app. as such its pretty hard not to have tag soup but its generally in the form of %= bean.getVar()%
not exactly tag soup.
for all of our complex stuff we use taglibs which output the html. Is it confusing refactoring the taglibs? kinda, but once they are stable its not too bad.
At home i do some cakePHP, and i stuff all my server side code in an element.
?php echo $this-element('helpbox',array(helptext = Oh, this text is very helpful.)); ?
that doesn't seem too much like tagsoup to me.
Yes it is just transferring the problem to a different area, but if i start editing the navbar element im likely to only see code that is relevant to the navbar, so i can focus on the relevant portion.
Tristan on July 21, 2008 7:19 AMNormal ASP.NET controls and web forms?
chakrit on July 21, 2008 7:22 AMThis kind of thing is a truly horrible and counter-productive technology in my opinion.
I took over a huge suite of manually written reporting pages implemented very badly by a completely undisciplined and careless coder (I refuse to call her a programmer) in jsp, html, Struts (with Java Action classes and custom tags) with a generous larding of JavaScript.
The first few months were very, very unhappy...lots of untraceable bugs...until I realized that I basically had to rewrite everything. What a huge waste of time!
Don't put your least experienced coder anywhere near this stuff as it will cost you much more time to unravel it than it took to create in the first place.
Sue W on July 21, 2008 7:22 AMIsn't this why templates were invented? What's all this fuzz I'm hearing about MVC in web programming? Are people just talking about it and not actually doing it? That code you posted looks like my PHP hacks from the early 2000s.
Anders Sandvig on July 21, 2008 7:24 AMJust echoing what others have said about .NET 2.0
I really have not experienced tag soup on this platform. User controls and such nicely seperate most complications and still allow our designers to edit the markup with relatively little stress.
Also as someone pointed out, in that example the HTML markup isn't great. It's a lot easier to have nice clean front end code with server side code interlaced when the HTML is simple and semantic.
Chris James on July 21, 2008 7:24 AMhow about Markaby ?
Trev on July 21, 2008 7:27 AMNo real clean way around it. No matter the fix as many have suggested, it causes other problems. Tag soup is an unavoidable problem of web development and it stems from the fact that in this unique environment you get to use several languages in one environment.
All sever-side scripting has this unfortunate drawback. However, I have noticed that's why companies would rather hire people with experience than those fresh out of college who probably cannot read mish mashed code very well. An experienced programmer can read the sometimes convoluted code. College kids have a much more difficult time in doing so.
If done properly, Jeff is right. You can write good tag soup. Too often though, I see bad tag soup. And as others have mentioned, when writing the code yourself that only you maintain its not that bad. You know your style of doing things. However, the problem comes when maintaining someone elses code and that is where things can get tricky.
Adam on July 21, 2008 7:33 AMI see someone mentioned Velocity for .net. That's kind of what I meant. With Velocity and or XML/XSLT with custom tags in Java you create your own (hopefully consistent) template syntax and you don't have to make such a big soup. I guess I already assumed that's the kind of frameworks people were using (but then again, assumption, etc..)
Anders Sandvig on July 21, 2008 7:34 AMSeveral commenters have said it above. You should be doing as much logic as possible in the controller. That way it's testable that comments that are unmodded appear in red, as the logic for this isn't embedded in a page but are in the controller.
If your HTML page has too many % if (... 's, its a smell that your controller isn't doing enough controlling.
Will Sullivan on July 21, 2008 7:34 AMGoogle is open-sourcing GXP, their (full disclosure: our) template language that has as one of its goals strong restrictions against imperative code attempt to force separation of application logic and templates. There will be a presentation at OSCON about it:
http://en.oreilly.com/oscon2008/public/schedule/detail/3501
Mihai Parparita on July 21, 2008 7:35 AMThe example you gave is really ugly, but could be cleaned up. In a world where search engines and rich javascript are important, then control over the generated html matters. When you don't care, then using an abstraction layer like asp.net web forms is fine.
Part of the reason for the seperation of concerns is to allow developers and designers to work independently. So any templating solution needs to work with tools designers use and not require them to be developers to develop templates.
The ruby on rails way is nice, because of ruby's dsl abilities you can create a language just for templating and have the full power of a programming language.
I am a .net developer so until IronRuby comes out, I have been working on a django inspired template engine for my asp.net mvc project.
Mike on July 21, 2008 7:38 AMThe rails sample isn't that bad i think, althoug it could be better indented and some of the code had been moved where it belong.
For instance this line: (ignoring angle brackets)
% link_to (page.title == '' ? '[Untitled' :page.title), Site.full_url + '/admin/pages/edit/' + page.id.to_s %
should have ben simplyfied to something like this:
% link_to page.get_pretty_title, edit_admin_pages_url(page) %
and adding this to the page model
def get_pretty_title
return '[Untitled]' if self.title.empty?
self.title
end
Using MVC helps the tagsoup problem a lot...
The examples above look like rather bad examples. In normal code, you'd refactor and split it up in several methods; in the first example e.g. get_row_class, next_page_link, etc. This is possible (most) in HTML/code-combinations as well. In Java, one of the ways to do this is by introducing custom tags, in Rails you can user helper methods, include partials, etc. I'm sure there's something in ASP.NET MVC too.
(In fact one of the great advantages of Rails IMO is that there is a low entry barrier for cleaning up the tag soup - much lower than in Java.)
Jeroen on July 21, 2008 7:40 AMAnyway the real reason its better to have soup is that a CSS developer makes the templates and decides how to get the page working, if it was just up to the severside dev then everything would look dogshit because they don't understand that hacks involved to create things they just know their drag and drop in many cases and that makes one thing… bullshit
Trev on July 21, 2008 7:42 AMI just use standard VB.NET / ASP.NET. With code-behind pages and ASP controls, there is very little tag soup. The worst of it comes with using Repeaters, and even then it's not too bad.
In my opinion, ASP.NET already took a large step towards solving this problem.
Sean on July 21, 2008 7:48 AMOn the Java side, I have used Struts along with Tiles. All the tiles deals with is the data (only logic as needed, for building tables, etc). The more the view only shows data the better, it makes it easier when the front end needs to change or if I want to reuse components.
Alex on July 21, 2008 7:48 AMFlex.
I'm serious. It solves the tag problem, as it separates the client side from the server side and provides quite reach UI.
Whether you want to use it here or not is another matter.
Pawel Rygielski on July 21, 2008 7:49 AMThe comments to this entry are closed.
|
|
Traffic Stats |