Framework: The Next Generation

There have been a lot of new PHP frameworks coming into existence. With the release of PHP 5.3, many frameworks are taking the leap with a total do-over of their codebase to take advantage of 5.3’s namespacing and other advancements. But most seem to be missing the mark.

PHP 5.3-specific frameworks :

  • Recess has a 5.3 branch in development
  • Sensio is working toward Symphony 2.0 (in dev)
  • Some CakePHP core devs have gone AWOL to start Lithium (0.2 released yesterday)

These last two are both total do-overs. Lithium seems very promising. It comes with very good support for schemaless key-value stores like MongoDB which to me is a huge win. Also they use the same view template extension convention as Recess (index.html.php) which is nice. But still I can’t tell you what a pain in the ass it is to open a layout and find code like this :

<html>
<head>
	<title><?=$title; ?></title>
	<?php echo $this->html->charset(); ?>
	<?php echo $this->html->style('base'); ?>
	<?php echo $this->scripts(); ?>
	<?php echo $this->html->link('Icon', null, array('type' => 'icon')); ?>
</head>
// ...

Do you really need to abstract away the stylesheet tags?
Is it that hard to type in a meta tag for the charset?
Why make me hunt through the code to find this stuff?

I think there’s a problem with the way people are writing frameworks these days.
I think people are afraid of HTML.

And it’s sad.
Because that’s what websites are.

We should be embracing our HTML, not hiding it.
We may like to think that we’re Ajaxy, but the goal of development should not be to write less HTML.
The goal of development should be to quickly produce code that works well and is easy to understand and maintain.

Fancy framework shenanigans be damned.

