The Siren Song of SSI

I needed to get a small content website up and running for a project a friend of mine and I are working on, and we started discussing what to use; i.e. raw HTML, a web framework, a CMS, or something else. I have experience on ASP, IIS, and Windows Server using my own mini ASP-based framework but I’ve got very little experience on our chosen deployment platform and hence am not productive on any of the common platforms in use on Linux. So my friend, thinking I was unfamiliar with SSI suggested that I just use SSI with HTML, to which I replied:

Oh, I’ve done that in the past; I built up a pretty robust set of SSI templates, but it took me a while to get the feel of the language and make it all work. So I don’t want to reinvent the wheel.

To which he replied:

But SSI is beautifully simple. You write a couple lines for your header, say, then throw it in a file. Then you write a page containing whatever content you want, with a call to include that header file at the top of the document. Then…well, that’s it. It takes no time to "learn", requires no programming, and seems perfectly sufficient for what you want.

Sigh.

But as I was thinking about how to reply, I realized that my reply would make an interesting blog post. So here it is; I’m going to build a simple website and use SSI to eliminate all the inevitable duplication. Let’s see how it goes.

First thing is to create a header and a footer (please forgive the lack of DOCTYPE and of obvious things we’d add as I’m trying to make my examples easy to follow. And the omission of DOCTYPE and other specifics won’t affect my main points anyway):

header.inc:

<html><body>

footer.inc:

</body></html>

Next step is to create a template for all our web pages; we’ll start by creating the home page:

index.html:

<!-- include virtual="/header.inc" -->
The web page's HTML content would go here
<!-- include virtual="/footer.inc" -->

So far, so good.  Next let’s add a menu to header.inc that will be on all pages in the website. We’ll need to use CSS styling for the menu, so we’ll add a LINK element allowing us to bring in CSS:

header.inc:

<html>
<head>
<link rel="stylesheet" type="text/css" href="/style.css" mce_href="/style.css">
<body>
<ul id="menu">
<li><a href-"/">Home</a></li><li><a href-"/products/">Products</a></li>
<li><a href-"/downloads/">Downloads</a></li>
<li><a href-"/store/">Purchase</a></li>
<li><a href-"/faq/">FAQ</a></li>
<li><a href-"/about/">About</a></li>
<li><a href-"/contact/">Contact Us</a></li>
<ul>

Great! Now let’s start building out our website. Let’s add three, five, ten, twenty five web pages, and more. These SSI are pretty nice, no?

But wait. Someone mentions to us that none of our web pages have titles. Bummer; titles are really important for usability, and super important for search engine optimization. Oops.

So how are we going to fix this? Hmm, looks like we need to split header.inc into two parts and add a <title> element spanning the two.

header1.inc:

<html>
<head>
<link rel="stylesheet" type="text/css" href="/style.css" mce_href="/style.css">
<title>

header2.inc:

</title>
<body>
<ul id="menu">
<li><a href-"/">Home</a></li>
<li><a href-"/products/">Products</a></li>
<li><a href-"/downloads/">Downloads</a></li>
<li><a href-"/store/">Purchase</a></li>
<li><a href-"/faq/">FAQ</a></li>
<li><a href-"/about/">About</a></li>
<li><a href-"/contact/">Contact Us</a></li>
<ul>

Well that’s done, but now we need to go and fixup all those three, five, ten, or twenty five odd web pages, right? I guess it’s going to look something like this:

<!-- include virtual="/header1.inc" -->
Page title goes here
<!-- include virtual="/header2.inc" -->
The web page's HTML content would go here
<!-- include virtual="/footer.inc" -->

I guess that wasn’t too bad. But wait. It becomes clear some of our pages need to omit the menu. Hmm. I guess we need to split the menu out of header2.inc and into it’s own file.

header2.inc:

</title>
<body>

menu.inc:

<ul id="menu">
<li><a href-"/">Home</a></li>
<li><a href-"/products/">Products</a></li>
<li><a href-"/downloads/">Downloads</a></li>
<li><a href-"/store/">Purchase</a></li>
<li><a href-"/faq/">FAQ</a></li>
<li><a href-"/about/">About</a></li>
<li><a href-"/contact/">Contact Us</a></li>
<ul>

