- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Maybe it's time to move to ASP.NET...
Admin
Ah, those freshman follies!
I did have one occassion where I was told to build a small, data-intensive internal site, but explicitely denied the opportunity to make it dynamic. So I wound up putting the data in MS Abcess, and using MS Word .dot files with bookmark objects to make life manageable, dumping a lop of .htm.
See, boss! You said static!
As far as this WTF goes, two things we all need to do are grasp the cost of each act we ask of the system, and RTFM.
Aside: <FONT color=#555555>Alex Papadimoulis</FONT> , thanks for the boot to the head about tlkp_ a few days ago. Made me rethink the design of a pet project, with positive results.
Admin
I think this can be made to work. Instead of doing the replacements for every request, have a caching system that replaces @@ORDERTOTAL@@ with <%=OrderTotal%> automatically, and then just use plain old ASP. This way, you only have the cost of checking if the ASP code is up to date with the files the web designers are using.
Admin
Finally, someone spelled the name right to MS's consumer-level "database" system.
Admin
I have to disagree to some extent that this is a wtf. Especially from the other wtf's we have seen. I worked for a company that implemented this same type of philosophy. It allowed us to port the code quickly. In our world, we would build websites for various companies. Rather than constantly changing the .asp code and/or .html, we had standard functions like this that would process "template" type files. It was simply a matter of changing the template for each customer. Granted, it could probably be implemented a little better using vb com dll's and I'm sure .asp is not the fastest when implemented this way. But a wtf? Not really. (imho)
Admin
I must say that I have seen a nearly complete implementation of cold fusion (cfm) implemented in asp 2.0 using the same parsing based approach.
Try not to think that this is the exclusive domain of juniors and newbies, I am periferaly aware of stuff created by MCS France that didn't want to confuse people with <asp:controlType ... ></asp:controlType> so they created a kind of FrontPage webbot that converts custom tags to asp.net tags when you upload them to the server.
Admin
Isn't this exactly the philosophy behind JSTL?
It's too confusing to write
so instead we write
(No, I'm not justifying the WTF code, I'm bashing JSTL.)
Admin
I meant, we write
Admin
What exactly is the line of thinking here?
"That asp.dll extension is crap. Why, I bet I could do my own. With a scripting language. That uses asp.dll."
Admin
Of course I could mention the other WTF nobody has noticed, abusing the string datatype to hold large amounts of changing content when a StringBuilder should be used. Their string abuse is probably the largest bottleneck of their application.
And in case you are wondering, StringBuilder DOES exist for VBScript (aka Classic ASP) and VB6. For Classic ASP check out http://www.15seconds.com/howto/pg000929.htm
For VB6 you have to include a COM object, but you can google it if you are curious.
Admin
Silly microsoft types, don't you know templates are so 1990's? Transformations are where its at now.
Admin
Without JSTL
<%@ page import="com.mycompany.myapp.UserContext" %>
<% UserContext uc = (UserContext) session.getAttribute("userContext"); %>
<%= uc.getGroup().getName() %>
With JSTL
<c:out value="${sessionScope.userContext.group.name}"/>
With JSP 2.0 EL
${sessionScope.userContext.group.name}
You're so right. JSTL is definitely useless. And that expression language crap. I mean really, who needs it?
Admin
Yeah, so is asp though.
Admin
Self-referential names are as cool as all openOutdoors. Self-referential code is Lisp.
Admin
This is why ASP was invented. You can already have variables and function calls in an ASP. An ASP is a template already.
I think you're smoking crack. IMHO.
Admin
In your favorite IDE or editor, try searching for usages of the getName() method.....better yet, try to use your IDE's refactoring tools to rename "getName()" as "getUsername()".
Or try to figure out, just from the JSTL expression, what classes are being invoked.
</c:out>
Admin
ASP is NOT implementing itself. The .html file is a static string - no ASP directives are processed by Response.Write.
This isn't really a WTF... it could be sped up by loading the template into the Application object, for example:
Application_OnStart:
Application("Discount_Template") = CreateObject("Scripting.FileSystemObject").OpenTextFile (cstpg_SHOW_DISCOUNT, 1, False, False).ReadAll
In this page:
v_Content = Application("Discount_Template")
...
Any stale content issues could be fixed by having an admin page which reloads the file into the application string.
Admin
Good point. Really it should be:
Servlet snip:
String groupName = userContext.getGroup().getName();
request.setAttribute("groupName",name);
JSP snip:
${requestScope.groupName}
Admin
v_Content = CreateObject("Scripting.FileSystemObject").OpenTextFile (cstpg_SHOW_DISCOUNT, 1, False, False).ReadAll
v_Content = Replace(Replace(Replace(Replace(v_Content, "@@ORDERFINAL@@", FormatNumber(v_OrderFinal)), "@@ORDERSUM@@", FormatNumber(v_OrderSum)), "@@ORDERINIT@@", FormatNumber(v_OrderInit)), "@@ORDERREC@@", FormatNumber(v_OrderRec))
Response.Write v_Content
I totally made that code more efficient by reducing those four Replace() calls to one single line. Now it will work 1x as fast! Seriously this was the worst idea ever. Create your own scripting language to run on top of another scripting language. What about when someone wants to add a 5th variable? Gotta add another variable to their lookup table, and another Replace() function call, thereby delaying the load time of the page just a little bit more.
All of this because the web designers get confused with ASP tags. Sheesh, they're freakin' web designers!! They should know simple web languages like ASP enough to know what this will do: <%= myVar % >. If not, they shouldn't be messing with that code in the first place, just stick with their Flash animations.
And I am wary of the excessive use of FormatNumber where the only parameter supplied is the actual number, and the "programmer" is allowing the default optional settings control the output. It's just not good form. IMHO.
</FONT>Admin
So your suggestion is that rather than educate the web developers in the simple syntax of a well-known web language that has been mastered by hundreds of thousands of people, instead we should add a little ASP code to make the server load all HTML pages into memory on bootup.
And the reference about ASP implementing itself is in the Replace() function calls, because ASP will already do that if you use the proper syntax in the page. These people came up with their own syntax which ASP must now detect and deal with. Instead of one ASP file to do everything, they have one ASP file which the user visits, but it loads an HTML file and does ASP-like automated find-and-replace on it, only much slower because it's working through the scripting layer.
Admin
Possible valid reason... it may be that there is a design constraint in place to separate content from code. This is likely given the path to the file:
e:\content\estore\shopping_cart\show_discount.html
I suspect that content editors have rights to the E:\content directory and can change text, HTML, images, etc. Giving these content editors access to the ASP files might be dangerous. The code is a reasonable solution given these design constraints (except for the slowness - probably mostly due to the overhead of creating the FileSystemObject, and less due to file I/O [which is fast] or string manipulation [which is also fast])
Admin
Sure, why not? I can see this being perfectly viable. If there were thousands and thousands of HTML pages, RAM usage would be a concern... but we don't know how many pages there are in this app...
Another concern would be the first-hit penalty the first user of the day will experience. This could be mitigated by taking all the Application-level caching out of the Application_OnStart(...) event, and having each page be responsible for caching itself.
v_Content = "" & Application(this_page)
If v_Content = "" Then
v_Content = ... ' load filesystem object
Application(this_page) = v_Content
End If
' ... replace @@ stuff...
Admin
Actually I would probably write <fmt:formatNumber type="currency" value="${order.total}"/> [8-|]
Agreed, there isn't yet support in IDEs for EL lookups as there is for strongly types languages. And implementing it would be tricky, as you actually don't KNOW the type of the object.
However I much prefer JSTL to scriptlet code. Give me a <c:forEach>loop rather than a standard for loop any day of the week.
And JSTL is nowhere near as bad as this WTF. It still gets compiled into java code - not loaded/searched/replaced at runtime.
Meh, evnafets
</c:forEach>Admin
From what I've read so far in the comments, I have to wonder what you people think of the Smarty engine, or perhaps Velocity.
Template engines make more sense that you might want to believe, even in template-like systems like PHP or ASP.
Domain-specific language. Separation of functionality and content. Ease of use. Maintainability.
Template engines make a LOT of sense.
The WTF here, if there is one, is that the entire file is scanned once for each variable to be replaced. And that the system is not extensible.
The idea is sound. The implementation is a WTF.
Admin
yuck.
This looks suspiciously like a (now derelict, I hope) Microsoft technology known as WebClasses or IIS Applications. WebClasses are essentially the same kind of thing moved into a VB-implemented COM DLL.
I've had many shock treatments to burn the memory of WebClasses from my cerebral cortex, but I believe it came down to your class responding to a ProcessTag event raised everytime the parser came across a tag in your template (which had the form wc@tagName). The event handler was a switch/case (excuse me select/case), that looked like:
This was the design, not just a workaround.
So, you have all the wonderful text/template problems that ASP gives you, and now you have to recompile a DLL each time your content changes.
Admin
I sincerely hope this is some severely subtle sarcasm (approaching british comedy levels).
Admin
This style of "self-templating" is very often seen in PHP world. In my opinion templating systems like Smarty are good only if there's a clear need for controlling the code which goes into templates (as Smarty allows only subset of functionality put into templates, you can allow only "safe" methods to be put there). An example could be a large system where templates are made by non-programmers and there's so many / so large templates that programmer himself doesn't want to scan then though or a multi-user system where users themselves can submit and use their own templates, so you don't want to see system("rm -rf ~"); snippets there. Compiling PHP templates with PHP into PHP seems a bit slow, but Smarty uses pretty robust caching system to save those compiled templates, so it's really just a first-hit penalty of the first user of the day.
That said, templating templating languages isn't needed if security conserns are not the case, like in this example. What makes this even more WTF is of course that whole HTML is loaded into memory and it's run through 4 times with string match/replace operations.
Admin
Dude,
Your spelling is a WTF !!
Admin
They were sooo close
If only they had written their own web based template editor to edit the e:\content\estore\shopping_cart*.html files, they could have done the Replace at write time.
and simply
<#include virtual="\content\estore\shopping_cart\show_discount.html">
Admin
simply
<#include virtual="\content\estore\shopping_cart\show_discount.html">
Admin
Dude, don't be the WTF.
Loading the file into memory will take as long as loading the asp page or any other html file on the server, assuming a rudimentary server file-caching. You're designing a solution for a NON-PROBLEM. It's the repeated replace() calls that bog down performance.
One solution is to rip through the file two characters at a time with an iterator looking for "@@" and then replacing whatever comes after it appropriately, so you only have one iteration. Most templating modules do something like this. If you're really adventurous you can call an in-proc C function to do the searching with callbacks or a state machine for the replacements. (Which is how the language parsers themselves do it.)
If portability isn't a concern, of course, just scrap it and turn it into real asp like a good code monkey.
Admin
I believe that has more to do with upgrading JSP to use XML rather than removing complexity (in fact I think it introdices it as it makes it had to find good documentation).
While you might not want JSPs switched to XML I like the fact that we will be able to (should be able to at least) check the JSP against a schema before compiliation.
Admin
Generally I think it's a good idea to use a template system, because in ASP or JSP or similar, people tend to mix business logic and HTML layout, which is a pain in the ass when it comes to maintenance.
Of course, it's rather stupid to implement such a system in ASP. I've done that in Java servlets, with good results. Of course, the template engine was a bit more sophisiticated than just stupid string replacements.
Admin
Man, I am amazed at how far I come. I don't miss Classic ASP at all. Thank God I was able to make the switch to ASP.Net when I did.
Admin
I have to agree with Tony, I don't miss classic ASP at all. Even with ASP.NET there are still times when a templating system is required. Imaging a complex ASP app that has a common look and feel across many pages, with common components. Now imagine that the look/feel changes often of the users is allowed to pick from many "skins". Having a Master Page that you can change, without a recompile that flows through the whole site is required. There are many different hacks to achieve this right now, I'm looking forward to the new version of ASP.NET that has this built in.
So, I have to say that maybe the idea behind this wasn't a WTF... the implementation DEFINATELY was. :)
Kev
Admin
I have to agree with both Tony and Kevin, but I experienced the inverse. I had to change jobs recently (because where I was we were working overtime pretty much everyday and every weekend and I need to go to college everyday after work, so I was losing classes and study time, but anyway), and with that job change I stopped working with ASP.NET and I'm back to PHP and classic ASP [:@]. I miss ASP.NET sooooooooooo much [:'(].
(Talk about job change, I'm from Brazil but I'll be looking for opportunities in Canada next year. Any canadians around? Drop me a line at luciolucio AT gmail dotcom. Thanks.)
Admin
That is what we though when we starting making everything smarty for our PHP stuff. Let the programers write code, and the artists who don't known code write the template. Problem is the artists (at least the ones we work with) use tools to write webpages, not raw HTML, much less raw smarty (which isn't much like html). The tools don't understand smarty. The artists don't understand smarty. So the programers (who make terribal artists!) end up having to do the page themselves anyway.
I'm still looking for a solution that allows artists to do what they do best, programers to do what they do best, and somehow takes care of the middle ground where the two have to meet. Programs like photoshop and dreamweaver work well for pictures and web pages respectivly, but they don't handle our needs.
Admin
[H]
For those debating the value of templating systems, both ASP and JSP are fundamentaly templating systems.
Admin
I agree. In my opinion, the WTF of this style of template system is ASP's and VBScript's own deficiencies in processing strings. This type of system has been in used to build dynamic pages for years, with perl, php and other frameworks; in fact, the original PHP worked by doing this same thing before it became a "real" scripting language. Seems to me that the developers of the system were probably either used to working in other platforms, or like mentioned above, planning for multi-platform deployment.
The fact that ASP is so inefficient in working with files and string manipulations -- while designed to do precisely this -- does not make it a WTF in itself. Least in comparisson to other classic WTF's posted on this site.
-dZ.
Admin
Perhaps the developers do not want to give unnecessary access to the page designers, and instead offer them static templates for them to implement their designs and therefore keep all executable code separate. This is a very well known template system used for years.
dZ.
Admin
What if you do not want the site designers to have access to executable code, or to potentially modify or damage delicate code?
dZ.
Admin
They should use an FSA to replace all the tags, not multiple calls to replace. They are traversing the entire webpage 4 times to replace a few tags. Using an FSA they could go though it one time and get all of them. The WTF here is that people grow up on things like VB and never learn parser design or the skills you need to be a real programmer.
Admin
The implementation might be wtf, but the idea itself isn't.
My approach would be to implement this process the stuff into the variables variables and then use SSI-directive to include the HTML-file with embedded <%=var %> ASP tags to the file.
Admin
I know the feeling! I just went from asp.net to vb6 :(
Admin
<FONT face=Arial size=2>Implementation bad, concept good.</FONT>
<FONT face=Arial size=2>Yes, ASP/PHP/et.al. are templating systems - but the problem is they are limited. ASP combines dynamic logic and static content into a single template. Many real world applications need to make a further distinction, and split dynamic logic from dynamic content templates. To get this dynamic-to-dynamic mapping to work requires a metatemplating system. As others have posted, this is neither uncommon nor in any way "bad."</FONT>
<FONT face=Arial size=2>One of the most entertaining web applications I ever built was based on metatemplating. Each page was defined as a series of segments, and some segments could be given parameters. The top level design for the site was quite literally a set of flat-text segment lists. A segment could be used to display static content loaded from another location, or dynamic content (news, product details, etc.) - the behavior of a segment was determined by the parameters given. The format was very simple and let the (highly technology-illiterate) staff rearrange the site as they desired. Underneath this, each segment was built up of fragments. Each fragment was linked to a snippet of HTML that would eventually be fed to the browser. A segment definition could embed information using inlined tags that were essentially escape codes. This made segments easy to edit for the occasional person who understood web design (at a high level). The really hardcore (i.e. me, in most cases) could edit the raw HTML to change the fundamental look of the site. Of course all of this was also connected to a potent CSS system, so aesthetic changes could be made easily by anyone with a good grasp of CSS.</FONT>
<FONT face=Arial size=2>The whole mess was "compiled" at write time when the templates where changed, and the resulting data was cached in various forms for fast access. When a user requested a page, a simple engine would assemble the entire content from cached HTML snippets and dynamic data, and output it to the browser. It was nearly as fast as hardcoding all of the HTML, was infinitely more flexible and maintainable by the staff, and it allowed people with a wide range of skill levels to adjust the site without any security or performance risks involved.</FONT>
Admin
I'm going to say the daily WTF is the ad on the sidebar saying "Smart admins use Microsoft IIS". I haven't gotten a good laugh like that for a long time.
Admin
I"m uncertain what you mean by a need to seperate "dynamic content" from "dynamic logic". If you are talking about seperating presentation or business logic (database queries, if/then/loop statements to show or hide content, etc) from presentation content (HTML, text, data to be displayed) again, this isn't too hard to implement using standard ASP. I will readily admit that it takes a little discipline, and ASP/PHP/JSP and similar scripting languages DO seem to encourage blending business/presentation logic with the content and layout aspects of the application. However, this is no reason to reinvent the wheel and create your own templating system on top of another. You can implement the entire thing using standard ASP. You just have to be careful to make this seperation yourself. With the advent of ASP.NET, its much easier to make this seperation by default. If this is NOT what you're talking about, please explain.
Also, what you are describing sounds a lot like a CMS, which is readily available in both commerical and open source versions, and isn't that difficult to build if needed. There is no need to built the "fragments" or "segments" using a seperate kind of markup. Its just not that hard to layer things appropriately for skinning, templating, etc. Parsing text files to reinvent the wheel sounds kind of kooky to me. If you're users are technically illiterate, why not create your "templates" as ASP files, but with minimal logic in them, perhaps by only allowing rendering expressions such as <%= customerAddress %>? How is it more advantageous to make your own parsing system with @@ something @@ or tags or whatever? Maybe we're saying the same thing, that its ok to seperate things skinning, markup, layout, content, logic, etc and that only the implementation is bad. But it SOUNDS like you're saying its actually ok to recreate the parsing mechanism which ASP has natively, because SOMEHOW that will make it easier for users to edit content and HTML templates.
Admin
<FONT face=Verdana size=1>I'm not talking about separating logic and content - that's the first level of distinction, which ASP/PHP/etc. handles very nicely. What I'm talking about is separating logic from content and also from the way the content is generated. In my case, the client wanted a site that they could redesign on a regular basis without touching the database access and shopping cart code. I don't mean redesign like changing the fonts and colors - that's trivial with CSS - but changing the actual physical layout and structure of pages.
Web applications are not really my forte, but I'd be shocked to learn of a technique for allowing that kind of redesign on-the-fly that didn't involve a templating system sitting on top of ASP/what have you. This was in the olden days before ASP.Net (which I have no experience with, having moved on to much better projects since then) and for the situation at the time I am not aware to this day of any approach that would have been better.
The segments were build of simple blocks like:
WelcomeBanner
ProductList CurrentPromo
ProductList MensShoes
ShoppingCartBar
Footer
If it isn't blindingly obvious how that's easier for a marketroid to work with than an ASP script, I deeply envy your sheltered career and the wonderful people you work with [;)]</FONT>
<FONT face=Verdana size=1>No wheels were reinvented in the making of this film - at least not any wheels which existed at the time.</FONT>
Admin
I think you've identified the REAL problem. I would bet that STRINGS are immutable, even in ASP. So each of those calls to REPLACE is just creating yet another HUGE string that must be allocated and ultimately collected.
Admin
Good one, Dave. These fine people should have read Rule One of VBScript, for sure. Don't try and manipulate Strings unless you have a web farm.
On the other hand, maybe they should get partial credit for inventing the codebehind model ...
S
http://www.sempf.net/blog/