YASB – Yet Another Symfony Blog

July 14, 2007

RobotReplay, a usability testing tool

Filed under: Ajax, Browsers, General, Tips and tricks — Krof Drakula @ 4:54 pm

If you’ve ever asked yourself just why your web site or web app doesn’t perform as well as you’ve thought it would, since you’ve given a lot thought into the design of the page and user interface, then you might ask yourself – are you the proper person to be judging the design?

In comes usability testing. It’s giving the end user a chance to work with your product (in our case, a web page or application) and having a system measure the user interaction – how long it takes them to locate a certain function, where they have the most difficulty identifying a certain feature, finding information, etc. There’s already great software that does exactly this (Morae, for example), but the problem here is that you still need a lab to conduct such experiments.


June 22, 2007

A PHP gotcha within Symfony

Filed under: General, PHP, Tips and tricks — Krof Drakula @ 10:45 am

There’s an interesting aspect about using functions within partials, which I’ve written about before – the existence of functions and the dangers of redeclaring them.

The problem here is using partial-specific functions within partials. We’ve had an instance where we needed a function to solve a recursive problem when displaying data within the partial (a complex tree structure).

The quick’n'dirty solution was to declare the function within the partial, which solves the problem. There was no PHP fatal error right up until functional testing. The reason why this error wasn’t spotted before was because the partial was used only once (if it was ever used within a view), thus never realising itself.

When running functional tests, sfTestBrowser instantiates an instance of the sfContext class and runs the application within a single runtime, which means that all registered global functions exist at all times. And because the partial is used by many views, the second the test encountered the second view that used the aforementioned partial, the test died with a PHP fatal error.

As mentioned in the article from before, the solution is to never declare any functions within template PHP files. Any functions that you need (even if it’s used by a single template file) should be declared within a helper and included appropriately. This way, Symfony guarantees the helper will be included exactly once, avoiding the fatal error that would otherwise crash the application.

June 13, 2007

Followup: Creating rich GUIs with Javascript in Symfony

Filed under: Browsers, Javascript, PHP — Krof Drakula @ 11:08 am

Well, I’ve written up a short summary of ideas relating to handling Javascript files in relation to requests, not it’s time to evaluate them.

First thing I’ve noticed with the different ways of injecting Javascript into the response is the order by which the files are loaded, the problem being dependency. If you’re using a library such as jQuery (or any other for that matter), the order by which the JS files are loaded is crucial. I usually force jQuery to use the noConflict mode by calling jQuery.noConflict() in a separate file (to keep the original library file intact in case of upgrades and updates) and loading it after jQuery. That’s done in the general view.yml file on the app-level configuration.

But when I try to add an action-specific JS to the mix, things start getting hairy – when you call $this->getResponse()->addJavascript(), it adds Javascripts to the beginning of the list of JS files, before the view.yml gets a chance to add its own. In this case, you’re limited to adding JS files via a module-level view.yml file by specifying the view to which you want to append the JS.

This is different when handling components – imagine having, say, a countdown timer written in Javascript. If you’d like to include it in several places but don’t want to handle the dependencies, then there’s a foolproof way of handling those – simply include the dependencies using $this->getResponse()->addJavascript(). This time, the components get rendered AFTER the main view, so including JS files this time adds them to the end of the list, after the main view’s files have been added.

The good thing about the latter is that you never have to worry about changing any view.yml files after including the component anywhere in your main views. That lends itself to building self-contained, no-fuss plugins using components, which, in the context of this article, could be HTML widgets, like calendars, calculators, AJAX comment boxes, shoutboxes, etc.

Anyways, hope this insight helps. Now for some midday coffee.

May 20, 2007

Using jQuery to manipulate a foreign DOM

Filed under: Browsers, HTML, Javascript, Tips and tricks — Krof Drakula @ 9:39 am

This is somewhat of an old topic, but digging through a myriad of ways of including jQuery into a website that doesn’t use it (eg. Wordpress having Prototype and such), I stumbled upon a bookmarklet written by John Resig that loads jQuery into the current DOM and enables you to run an onload function that executes when the library’s ready to use.

Here’s the page where the process is documented with an example of manipulating Digg using jQuery. The approach used with this bookmarklet is useful because it enables you to turn on the noConflict mode without manually waiting for the library to load. You do this by replacing the comment fragment in the bookmarklet with jQuery.noConflict() inside the onload handler and hey presto! you have jQuery enabled and available via jQuery.*.

May 11, 2007

Easier I18n XLIFF message generation

Filed under: General, PHP, Tips and tricks — Krof Drakula @ 1:43 pm

If you’re like me and you don’t trust yourself to catch all of the breadcrumbs you leave behind you, you tend to rely on an arsenal of tools to keep you in check. This is especially true with XLIFF and Symfony.

There’s an i18n generation script that scans your actions, YAMLs and templates for the use of the __() function. The scanner routine is pretty robust and only adds missing entries, but leaves others intact. A great tool if you’re translating applications.