I guess that means NOW we need to revisit those three, five, ten, or twenty five odd web pages AGAIN, right? They should probably all look something like this:

<!-- include virtual="/header1.inc" -->
Page title goes here
<!-- include virtual="/header2.inc" -->
<!-- include virtual="/menu.inc" -->
The web page's HTML content would go here
<!-- include virtual="/footer.inc" -->

Sheesh! What’s with this SSI concept? I thought it was suppose to eliminate the need to change every web page file every time we needed to modify a site’s architecture. Why then do we have to keep making all these sweeping changes?

What’s more, those web pages are really hard to read, what with all the cryptic SSI syntax obscuring the logic in the page.

So I’ve shown two simple examples of where a web site rearchitecture requires refactoring of (almost) all of the web pages in a site when SSI is used naively. Yet I could go on. And on. And on. And on. The problem is that you can’t easily parameterize SSI files (easily) and then capture those parameters in pure HTML. And even if you could, you’d be programming, and you’d have to learn how to do it! We’re going full circle, you know?

Which brings me to a question: "Are Server-Side Includes Bad?" And the answer is: "Of course not, but you do need to know how to use Server-Side Includes properly, and they are really only beneficial when paired with a server-side scripting language[1]." I’ve actually used SSI on every web project I’ve every worked on, save the very first. But I have a rule of thumb when using SSI: I generally only use one SSI per web page file, and I include that SSI at the top of the web page file.  My single include file actually includes my library of scripting functions and is a mini-framework of sorts.

So that you can see a good way to use SSI, I’ll show a quick example. The majority of my web experience has been on programming ASP websites so I’ll use ASP and VBScript syntax. For those not familiar, ASP/VBScript is relatively similar to programming in PHP albeit PHP has moved far beyond the capabilities of ASP since Microsoft dropped ASP and went on to focus its efforts on that that abomination they call ASP.NET[2].

default.asp:

<%
   '--Filname: /default.asp
%>
<!-- include virtual="/sitedef.inc" -->
<%

With page
   .Title= "Page title goes here"
   .Show()
End With

Sub PageContent
%>
The web page's HTML content would go here
<%
End Sub
%>

For completion, I’ll so a tiny subset of a workable sitedef.inc as showing and explaining the entire thing would be way out of scope for this article:

sitedef.inc:

<%
   '--Filname: /sitedef.inc
   Option Explicit
%>
<!-- include virtual="/funclib1.inc" -->
<!-- include virtual="/funclib2.inc" -->
<!-- include virtual="/funclib3.inc" -->
<!-- include virtual="/and-so-on.inc" -->
<%
Dim pageSet page= New PageClass
Class PageClass
   ...
End Class
%>

A quick rundown of sitedef.inc shows the first line being a comment to document the file name for print-outs, etc.. Next is the directive Option Explicit that turns on error reporting for undeclared variables.

Then you can see several times the use of embedded SSI to bring in other files from my VBScript library of functionality. As a note, at first I thought that incluing everything even if it wasn’t needed would cause poor performance but I later realized everything was cached and there really were no performance problems at all. At least this is true on  ASP and IIS; I can’t yet speak for PHP or other languages on Linux and Apache.

Then we have the declaration of the "page" variable which you saw used in default.asp above, the creation of a new instance of the page variable, and the skeleton declaration of the "PageClass" class. Note that VBScript is case insensitive and won’t let you reuse symbols so the "page" variable and a class named just "Page" would have clashed hence the use of the suffix "Class" on "PageClass."

With sitedef.inc we can now create our three, five, ten, twenty five, or more web pages using the template shown for default.asp and (almost) never have to modify them when we refactor the code in our server-side includes. Much more maintainable than SSI and HTML alone. Which brings me back to my friend’s statement, a portion of which I repeat below:

But it takes no time to "learn", requires no programming, and seems perfectly sufficient for what you want.

