Web Development - The Line Between Code and Content?
markmcb asks: "I help design a LAMP web site and I'm constantly plagued by trying to decide on what level should I separate functional code and markup. Depending on what you read, some say embedding HTML in your PHP scripts [or Perl, or Java, or Ruby, or Python, etc] is bad while others say it's no big deal. However, seldom are any practical applications of such code cited. How is your site built? Do you mix HTML with your code? If not, how do you overcome the simple and easy method of doing so? Lastly, what performance gains/losses have you noticed by doing so?"
I taught myself to script perl a few years ago, and no one told me one way or the other. So I decided to embed the html a bit in the code, and I really can't think of a good reason why it would be bad to mix the html, unless its for the sake of the clarity of the code.
I had to implement an intranet site using zope/plone which seemed to prefer a separation, but I saw no reason for it, except the obvious use of templates, and just went ahead business as usual. So i think this is just a matter of preference.
I personally find it easier to integrate (X)HTML with my PHP. When I've needed to store them seperately, though, I've seen no performance differences and I highly doubt that there would be anything significant. PHP is fast.
Then again, I've never used Perl, Python, or Ruby for web development. Perhaps they're different.
ROMANES EUNT DOMUS
Seperated: If you want something modular and scalable (but slower)
Embedded: If you want something faster and easy to write (but not as scalable)
MABASPLOOM!
Business logic would use the driver API, making data requests that were resource-neutral. In other words, the business logic didn't care where the data came from, only that it got what it asked for. Different business functions were isolated, and each presented its own API to the applications. The APIs themselves conformed to a specification. That way, apps written by different developers could perform the same business functions without recoding everything. The applications made requests of the business logic according to the spec, then presented the results to the clients for formatting (web, RSS, PDF, whatever). Uniform data structures were used throughout.
You may not need that level of sophistication, but it sure as heck helped us prototype, isolate employee functions and skills, etc etc. It allowed us to run multiple OSes (Windows, Linux, Solaris) and multiple languages (.NET, VB, and Java) together seamlessly. It also helped when doing architecture, since it forced us to think about what a particular piece of code was really doing. Under our scheme, PHP would be layer 4, and HTML layer 5, so we would separate them. You could just as easily use PHP to generate XML, for example.
This post expresses my opinion, not that of my employer. And yes, IAAL.
For the project we're working on, we are combining several bits of XML data and using an XSL template to display the HTML. This helps seperate the data from the markup. That way, your PHP or Perl would be responsible for getting the data (in our case, XML from web service calls and XML config files), handling user input, and running the XML/XSL transform. This solution works for us because we can dynamically call different XSL templates depending on the skin we want to display to the user, but the data always coming from the config files and web service calls always stays the same and doesn't care about the markup. The downside here is that this method requires that any database calls or business logic is returning XML. It works great for us, since we're moving all of our logic into a web service layer, and the services always return XML. This might require more architectural work than is necessary in your case, but if the web app is big enough or complicated enough, this method provides some great decoupling.
People will always tell you to "separate logic from presentation" and that is good advice - to a certain extent. I don't think that this is correct all the time, however, because it is not a correct statement per se because the two cannot always be separated. However, they usually can and usually are, and web pages are a good example of this. But what does "separate" mean? Does it mean physically moving your presentation to another file, generating it, etc.? There are many different ways, all of which work best in certain situations.
Here's what you should worry about instead:
1) Is the program readable?
2) Can you easily make changes in the program without having to change too many other parts of it?
3) Are you having to rewrite the same code too much?
Those are some pretty basic computer programming design concepts, and if you apply those, you'll find that the answer should be pretty clear. Just keep everything clean and life will be happier.
Did you ever notice that *nix doesn't even cover Linux?
For me, I try to look at it from a practical perspective. I don't separate code & content because of some idealogical reason (well, OK, I do... but I use the following thinking to help me determine how to implement it). Instead, I separate code & content because I know that inevitably, some non-geek is going to need to change the look & feel. And I want to expose the least amount of code possible, so that they can do the least amount of damage.
Therefore, here is how that plays out. First, I create everything procedurally, one huge page, HTML & PHP & CSS & JavaScript all mixed in together. Then, once I am no longer iterating through revisions frequently, I start to pull out the non-HTML bits. The CSS & JavaScipt are usually the first to go, with HTML tags to pull that code back in. The PHP gets two run-throughs. First, I move repetitive code into functions (I don't do a lot of OOP). Second, I break the PHP code into logical include files. So for example, I typically have a handful of libraries that set up the page. Those go into setup.php (database connections, handling the on/off issue with addslashes, and so on). Anything that is page-specific goes into another include file. What I'm left with is HTML with a few short PHP echo statements. For example, something like this might appear right after the BODY tag:
...just to output any status messages that my code generated. And then something like this might appear anywhere I had a PHP variable to drop into the page:
...and so on. The basic gist is that I offload the code into include files, and those files generate variables that contain whatever content is needed for display. The HTML page itself merely has some PHP include statements and a few PHP variables sprinkled throughout the page. By doing this, some random artsy-type or client who noodles with the HTML can usually still revise things without damage. They usually understand what they're seeing. And that's all I'm aiming for. I don't try to go any more hardcore than that -- no abstraction layers, etc. Oh, also, I try to avoid having more than 1 level of included files. In other words, my included PHP code does not use include() to pull in even more files. The nesting on some projects just drove me a bit nutty, so I try to only go 1 level deep. I rarely keep to it, but it's an ideal. :)
My Greasemonkey scripts for Digg &
BTW, if you're looking for a nice framework for Java web development I highly recommend Stripes. I stumbled across it last year and it is much nicer to use than Struts!
My web pages break down as such...
I build a content page using HTML and CSS. No tables unless it is to display data. Trying to make it as clean as possible.
I then move any HTML that repeats throughout the site (usually header and footer) into includes.
I then create the functions that will build my menus and populate the content. I put these into classes.
Call the class in the header include. Call the functions where apporpriate, and viola! I have five documents: CSS file, header, footer, class/function file, and then all the other pieces that are left in the original HTML document. Usually I will end up with a six document that has all the javascript, if necessary.
Technically, you could build the header and footer to be functions, and cut down to two documents, but I have found that to be a bit of overkill, as usually the stuff in these are not very dynamic.
Now, there may be some HTML in my functions. After all, if the function is going to put out HTML, then it probably needs HTML in it. But I try not to build any function-type code into the HTML. The nice thing about this set up is the core HTML document needs virtually no maintenance, and can be used for every single content page, assuming you are passing which page you need to the appropriate function.
The world moves for love. It kneels before it in awe.
The Smarty template engine offers a flexible and powerful tool for PHP developers.
Where/when I choose to use templates versus embedded code depends on where in a web application the page is viewed. For example, I would use templates on the frontend of complicated sites that require pages to have different page displays, such as a newspaper. A regular news story may display differently from an editorial or op/ed piece. I also think the frontend of a website should be flexible because redesigns happen often.
But I embed HTML on the backend because the admin control panels are more functional than asthetic. Also, the backend pages are more critical than frontend pages and I want admin pages to be self-contained (not reliant on templates that may or may not work or contain errors).
If a user screws up a frontend template, the worst thing that can happen is that the page is unavailable until fixed. But if a user screws up a backend/admin page template, you're can't even access the backend to fix the problem.
Separation is good. I can trot out the old "let coders code and designers design," but I often do both, and there are other benefits. You should look at model view controller. You don't have to drink all the MVC kool-aid to get good ideas from it.
Wonder why Slashdot looks like ass? I've spent a lot of time hacking Slash source and, until their recent refactors (and maybe even now) there was markup everywhere in the Perl. It made a redesign impossible without actually writing code, and possible introducing bugs.
MVC says that the presentation layer should be separate from the rest of the application. If you think about it, that's the same idea as keeping presentation (e.g. CSS) separate from content (e.g. XHTML). That idea has clearly won out.
Performance can be a factor for smaller systems, but if you cache your templates or have them precompiled (e.g. JSP) it helps. Also, programmer efficiency is almost always more important than code efficiency. Keeping the controller code and the view separate allows you to find and fix code bugs without wading through all sorts of presentation logic. Who cares about how a nested list is constructed in XHTML when you're trying to find out why your app is barfing?
This isn't as much "normalization" as it is "don't take so many drugs when you're designing tables."
I use the Model View Controller design pattern for UIs. I would suggest you do the same. The View is your pretty HTML stuff, the Model is the crap you want to display, and the Controller is where the code goes to fetch that content and save user input.
"Avoid employing unlucky people - throw half of the pile of CVs in the bin without reading them." -- David Brent
The more proficient you are in web-based languages, the easier it is to separate stuff:
At the bottom you just have a mashup of PHP and HTML using one file per page, with the odd file include for a header or whatever. I started out doing PHP by trying to fix something written this way; it's an easy way of learning what to avoid.
One up from that is separating the layout into CSS, which is pretty obvious.
From there you can move the logic behind the dynamic content into separate files, by using includes or classes or whatever. This is the most common way from what I've seen.
If you want to take it to extremes, then you can get XSLT involved. Probably overkill for a lot of things since it involves juggling 4 languages at once, but I haven't tried it so I can't say whether it's worth it.
I use eGroupWare which was forked from phpGroupWare. Both of these have a utility called "eTemplates" which does all the HTML for you. Try it, you'll like it, productivity is awesome, something like several pages of working, tested, debugged, HTML per day.
If you're using PHP, there is an excellent library called Smarty. It makes using templates very easy.
With Smarty you can do something like this:
template.tpl:
For your PHP it's simply:
With this I can easily change the layout later. No messing around with trying to find all the embedded html.
Smarty also allows you to include other templates from within the template. There are tons of features in Smarty, it greatly improves my productivity.
"It ain't a war against drugs.it's a war against personal freedom" --Bill Hicks
I'm part of a student-run group at my high school that is in charge of developing and maintaining our school's website, servers, and other infrastructure. This past fall, we began redoing our school's site which, up until that point, was a mish-mash of ASP and HTML. The code was ridiculous - in fact, if we ever get bored, we like to look at the old code for a good laugh. However, we put a lot of thought into different techs that could be used to redo the site. We considered PHP, ASP, Ruby-on-Rails, Python, and different Java solutions. In the end, we chose Apache Struts - it offers an incredible level of abstraction, but it works wonders for development.
Struts works by seperating business logic, actions, and markup. If, in the future, we decide we want to ditch Struts, we can keep the BL and the markup and throw out the actions for whatever we choose to replace it with.
More importantly, however, this allows us to keep code and markup seperate, allowing the backend team to tweak the code as they see fit and the layout team to likewise play with the JSPs.
In my personal practices, I generally do my damndest to keep code and markup seperate. If I'm using PHP, for instance, I'll write a simple template class that I can use to feed data into HTML without fusing the two together. It keeps things organized and (most of the time) headache-free.
I hope I've offered some useful insight - best of luck to you.
-WeAz
If your businesslogic breaks when you change the site layout then embedding HTML in your business logic clearly was a bad idea. Doing so gets you up and running soon but you pay the price later when doing maintenance.
Putting some time and effort in separating logic and presentation is not a novelty. The MVC pattern dates from the seventies. The n-tier server architecture was invented shortly thereafter. These two are now well accepted architectures for separating logic and presentation.
As for performance. Code that mixes everything together tends to be naive in multiple ways, including performance, security, extensibility, etc. Optimizing performance generally requires using caching, pooling and other types of strategies. These are hard to retrofit in monolithic single tier systems. Again there's no absolute truth here: you just may be the genius that gets it right in one go.
So it all depends on the question are you the guy who's doing the maintenance and/or will you be there when the shit hits the fan when somebody else tries to do it for you. If so, you are probably better off doing a proper job. On the other hand, out of control IT projects are a great way to milk stupid customers. Many IT businesses have built their empire on that kind of incompetence and billions of dollars still change hands annually for software projects that are over time, over budget and ultimately disappointing.
Jilles
Project Leader: Right you coder, the HTML designer doesn't understand PHP so you got use a template language instead you never heard off.
Coder: Oh okay, I can do that, so Designer guy, you can help with learning this template language?
Designer: No, I never heard of it either and I am going to just delete any html I don't regonise just like I do with php tags.
Coder: Fuck.
And this ain't a joke. My introduction to templates went pretty much like this. In order to deal with a designer who kept removing PHP because of the design program she used I had to learn a new "language" wich didn't help since she still kept deleting it.
Also templates are very limited if you want to do extra stuff. Like changing the layout of the table you just gave dynamically.
Is it possible to color each row an alternate color for instance? Probably it is but either way you end up adding more complexity to deal with what problem? Your designer unable to deal with your coding language? Get a better designer. Coders don't just delete html do they?
MMO Quests are like orgasms:
You may solo them, I prefer them in a group.
The thing is, sometimes dirty php hacks are fine.
What are you coding? If I went to ebay, or amazon, or something like that, and they didn't have a serious n-tier architecture, and all their logic code was scattered randomly throughout their html source, that would be a proper WTF.
On the other hand, when I knock up some sort of ultra-basic blog for myself, or a cheesy feedback form for my band's website, or something like that, then using full-on OOP and MVC is an equally big WTF. In that situation, please stop about impressing other people on slashdot with your architecture model professionalism, and write something shamelessly quick and easy. You're going to be the only person updating it, so who cares?
One further point on that subject... everyone praises a clean separation / MVC approach for being essential when you have multiple developers updating code. Well... true in a way... but there are qualifications to that. I remember doing some hacking on php blogging software Plog for a customer last year. That's completely OOP and MVC, using Smarty for templating, and the intellectual side of my brain was impressed with the cleanliness of the design patterns, but the practical side of my brain found it a pain in the arse. The client would say "you see this output of such-and-such a word on such-and-such a page, can we change it?" If it had been I'd go into the source for that page and it would be pretty much a single line of code...
model._request->("by_categories").view
or something ludricously cryptic like that. So I'd have to trying and "trace" things from the by_categories.php through the templates into all the object classes... of course the OOP was so fully-blown that you'd reach some initial completely generic class whcih told you nothing, you needed something which inherited off something which inherited off something.... etc, etc. It was an absolute nightmare, for the simple reason that the documentation, like so many OSS projects, was extremely lacking, verging on non-existent. I went to their wiki and found a page with the perfect title, something like "which functions are handled in which classes", but it just said "coming soon".
To their credit, when I asked on their forums I got a quick and friendly reply, but still, I think it illustrates my point. If you're going to put things into an elaborate architecture so that what-you-see-in-the-final-html-pages bears almost no direct relationship to organisation of the 'business logic' source files, then documentation is essential otherwise it's actually harder for multiple developers to hack than if you just stuff your html full of inline php.
A good web app has 3 layers: the code, the markup HTML (wireframe only), and the CSS. I strongly encourage you to check out CSS Zen Garden to gain insight to this powerful model.
For a serious web app, mixing logic and presentation is disaster. It becomes a huge headache to change even a simple thing in your presentation. Other developers that need to edit your code can't jump right in. They have to sift through all your crap, completely killing any of the supposed time-savings of building it hastily in the first place.
However the last layer, the CSS, is the most over looked. CSS has wide browser adoption now and is extremely powerful. There are numerous performance benefits for using minimal HTML and pushing things to CSS, mostly centering around CSS getting cached locally. But CSS also provides a tremendous amount of flexiblity for layout. You can drastically change the layout simply by changing the CSS.
More over, when built this way, you can let a much lower cost CSS specialist (pixel pusher) worry about how much padding there and what color widget there, and let us Web App Developers stick to the meat of the project. It's a great way to split the task up in a team environment.
I cannot over emphasize checking out CSS Zen Garden.