Maintainable CSS

Posted 22:44, 2/10/2008, in Web

Natalie Down has put up slides for what looked like an interesting presentation on writing maintainable CSS. This is one of those topics that rarely gets much attention, so it's nice to see some suggested good practices, particularly for stylesheet structure and layout. She also has some good tips on CSS implementations in general.

The biggest problem I've found when maintaining CSS is that when you come back to a site some time after the initial implementation (or if you're maintaining some code written by someone else), it's usually easiest to add new styles to the end of the existing stylesheet instead of reminding yourself how it all fits together, and then putting the new styles in the correct place. This gradually leads to bloat, as you end up putting in overrides for rules you've defined elsewhere, and then the next time it becomes overrides for your overrides, and so on. Grouping your rules as Natalie suggests is the only real solution to this, as it forces you to insert your code at the appropriate place, which in turn encourages to you edit what is already there instead of adding to it.

Some other random notes on the slides:

It's interesting seeing other developers' approaches to design implementation. After some basic planning I tend to start chopping straight from an actual-size mockup provided by the designer, the aim being to end up with as close a representation of this graphic as possible.

Perhaps I'm interpreting it incorrectly, but "the grid" is not a phrase I'm particular fond of in this context - elements of a design rarely translate perfectly to a grid-type layout, and even slight changes in the spacing between elements (in order to conform to your grid) will usually result in some pretty negative feedback from the designer. 