If you are going to use SSI and you want it to be maintainable, it actually does require you learn server-side programming. Maybe we are only talking about three or five web pages for the project today, but we all know that things change quickly and before you know it, there will be fifty web pages or more.

And who wants to architect a website such that you have to rearchitecture as soon as it grows? Not me. :)

Footnotes

  1. When I say server-side scripting I’m using the term "scripting" liberally to refer to any server-side programming solution including platforms that use Java and C#.
  2. Please don’t misquote me; it’s not the .NET framework, .NET languages, and the common language runtime I dislike; it’s the ASP.NET web framework that I think is misguided.

 

Can Microsoft’s Developer Division Compete Moving Forward?

I’ve been planning to blog about this for some time but just haven’t gotten to it. Well here goes…


Contents

Note: The day after I posted this I decided to add headings to make the argument easier to follow.


Is Microsoft’s Approach Failing?

I believe Microsoft legacy processes simply cannot react fast enough to the innovation happening in the open source arena on the language and web framework front. Microsoft’s developer division typically offers three-year version cycles where they first architect Visual Studio and related technologies in a vacuum. In recent years they’ve even thrown out alphas and betas to the Microsoft faithful to get feedback which, and thankfully they’ve used a lot of that feedback. But that approach just isn’t working in the market anymore. When the release cycles of
scripting languages frameworks like Ruby On Rails and Django and CMS platforms such as Drupal are sometimes as little as a few months, it’s really hard to wait around for the next version of Visual Studio.

After Ten Years; Too Little, Too Late?

It would be different if Microsoft’s developer technologies provided at least 95 percentile of what’s needed by work-a-day developers on a daily basis, but they don’t. Case in point is we still don’t have the ability to do complete URL Rewriting for ASP.NET on IIS even though Apache has had mod_rewrite for years. Looking back, how many years of massively duplicated developer effort in the field did it take befor Microsoft finally provided a login module and a method of managing site-wide templates?!? (i.e. “MasterPages”) Oh, about a decade from when they first released Active Server Pages.

Providing Solutions Frequently Just Not a Priority

It’s not just that Microsoft’s developer division takes too long to offer new solutions to recurring needs; it is that they place such low priority on providing those solutions. Three year development cycles testify to that fact, especially when you consider it takes Microsoft many releases to address fundamental needs. The guys on the product management teams at Microsoft are really smart people, but they often can’t see how much trouble they cause people in the field by their decisions. They see the world of creating Visual Studio, but they don’t see the world of using Visual Studio to develop software.

Core “Real World” Problems Not Addressed

What’s more, Microsoft architects its developer products in a vacuum; they don’t use them to solve “real world” problems. Sure, they may use them internally for developing productsbut when does the average developer’s project look like product development at Microsoft? They often create excellent software but software that either doesn’t solve real world problems or does so in a totally over-engineered manner. While running Xtras I watched many a developer launch a 3rd party component business because they had identified a need while working on a real world project. However, once they saw small success as a vendor they started developing, designing, and even envisioning new products in a vacuum. And often those products either didn’t address real world needs or did so in a really unnatural manner.

Microsoft is a much worse example of this. Their saving grace thus far has been market share and financial resources to brute force their products into the market, and many of the faithful won’t even look at other s offerings to understand why some of Microsoft’s offerings so miss the mark. I know, until recently I was one of them.

Values “Sugar”-Free Over Productivity

And Microsoft’s product managers often dismiss feature requests that would make development a LOT easier as simply being “syntactic sugar. For example, one such dismissed feature request I made years ago was for simplified property references in VB.NET. I wanted a syntax that would allow a developer to implement a single-line syntax for specifying properties you didn’t need anything special, something like:

1. Property Foo Into _Foo

Instead of nine lines of:

1. Private _Foo
2. Property Foo
3.    Get
4.       Return _Foo
5.    End Get
6.    Set(ByVal value)
7.       _Foo= value
8.    End Set
9. End Property

That would have reduced the number of lines of VB.NET code by probably half an order of magnitude. But they just weren’t interested in it because it “bloated the language and otherwise had no value” (I am paraphrasing from memory.)