3 Comments so far

  1. Nate Abele on November 20th, 2009

    Hey Kev, thanks for checking us out. I’m glad you like most of what you see, but I have to say that when it comes to templates, you’ve really got it wrong.

    First of all, I love HTML, especially HTML5. I still get goosebumps every time I type “<!doctype html>” into a new layout template.

    I don’t use helper methods because I’m afraid of HTML, and thinking that that’s all those helper methods do for you is incredibly short-sighted.

    Let’s take the simplest case first: the charset( ) method, while easy enough to type out manually, ties into the character set settings for the entire framework. It ensures that your data is queried, processed, and displayed in the same consistent character encoding (usually UTF-8, but not always). This not only prevents your pages from displaying broken characters, but has huge security implications as well. Ensuring a consistent (and enforced) character set across the board protects you from several classes of character encoding exploits.

    For anyone who’s spent more than 5 minutes with YSlow or front-end optimization in general, the CSS and JavaScript include helpers should be obvious. Not only can I use those to compress (JSMin, Minify, etc.) and pack my assets into a single file (which becomes completely seamless to me as a developer), I can set my site up to only do this in production mode.

    Further, with asset timestamps, I don’t have to clear my cache in development every time I make a change to a JS or CSS file. More importantly, I don’t have to tell my users to clear theirs. It just works.

    Finally, I’m if you haven’t heard about the new “resource packages” feature which will be part of the next version of Firefox, it’d be worth your while to check it out. With my helpers, I can support resource packages with 1 new class, a couple lines of configuration, and zero template changes.

    Next time you try to critique someone else’s design, you would do well to spend a few minutes trying to put yourself in that guy’s shoes. You might stand a better chance of sounding more informed.

    Hope that helps,
    - Nate

  2. KevBurnsJr on November 20th, 2009

    The charset() method. I don’t have extensive i18n experience so I may very well be full of shit. However I’m pretty sure that just because you set the charset in a framework config variable doesn’t mean to have to generate the HTML inside a helper class.

    I see code like this and I wonder (\lithium\template\Helper\Html;24-52)

    protected $_strings = array(
      'block'            => '<div{:options}>{:content}</div>',
      'block-end'        => '</div>',
      'block-start'      => '<div{:options}>',
      'charset'          => '<meta http-equiv="Content-Type" content="{:type}; charset={:charset}" />',
      'doctype'          => '<!DOCTYPE {:version} PUBLIC "{:dtd}" "{:url}">',
      'image'            => '<img src="{:path}"{:options} />',
      'js-block'         => '<script type="text/javascript"{:options}>{:content}</script>',
      'js-end'           => '</script>',
      'js-link'          => '<script type="text/javascript" src="{:path}"{:options}></script>',
      'js-start'         => '<script type="text/javascript"{:options}>',
      'link'             => '<a href="{:url}"{:options} rel="nofollow">{:title}</a>',
      'list'             => '<ul{:options}>{:content}</ul>',
      'list-item'        => '<li{:options}>{:content}</li>',
      'meta'             => '<meta{:options}/>',
      'meta-link'        => '<link href="{:url}"{:options} />',
      'para'             => '<p{:options}>{:content}</p>',
      'para-start'       => '<p{:options}>',
      'style'            => '<style type="text/css"{:options}>{:content}</style>',
      'style-import'     => '<style type="text/css"{:options}>@import url({:url});</style>',
      'style-link'       => '<link rel="{:type}" type="text/css" href="{:path}"{:options} />',
      'table-header'     => '<th{:options}>{:content}</th>',
      'table-header-row' => '<tr{:options}>{:content}</tr>',
      'table-cell'       => '<td{:options}>{:content}</td>',
      'table-row'        => '<tr{:options}>{:content}</tr>',
      'tag'              => '<{:name}{:options}>{:content}</{:name}>',
      'tag-end'          => '</{:name}>',
      'tag-start'        => '<{:name}{:options}>'
    );

    Is that rly necessary?

    I’ve seen many applications where html keeps working its way further away from the view templates. Letting a helper generate HTML is a constraint I would not soon violate. But then who cares right? That’s what helpers are for. To help. But does this belong in the framework or would it be more appropriate as a plugin?

    CSS and JS bundling and minification are definitely huge wins for production. That doesn’t mean that the HTML has to be generated in a helper. And it certainly doesn’t mean that it’s okay to disperse additions to the site’s collection of scripts from any-old-place within the application. If I want to know what scripts are being added to a page, I want to see that in the layout. For separate applications with individual bundles, nested or separate layouts might be appropriate.

    But this is all just me being bitter and bitching about how I would do things differently. Nitpicking aside li3 looks like an interesting framework. I’m planning to release a framework of my own (1/1/2010). I’ll ping you when its up, and hope you’ll see a different approach to what an application framework can be.

    - Kev

  3. Nate Abele on November 20th, 2009

    Again, you’re missing the point. The point is not to abstract away having to write HTML, the point is extensibility. Suppose I wanted to replace all my date/time inputs with some other tag that got transformed into a datepicker using jQuery. With tag templates, I can do that easily. Same goes for any other tag. I can wrap, replace, extend, etc., all without having to unnecessarily extend or replace method calls in my templates.

    To the point about the plugin: HTML is pretty much the foundational technology of web applications. Without HTML, you’ve pretty much got nothing. If you’re writing a framework for making web applications, why on earth would you have the component that generates the foundational piece of it in an optional extension??

    I’ll grant you, many if not most of the tag templates you listed are hold-overs from a much earlier iteration of that code, (hence most of them are not actually used, and will likely be removed). But let’s be clear: most people don’t want to develop like you do. When choosing between hand-coding HTML (i.e. forms, etc.), or using helpers that save you time *and* buy you flexibility, most people (myself included) would choose the latter. When I go from dev to production, I don’t want to have to think about going through all my templates and replacing all my calls to external assets.

    “And it certainly doesn’t mean that it’s okay to disperse additions to the site’s collection of scripts from any-old-place within the application.”

    So does this mean that if you need a specific JS library on *one* page in your site, you include it in *all* your pages? This is an anti-optimization at best.

    Finally, as my astute colleague Alexander points out, no one is twisting your arm about this. If you like coding straight HTML, by all means, do so.

Leave a reply