I’ve been on any number of HTML projects with all kinds of different programmers over the years.
I’m yet to see a programmer who always remembers to escape their output correctly with string concatentation. This includes me, and I’m very aware of the issue. Encoding issues like that are probably the number two cause of security vulnerabilities; with that approach, you forget once to escape correctly, and you’ve got a potential XSS security vulnerability on your hands.
On the other hand, I’ve found that a full OO-esque approach has had comprehension difficulties that make it tough to just throw a web page at somebody and expect them to work on it. Personally, I love the OO approach because it allows you to create functions for recurring snippets (and I wouldn’t be caught dead using a language or library that was a quarter than verbose; I’ve written libraries in languages where the penalty is about two chars an “element” (tag, attribute, etc.), which came back almost instantaneously due to the functions I got to write), but this is also something I’ve experienced people having fun with.
Where I work now, the lead developer and I went back and forth on this issue, and we settled on a compromise I’ve found acceptable, and has been working for us (that is, people aren’t accidentally writing XSS vulnerabilities left and right): We changed the default escaping mechanism to be XML/HTMLEscape, instead of straight concatenation. We’re in an ASP-esque enviroment that uses [%= %] as the shortcut for rendering, and then we added [%! %] for “no escaping” inclusion. Square brackets are used because there is no indication of whether this comment box will take HTML, and there is no preview. (And we’d use the ASP templating to do that substitution, not string manipulations in the program.)
This has avoided the very real objections raised about crossing encoding planes (very dangerous, should not be underestimated!) while still retaining the practical essense of the second solution.