I tend to think of layouts more as collections of boxes. E.g. if this site had been designer by a proper designer (obviously it hasn't) and they'd sent you this layout as a graphic, by looking at it you'd put mental boxes around distinct elements such as the right sidebar, navigation and main content area. These then translate directly to semantically named divs in your layout. For more complex layouts, it can help to use the draggable line guides most graphic programs provide in order to work out exactly what lines up with what.

Regarding CSS frameworks, it's nice to see someone speak out against these. We've been experimenting with Blueprint a bit at work and I haven't been too impressed so far.

On the plus side I can see the attraction of something that resets browser defaults to a common baseline (particularly to people who've been stuck by browser inconsistency issues before), and I think grid-style layouts are a little easier for people to get their head round than floats and clears. But to me the negatives far outweigh these advantages:

  • You're adding a layer of overhead to your site - every user has to download all that additional CSS code, plus (generally) slightly larger HTML files
  • These frameworks steer you away from good markup, as your classes end up being presentational ("span-36 last") rather than semantic ("navigation").
  • You're setting yourself up for maintainability problems (as Natalie mentions), as you're starting off with a whole load of CSS code that was written by someone else, making the site more difficult to debug when you hit problems.

CSS frameworks haven't gained too much adoption as yet, so hopefully as the older, buggiest versions of IE continue to slowly lose market share, the demand for them will gradually disappear.

Comments (0) Tags: css

Module-specific models in Zend Framework

Posted 18:27, 15/8/2008, in Web

A post this week on PHP::Impact looks at the handling of modules in ZF, particularly the issue of module-specific models. Frederico's solution for this involves calling a particular function when you want to load a model. The way I solved this was a little different - I have a simple controller plugin that uses a dispatchLoopStartup method to grab the current module name from the request and add its model directory to the PHP include_path. That way, assuming you're using Zend_Loader, you can instantiate your module classes in the same way that you would any other.

Here's a quick example of how this works (code is untested). Assuming a directory structure based on the proposed standard one in the ZF wiki:

application/
   config/
   controllers/
   layouts/
   models/
   modules/
      news/
         controllers/
         models/
         views/
   views/
data/
library/
scripts/
tests/
www/

In my bootstrap I define two constants - ZF_PATH (full path to the Zend Framework library directory), and APP_PATH (full path to the current project). I then use these to set the PHP include path initially:

set_include_path(
        get_include_path() . PATH_SEPARATOR .
        ZF_PATH . PATH_SEPARATOR .
        APP_PATH.'/application/models'
);

then I have a front controller plugin which looks something like this:

class Myapp_Plugin extends Zend_Controller_Plugin_Abstract
{
        public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
        {
                set_include_path(
                        get_include_path() . PATH_SEPARATOR .
                        APP_PATH.'/application/modules/'.$request->getModuleName().'/models'
                );
        }
}

Register this plugin with your front controller and then as long as your module models follow the standard class naming conventions you don't have to do anything special to load them in.

The only disadvantage of this approach is the performance hit of an additional directory in the include path, but I'm hoping this will be negated by an optcache (something I have yet to benchmark).

Frederico's post has spawned a more general discussion on modules in ZF which I have some views on but that's a topic for another post.

Comments (0) Tags: zend framework, modules, models

Zend Framework in the enterprise

Posted 20:36, 23/7/2008, in Web

I just posted a comment on Federico Cargnelutti's (excellent) PHP blog that I feel I should expand on. The topic was Zend Framework's suitability as an 'enterprise' framework. Although I'm sure ZF is used in a number of enterprises (and I've used it for a few things over at Incutio already), I think it is still a way from being the 'perfect' enterprise framework, which is how it is described in the post.

There are three 'enterprisey' areas in which I believe it is particularly lacking:

  • ORM
  • Database migrations
  • Application deployments

None of these things are 'impossible' to do with ZF-based apps, but the ORM has its limitations; and the other two aren't covered by ZF at all and require integration of third party solutions such as Phing.

Zend's view on component development for ZF has been that they wish to focus on areas where they feel they can offer value to the PHP community as a whole. For this reason they have delibrately avoided developing components for things already well served by existing open source PHP projects. This makes complete sense. But as a developer coming to ZF afresh, unless you already know about these projects, you're going to see some pretty big holes in ZF as a platform on which to build your applications.

Firstly, ORM. I'm not going to say too much about this since I've posted about it before. I guess my main complaint about ORM in ZF is that I've found the Table Data Gateway pattern pretty limited (which isn't ZF's fault of course), and because of this you frequently end up having to either write your own ORM layer or turn to third party libraries such as Doctrine or Propel.

As an example, one of the first projects I tried with ZF was a rewrite of one our legacy applications, in which the data for domain objects frequently spans two or more database tables. The only way to load this kind of data with Zend_Db_Table is to create your own joins with Zend_Db_Table_Select, to the point where you'd basically back to writing raw SQL.

It is also suprisingly difficult to get the Zend_Db family of classes to return instances of your application's classes (by default they always returns data arrays which your application then has to convert into objects). It's not impossible to solve this, e.g. you can have your objects extend Zend_Db_Table_Row, or through some calls on Zend_Db_Statement directly you can specify the class you'd like returned, but both of these approaches are a little messy.

I feel a little bad bashing Zend_Db, as it does what it is supposed to do very well, and the adapter, profiler and select families of classes are all excellent. But these are real world problems that I've not found with other frameworks.

Secondly, database migrations. There is nothing in ZF to do these, the closest is a community-submitted proposal for a Zend_Db_Schema_Manager component which hasn't been updated since November last year. Sure there are some third party solutions, but this is functionality Rails provides out of the box.

Thirdly, deployments. Gone are the days when to make an app live you FTP in and manually upload the files (or at least they should be). Whilst Rails doesn't provide anything like this, Capistrano (which is excellent), was written for RoR, and is very easy to install and integrate with Rails apps.

This has been quite a negative post. I don't mean to suggest that Zend have taken the wrong approach in development of the framework - It's still relatively young, and the upcoming 1.6 release does plug a few of the less-enterprisey holes. But if the framework is to be taken seriously as a platform on which to build enterprise applications, these are the areas which I feel need improving. This could be achieved either through the development of new components providing this functionality, or through components that provide much easier integration with the existing PHP solutions (in the same way that symfony has a component for interacting with Propel).

In an ideal world, I'd love to see Zend-contributed components which implement some alternative patterns for use in ORM layers, such as Zend_Data_Mapper and Zend_Active_Record (post PHP5.3) classes. I also have a close eye on the Zend_Tool project, which I hope will eventually cover the other two areas I mentioned.

There are also quite a few big pluses for ZF as an enterprise framework, in addition to the things Federico mentioned in his post, the license of ZF itself and Zend's other offerings (training, IDE etc.) both definitely work in its favour.

Comments (6) Tags: rails, doctrine, propel, zend framework

Benchmarking Zend_Config_Xml and Zend_Config_Ini

Posted 22:59, 18/7/2008, in Web

Historically I've always used XML for configuration files, since the format is flexible and the parsing tools mature. Recently I've been considering switching to .ini files for some stuff, as given the simpler format I'd expect the parsing in ZF to be quicker.

This is simple to test of course, so I ran a quick benchmark using the (identical) example configs from the Zend_Config docs. Code below (uses the PEAR benchmarking class):

<?php
set_include_path(
    get_include_path() . PATH_SEPARATOR .
    '/path/to/zend-framework/library'
);

require('Zend/Loader.php');
Zend_Loader::registerAutoLoad();

// Load PEAR profiler class
require('Benchmark/Profiler.php');
$profiler = new Benchmark_Profiler(TRUE);

$numTests = 10000;

// Benchmark XML config
$profiler->enterSection('xml');
for ($x = 0; $x < $numTests; $x++)
{
    $xml = new Zend_Config_Xml('config.xml');
}
$profiler->leaveSection('xml');

// Benchmark ini config
$profiler->enterSection('ini');
for ($x = 0; $x < $numTests; $x++)
{
    $ini = new Zend_Config_Ini('config.ini');
}
$profiler->leaveSection('ini');

$profiler->stop();
$profiler->display();

And the results for 10,000 runs (lower is better):

FormatTime (seconds)
xml4.29669
ini5.6626

so, in this example parsing the XML file is actually quicker than parsing the same data in ini format.

Just to see how long an individual parse takes, I changed the variable to only parse each file once. The results were then:

FormatTime (seconds)
xml0.00152
ini0.00122

So with only one parse, ini was quicker! The only explanation I can think of for this is that simplexml is internally caching the file read just in case it needed to reparse the same data. But there is no mention of this in the docs, and it would seem like an odd thing to do in simplexml but not elsewhere.

The sample code and files are available for download in case anyone wants to experiment.

Comments (1) Tags: xml, zend framework, ini

Comparison of Propel and Doctrine (PHP ORM)

Posted 20:48, 8/7/2008, in Web

One of the symfony contributors has posted a comparison of Propel, Doctrine and the Propel integration plugin for symfony. The article focuses mainly on the syntactical differences between the three.

I've been looking at PHP ORM libraries recently, and have spent quite a bit of time with Doctrine in particular. Both libraries have some clever solutions to some tricky problems, I especially like Doctrine's ingenious way of implementing Rails-like acts_as functionality.

I did look at Propel first, since I believe it's been around longer; but was put off by its syntax and focus on auto-generation of classes (which I have an irrational dislike for). Doctrine is a little more intuitive, and the query syntax is a little closer to the Zend_Db_Select/Statement syntax which I'm a big fan of.

Still, it's sad that PHP frameworks have to rely on external libraries for ORM funcionality, as this seems to add an unnecessary layer of overhead for something so fundamental to web application development. The experience has given me a new found respect for Rails' ActiveRecord implementation, and I hope that this is an area that will improve in ZF in the future. Zend have hinted that they'd like to do a proper ActiveRecord implementation post PHP 5.3, it would also be nice to see some components to aid integration with the existing libraries (Zend_Doctrine / Zend_Propel), although these would be fairly mammoth tasks.

Comments (0) Tags: symfony, doctrine, propel, php, zend framework

New Gmail privacy feature

Posted 20:03, 8/7/2008, in Web

Google have added a new feature to GMail that allows you to view a history of logins to your email account, including time, browser type and IP address. Whilst this is a nice idea (and something I hope will become more commonplace), all it achieves is allowing you to see if your account has already been hacked, rather than providing extra protection in the first place.

Whilst this might be a fairly geeky feature request, I've often thought it would be nice if some online services that you really don't want to be hacked (e.g. Internet banking) offered some advanced option where you could restrict the IP addresses that could be used to access them. I know that I will only ever be accessing some services from a small number of static IPs, so doing so would provide an additional layer of protection.

It would also be nice if you had some visibility on brute force attempts to access your accounts (e.g. dictionary attacks). It might scare some people into changing their passwords to something a little more secure.

Comments (0) Tags: gmail

Search this site
Login
(or login/signup the old fashioned way)
Elsewhere

External URLs/articles that may be of interest:

Adobe releases 64-bit flash player for Linux

Adobe have released an alpha of their 64-bit flash player for Linux (I believe this is the first 64-bit player they've done on any platform, it's not available for Windows or Mac yet). And it works great. It may be an alpha but so far I've found it considerably more stable than the released 32-bit wrapper version. It also uses considerably less CPU power. Easy installation instructions via. this blog entry.

MS Office in the browser

The most interesting thing about this announcement is that MS say the system will work in Firefox and Safari as well as IE. The Microsoft of 10 years ago would have used proprietary IE only code and used it as a way to leverage IE market share.

The Future of Advertising, Branding, Media and Communications

Video of a very interesting talk by Gerd Leonhard on the future of the media industry, and content on the Internet.

Future of web browsing from Mozilla Labs

Some interesting ideas about how web browsing might look in the future (watch the first video).