Feed Sign in with OpenID OpenID

Simon Willison’s Weblog

Classes for pages

This weekend I started work on my latest web project, further details of which will no doubt follow soon. For the moment I’ll just say that it follows the classic news/articles/users with logins model—basically another small-to-medium sized PHP content management system.

This time I told myself firmly that I wasn’t going to reinvent the wheel and I wasn’t going to build myself yet another web framework library. I had a look at a whole bunch of Open Source systems (mostly thanks to opensourceCMS but none of them seemed to fit my (admittedly pretty stringent) requirements. I was looking for something flexible and easily modified with a well defined API, strictly standards compliant, structural/semantic templates, excellent CSS support, an easily extended user and permissions system, a powerful but straight forward control panel and a well designed, object oriented code base. It also had to be suitable for a team of programmers to hack on together, as the site will be maintained by a group of coders. With requirements like that maybe it’s not surprising that nothing fitted the bill, so I resigned myself to starting from scratch.

I said I wasn’t going to build a framework, and that really was my intention, but yesterday afternoon I hit on an idea that just got my itching to write some code. The way I see it, the structure of an HTML page is just asking to be represented with a class. All pages have a doctype, a title, a head with a bunch of script / link elements, and a body. Further more, almost all CSS designs depend on a number of div elements one after another in the body. Using these points as guidance, I quickly created a Page class that was capable of gathering this information over time until the display() method prompted it to render itself as HTML, or XHTML if that doctype was specified.

This class on its own is not much use, but the beautiful thing about using classes is that they can be extended. I created a second class, SitePage, which extended Page and performed some site specific cusotmisations such as adding the standard site header and menu divs and setting the stylesheet. Further extensions of this class will allow me to create more specialised templates for specific areas of the site. The code I have so far only took a few hours to write and is already proving to be a very productive way of controlling the overall look of the site.

My original intentions may have gone up in smoke, but I’m very happy with the code that’s been developing. I just hope it stands up to the scrutiny of my fellow coders... if not, it’s definitely been a productive learning experience.

This is Classes for pages by Simon Willison, posted on 15th February 2003.

View blog reactions

Next: micro_httpd

Previous: Image Drag bookmarklet fixed

6 comments

  1. Hurrah, he's invented the DOM.

    Tim - 15th February 2003 11:32 - #

  2. Seriously though, I've been in a position where I've tried to categories things and abstract the programming of it out to such a point I looked back and realised I'd invented the database. CMS wise, theres three components, functionality, content and design. You've already addressed content previously I think (structured text is the best way) and design wise you'll always have to create platform dependant code (unless you pay almost zero attention to design) as you may want mobile phone templates, pda templates etc. One thing to think about is to remember to split your css file into functionally discrete components (so you can use templates elsewhere if needed). Anyways, good luck..

    Tim - 15th February 2003 11:35 - #

  3. Actually there were some quite interesting discussions about using the DOM (server side) for XHTML templating a few months back on SitePoint. What I'm doing is pretty similar to the DOM in some ways (although a lot less verbose) but the most interesting thing that's come out of it is the use of inheritenc to extend templates for specialised areas of the site (and the fact that, despite the level of abstraction, it's not actually that much code).

    Simon Willison - 16th February 2003 11:19 - #

  4. We do something similar :-

    class MenuPage extends Page
    {
        function getMenu($location)
        {
            // Create the main menu
            $menu = array();
            $menu['home'] = array( 'label' => 'Home', 'link' => '/', 'submenu' => FALSE );
            // etc
    
            $menu[$location]['selected'] = TRUE;
            $this->smarty->assign('menu'$menu);
            return;
        }
    }
    

    Tim Parkin - 18th February 2003 15:04 - #

  5. Simon, First--- I'd bet you could find an OS project closer than "from scratch" to your end goal, and that adapting it (refactoring as needed) would still be faster than going at it as you are. We're all suseptible to NIH syndrome, and when I was looking for a wiki to fit my high requirements, I found none. I thought about writting my own... and then realized that taking a good one like Moin and making it fit my needs would be much faster. Anyway... given starting from scratch, the path you're taking is a sensible one. Still, consider using the DOM within your page class. Don't reinvent the wheel of appending child elems, finding existing elems, etc. The DOM can save you a lot of hassle. Yes, it's verbose... So make up some useful functions around the mechanism. :)

    Jeremy Dunck - 21st February 2003 15:11 - #

  6. Simon, your idea sounds just like my last take on the content/logic/display dillemma. I haven't had the time yet explore this area in dept. That said, I always create classes for the different types of content I have on a site. For now I only keep content/logic related matters in such classes (retrieve/edit/delete), this content is then referenced in templates (pure php templates). The next step would be to glue some presentation classes to those objects. I think it would be a bad idea to include both in one class. When considering this approach, I thought it would be even more powerful to have a 'widget'-like approach te display. Although there are some projects (phpHtmlLib) already, I prefer to code those myself. I did a few tests where I created some more arbitrary widgets (base classes), and then went on to extend/override those, while allowing parent classes to override child parameters. To create those widgets I used an extended version of your php implementation of XmlWriter.class. That way I keep all string HTML out, and generate XHTML compliant code easily. I have to admit this is really the fastest, cleanest way to generate X(HT)ML, plus, I'm not limited in the attributes I can add (opposed to certain existing html/table generating solutions, including my htmltable class I wrote and never used because of it). Hope you keep us posted on your progress ;-)

    fab - 23rd May 2003 11:37 - #

Comments are closed.

Previously hosted at http://simon.incutio.com/archive/2003/02/15/classesForPages

A django site