Focuses on Details, NOT the Big Picture

Even more, I advocated an advanced scripting language that would be a lot like today’s “in-vogue” scripting languages. I called my proposal VBScript.NET. But then my suggestions were dismissed for esoteric reasons and I was told that Top Minds Are Working On It! (Well, evidently not, or so many developers wouldn’t be moving to PHP, Ruby, and Python.) Microsoft’s culture is to argue semantics when reality doesn’t match their world view, and they are blissfully willing to ignore the pain that continues to exist.

Revolutionary Paths Are Often Dead-Ends

What’s more, probably because of its financial resources and a hubris that comes from being the industry leader, Microsoft has a bad habit of creating huge revolutionary jumps instead of small evolutionary steps. Rather than always creating lots of little independent layers of loosely coupled components, each with it’s own independent functionality, documentation, and rationale for existence, Microsoft often builds monolithically complex solutions where the individual components are highly coupled, not documented, hidden beneath the covers, and frankly with functionality that has not been fleshed out well had it had to be developed to stand on its own. This creates bloated and fragile systems that are often extremely hard to debug and for which there is no passionate community of supporters surrounding it.

ASP.NET: Wrong Medium, Wrong Model

ASP.NET is a perfect example of many of these problems. Rather than study the web and realize it was a violently different platform than desktop apps, Microsoft chose to shoehorn an event model onto the web and use a page-oriented implementation. Not only did they get the medium wrong, they also got the model wrong. And this decision resulted in an outrageously complex pipeline processing model with tons of code that is hard to debug or even understand, and that requires lots of high end developers to figure it out and repeatedly explain to newbies what they need to do just be able to do some of the simplest things, things that are brain-dead easy in PHP for example.
But hundreds of thousands of Microsoft-centric developers just trudged along and accepted it as the next best thing because Microsoft said so. And for a short time, I was one of those true believers.

ASP.NET: Exceptional Engineering, Answers Wrong Questions

Now, however, even many Microsoft developers are starting to see ASP.NET for what it really is: An exceptionally engineering product that answers the Wrong Questions. Former ASP.NET developers are moving to the platforms I mentioned earlier (Ruby on Rails, Django, and Drupal) simply because those platforms offered developers the syntactic sugar they crave, and because the developers of those platforms focused on solving pain because the pain they were solving was their own.

Open-Source: Answering the Right Questions, Rapidly

Open-Source development by nature results in lots of little independent layers, and there are communities that sprouted or are sprouting to support each of those independent layers. Each of those layers has had an opportunity to be fleshed out, and by comparison it shows. How can something like Open-Source PHP on Apache take on mighty Microsoft’s ASP.NET and IIS, and win? Because they answer the right questions, and they did so in far less than a decade.

Is there any hope for Microsoft’s Developer Division?

Which brings me back to the original question:


Can Microsoft’s Developer Division Compete Moving Forward?

Frankly, though I really like the .NET Framework and hope I’m wrong, I’m completely skeptical.

 

Quick Reference for Web Developers


LOCALHOST80.COM - Resource for Web Developers

I just noticed today in my blog logs that I’ve been getting referrals to my Well Designed URLs blog post from a website called LOCALHOST80.com.

I checked it out and it’s a pretty nice list of resources on a whole ranges of topics of interest to web developers, listed below. It appears they handpicked some of the best related sites and best articles on each of the topics I listed below to keep you from having to weed through them yourself. And I really like their navigation too; everything on one page for quick scannability, but you can also click the section title to drill down where they show the site domain for each of the links. And they use nice URLs too. :)

Highly Recommended!

  • 404 Handling
  • Creativity
  • Javascript
  • SEO
  • URLs
  • Adsense
  • CSS
  • mod_rewrite
  • Startups
  • Usability
  • AJAX
  • CSS Layouts
  • MySQL
  • Style and Design
  • Web Hosting
  • Blogging
  • Domain Names
  • PHP
  • Tech News
  • Web Icons
  • Color
  • Forums
  • Robots
  • Traffic
  • Web Writing
  •  
  • HTML
  •  
  • Tyopgraphy
  •