| « The Storage Warehouse, The Most Ethical, and The Customizer | 19999 Below » |
Imagine yourself as an eager, young developer. After many long months of self-study, you’ve carefully honed your craft and have skillfully mastered virtually all development technologies from enterprisey to hipster. Your twelve-page résumé could land you a job anywhere, and as it would happen, the job you decided to take was at a highfalutin consultancy filled with like-minded developers who were almost as skilled as you.
You and you cohorts could build anything. Literally, anything: a software cure for cancer; a software cure engine that could dynamically load cure plug-ins at runtime to cure anything; or even a software engine factory that could dynamically create engines that could dynamically load plug-ins that could do anything.
And as it so happened, your virtually unbounded skillset was desperately needed to solve an otherwise unsolvable problem: build skechers.com. The requirements for the shoe company’s website were mind-bogglingly complex: retrieve product information from some enterprisey ERP system, format it prettily on the web, and let people place orders online.
Although no one in the history of software development had ever undertaken a project of such scale, you were prepared for anything. In fact, even before hearing what the website would be for, you had already spec’d-out the architecture: use XML-based XSL to transform server-generated XML into XHTML and JavaScript.
Hopefully now you can appreciate the mindset that the developer(s) of Skechers’ website must have had. Their masterpiece can be seen by a simple view-source of skechers.com:
That’s the XML data sent by the server when visiting http://skechers.com/. Your browser then spends a bit of time transforming into HTML and JavaScript using the following XSL:
While the idea of building a website like this in XML and then transforming it using XSL is absurd in and of itself, digging through the code is a treasure trove of WTF. I’m sure there are at least three levels of Hell that are more pleasant than having to maintain this JavaScript-generating XSL code:
<script type="text/javascript">
var skxProduct = {}; var skxStyle = '<xsl:value-of select="$style/@code"/>';
<xsl:for-each select="$style/product">
skxProduct['<xsl:value-of select="@color"/>'] = {
color: '<xsl:value-of select="@primary-color"/><xsl:if test="@secondary-color">
/ <xsl:value-of select="@secondary-color"/>
</xsl:if>',
images: [
<xsl:for-each select="media">
<xsl:sort data-type="number" select="@view"/>
<xsl:if test="position() < 7">
'<xsl:value-of select="@image"/>'
<xsl:if test="position() != 7">,</xsl:if>
</xsl:if>
</xsl:for-each>
],
inventory: [
<xsl:for-each select="sku">
<xsl:sort data-type="number" select="@pos"/>
{
size: '<xsl:value-of select="@size"/>',
<xsl:if test="@type">
type: '<xsl:value-of select="@type"/>',
</xsl:if>
stock: '<xsl:value-of select="@in-stock"/>',
<xsl:if test="@disc">
disc: '<xsl:value-of select="@disc"/>',
</xsl:if>
price: '<xsl:value-of select="@price"/>',
upc: '<xsl:value-of select="@upc"/>'
}
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
]
};
</xsl:for-each>
</script>
I shudder at the thought of how labyrinthine the server-side code generating this must be.
I’ve preserved (well, after some indentation/formatting) some of the files for posterity. Just right-click download, then view in your favorite text editor for best experience.
I’m sure there’s plenty more fun examples to be found at all levels of skechers.com; feel free to share them in the comments or send them to me if you think they’d deserve an article of their own.
|
Ha! This is great-- I've been mentioned on TheDailyWTF, that's going to the very top of my resume. I'm the manager of the web team at Skechers, and we've all been having a great time reading the thread and the comments. Thank you, everyone, this is a great way to start a Friday. I would say that both the "wtf this is horrible!" and "no, this is great!" sides of the argument have great, valid points.
I can't give extremely detailed explanations of our code for obvious reasons, but here's a quick FAQ. WTF are you insane?!? XSLT is (maintenance nightmare|slow|hacky|terrible language)! You're right! Writing the XSLT took a good chunk of time, and we had to do a lot of workarounds to get the resulting output the way we wanted it to look. Whenever the XSLT wasn't well-formed, trying to debug it was a mess of biblical proportions. Luckily, maintenance of the XSLT isn't that bad; both the XSLT and the structure of the XML rarely change. But here's the great thing about XSLT-- it's cacheable on your browser. Instead of browsing from page to page to page, each time getting 25k+ of html, we can frontload a lot of that by having you download the XSLT. Once you've downloaded the file once, you have the layout for the entire site already cached, and the next page you go to is 2k of XML. ...but (JQuery Templates|Hogan|Backbone|etc)! You're absolutely right; unfortunately none of those were really mature enough at the time we started developing the site. My original thought was-- your desktop machine, and very quickly your phone, have just as much CPU cycles available as a commodity server. Why not shift as many cycles to the client as we can while still making it a relatively fast experience? ...but the browser support sucks! It's funny, IE7 and IE8 actually have better support for XSLT transformations than Firefox does. You want to see one of the crappiest browser bugs in the world? https://bugzilla.mozilla.org/show_bug.cgi?id=98168 was opened in _2001_. <xsl:text disable-output-escaping="yes"> doesn't actually work in Firefox. WTF?!? Anyways, the reason we run the transform on the server (trivial) for IE users is because IE9 actually broke their XML/XSLT transform engine, but only when you're visiting the page from a 304 redirect. That wasn't a fun bug to find. WHY, man, WHY?!? This is just insane! Is it any more insane than hunting through Struts code, or JSF, etc etc? Now, both our front-end CSS/Javascript developers, and back-end Java (now Scala) coders understand Xpath now, so we don't run into the "I don't want to touch that Velocity template" problem. How'd you come up with this idea, anyways? We were playing around with the RESTEasy framework. One of the great things about RESTEasy is that it allows you, via JAXB, to marshal and unmarshal POJOs to XML/JSON extremely easily; like, one @Produces("application/xml") annotation in your POJO and that's all you have to do. Well, hell, we have REST methods for obtaining catalog information, why can't we just output an entire page the same way? Similarly, I saw a pseudo-trolling comment about the enterprisey ERP system returning XML. That's actually very close! We take the XML output from our implementation of Endeca (essentially Solr on steroids) and just slam it to the browser. The amount of server-side code to run the browsing experience on the site (a pseudo controller, if you want to talk MVC pattern) is, basically, one class of about 100 LOC, most of which is web service calls. There was some comment about the Wow Armoury earlier on. I used to work for Vivendi, when we owned Blizzard (the plot thickens...). So while I didn't write the Armoury, I did try to keep up with the web technologies that they were using. I thought it was a brilliant idea, but that they didn't go far enough. Far-expires, plus cacheable view layer, plus very small subsequent http payloads, what's not to love about that? Sorry. This is still WTF. Given today's technology and how much Javascript templates have matured, you're probably right. As with any project, we've seen our share of development pain, and there's a lot of spaghetti XSLT I'm sure. It works really well for us, though, and turned what used to be an extremely slow JSF-based mess into a pretty fast browsing experience. What we're looking at now are technologies like Hogan, CouchDB, Bootstrap, Backbone, and the Play Framework (specifically the 2.0 beta). We've adopted Scala for all new code, and there are some really exciting technologies available now that really weren't when we created the site, so yeah, maybe the next version of skechers.com is just one very small HTML template that gets served up no matter which page you go to. Thanks again, everyone, this is great. It's hilarious to be mentioned on the site. |
| « The Storage Warehouse, The Most Ethical, and The Customizer | 19999 Below » |