Jacob Steringa

Thoughts on web development

20 notes &

Content-type mapping with Lithium

Recently I started experimenting with Lithium, an awesome PHP framework. I really like it’s style, as it uses many new features of PHP 5.3 which really can make your code a lot leaner.

I wanted to return JSON in some occasions and Lithium has a neat feature on collections where you can call ->to(‘json’) on an result set. It works out of the box, but there is a problem with the formatting of the JSON. It looks like this:

{"1":{"id":"1","family_id":"2","family_position":"0","na....},{"id":"2","fami....}}

As you see, it is an object with objects in it. The desired result in my case is an array of objects, like this:

[{"id":"1","family_id":"2","family_position":"0","na....},{"id":"2","fami....}]

I started looking around the interwebs to find a solution. But I didn’t find a satisfying answer in the Li3 manual, so I started to browse the API docs. The docs for the Media class, the class responsible for almost everything what has to do with content-types, gave me the answer right away.

Within the file config/bootstrap/media.php you can declare custom content-types and assign custom handlers. With that knowledge things got really easy. I knew that I could get the desired result if I manually altered the results in the controller, but that doesn’t really adhere to the DRY principle. Declaring my own handler for the JSON format was the solution.

Media::type('json', 'application/json', array(
	'encode' => function($data) {
		$result = array();
		
		foreach($data as $object) {
			$result[] = $object;
		}
		
		return json_encode($result);
	}
));

This small snippet fixed my problem! I can now render JSON like this:

$this->render(array('json' => Projects::all()));

The cool thing about this feature is that it works for many more content-types, for instance csv, like in the example in the Li3 API docs.

Filed under php json

10 notes &

The el property in Backbone.js and events

Today I found myself struggling with Backbone.js events. In this particular case I wanted a span element with the class use to point to a router url. That shouldn’t be that hard to do, but I couldn’t get it to work.

After a while I realized that I overwrote the el property with the template I used instead of adding it to the el property.

render : function() {
	this.el = this.template( this.model.toJSON() );
	return this;
},

When I added the the template to the el property instead of making it the element, all of the sudden it worked.

render : function() {
	$( this.el ).html( this.template( this.model.toJSON() ) );
	return this;
},

Lesson learned: do not overwrite the el property in your render method!

Filed under backbone.js javascript