But there’s a problem: when you try to write your own validators and have I18n enabled in your application, the sfRequest::setError() expects 2 parameters: the name of the request parameter and the value of the error, the problem here being that ::setError() expects the second parameter to be the source language for translation, which in turn means that you don’t need to use __() to wrap your error message, so that it works directly with your validation YAML files.

That’s very smart, because you don’t have to translate your YAML validation files, since it already wraps it in __(). But not good, if you want to generate your own XLIFF files and not use the __() function (since the current implementation only scans for occurences of that function).

The problem was elegantly solved by fatg, who proposed testing the script for the detection of *__() functions – and it works. So, if you’re using any function which ends with __, the init-i18n script WILL detect it and add it to the XLIFF.

But how exactly does that solve anything? Well, instead of writing something like:

// lang php
$this->getRequest()->setError("my_parameter", "my_error");

…you write:

// lang php
$this->getRequest()->setError("my_parameter", i18n__("my_error"));

Okay, so the script now detects "my_error" as being an XLIFF source, but the application will fail with a fatal error in this case. That part is easily solved by adding

// lang php
function i18n__($message) { return $message; }

to apps/[myapp]/config/config.php, which creates the i18n__() function within the myapp application.

Although this isn’t the ideal solution (it would be nice if Symfony auto-generated the XLIFF by itself when using the __() function), it’s way better than duplicating the source keys inside comments like:

// lang php
// __("this is a source string");

Not only is it a pain to edit, it bloats the code significantly.

Anyways, hats off to fatg. Nice work.

May 9, 2007

Solved: How to get I18n working on reverse-engineered tables

Filed under: Database, PHP, Propel — Krof Drakula @ 12:24 pm

We’ve all been there – Symfony and I18n do play well together – it’s got XLIFF for interface translation which works almost out-of-the-box, it’s got localization features for things like numbers, currencies and many others. It also has internationalization features that work with database tables.

Unfortunately, all is well until you stray from the guidelines presented in the Symfony book. The norm in Symfony is to write the database definition withing the schema.yml file. That’s okay… it’s compact, concise and verbose enough to be understood within the context of Symfony nomenclature. But when you’re dealing with 25+ tables that need accompanying I18n tables, things could get messy, nomenclature or not.


April 2, 2007

A list of handy browser-specific CSS selectors

Filed under: Browsers, HTML, Tips and tricks — Krof Drakula @ 7:12 am

Well, not exactly breaking front page news, but I thought I’d share this handy library of CSS selectors for targeting specific browsers:

CSS Hacks

March 30, 2007

Implementing rich GUIs in Symfony

Filed under: HTML, Javascript, Tips and tricks — Krof Drakula @ 9:57 pm

When it comes to rich graphical interfaces, we’re currently being swarmed by all these big and small players readily available on the net – there’s Script.aculo.us, YahooUI, Yui-Ext, Moofx, to name a few of the most prominent. All’s fine and dandy until you try coding some of the stuff inside views of actions.


March 15, 2007

Still wading through tough waters

Filed under: Uncategorized — Krof Drakula @ 3:04 pm

Just to fill you in – this blog is by no means dead, I just haven’t had the time to write up new updates, especially now that I’ve given my notice of resignation. Had a few major disputes with management, but I should get things straightened out within a week or two.

In the meantime, I’ve updated the Wideimage project code, so now the unsharp filter actually works. We’ve moved the code base to Sourceforge due to some problems we’ve had with Google Code hosting, so you should update your SVN checkouts to the new location, since this is where we’ll commit any new changes to the Wideimage codebase.

Anyways, wish me luck.


There’s a WideImage wiki at http://wideimage.sourceforge.net/.

February 28, 2007

Progress update

Filed under: PHP — Krof Drakula @ 3:11 pm

I know, I know, I’m getting lazy. Or rather, that’s what it would seem. Lately I’ve had projects coming in on all sides, which extended my field to include developing Flash applications, which is a pain in the. Also, Friday is the big premiere I’ve been bragging about the last couple of weeks.

As far as things here are concerned, I’ve decided to write up a better image manipulation package for Symfony as a plugin, based on the Wideimage project. Yes, it’s yet another open source project I’m involved in, but there are several advantages to incorporating this package into a plugin for various reasons:

  • it handles all GD2-supported image types, other formats can be added by extending the image loader
  • supports all GD2 filters
  • simplifies common tasks for images (resize, blur, sharpen, writing pixels, etc.)
  • supports chaining operations
  • fully extendable on all levels
  • implements an unsharp filter, which enables you to generate sharper thumbnails

For a simple example of just how it works on the user level, have a look at this. Also, have a look at the included demos and unit tests. Yes, the whole package is thoroughly tested.

What this enables you to do is handle image uploads or manipulate images already on the server, for example, adding watermarks or generating grids of cropped images.

More to come after the show. ;)

« Newer PostsOlder Posts »

Powered by WordPress