Embed images anywhere in CakePHP

Written: Aug 24th 2009, 22:38

Inspired by the Ez publish’s way to embed images inside rich text fields, this CakePHP code takes the same principle in the true CakePHP way, with two helpers to extend David Persson’s Media Plugin.

Attahcments from David Persson’s Media Plugin

The CakePHP Media plugin by David Persson is very smooth, and with the Polymorphic behavior you use this as your main files store, creating hasMany relations to your other models. You can even create multiple relation form one single model by the Model.Group syntax:

var $hasMany = array(
	'Image' => array(
		'className' => 'Media.Attachment',
		'foreignKey' => 'foreign_key',
		'conditions' => array('Image.model' => 'Posts.Post', 'Image.group' => 'image'),
		'dependent' => true),
	'File' => array(
		'className' => 'Media.Attachment',
		'foreignKey' => 'foreign_key',
		'conditions' => array('File.model' => 'Posts.Post', 'File.group' => 'file'),
		'dependent' => true)
);

What I don’t like is the way it generate different sizes when new files is uploaded. Rather I want to generate both thumb (and cache the markup) when the media file is used. Also I prefer to be able to work with a variety of different sizes, instead to be locked in a small, medium, large sizes. To accomplish this I have created

How this works

First up you create a relation to the Attachment model in Media plugin, in your textfields you add this code:

[image:7 size:full align:right]
// All options:
// [image:7 size:thumb|full|original align:right|left lightbox]

In you view code you parse the content this way:

<?php 
$body = $post['Post']['body'];
if (!empty($post['Image'])) {
	//debug($post['Image']);
	$body = $mediaEmbed->substituteEmbedTags($body);
}
echo $body;
?>

Inside the MediaEmbed helper the substituteEmbedTags() function parse the the text for the image markup and calls a element to display the resized version of the image:

<?php 
// $id, $size and $align is sent to the element
App::import('Model', 'Media.Attachment');
$attachment = new Attachment();
$attachment->recursive = 0;
$image = $attachment->read(null, $id);
$image = $image['Attachment'];
$class= "embed-image embed-" . $size;
$div_pre = "";
$div_post = "";
if(!empty($align) and $align !== 0) {
	$div_pre = '<div class="object-' . $align . '">';
	$div_post = "</div>";
}
if($show_lightbox === 1) {
	echo $div_pre . $mediaImage->lightbox($image, array('class'=>$class), array(), $size) . $div_post;
} else {
	echo $div_pre . $mediaImage->resize($image, $size, array('class'=>$class)) . $div_post;
}
?>

The image size system

You define your image-sizes in app/config/core.php:

Configure::write('Image.full.height', 400);
Configure::write('Image.full.width', 500);
Configure::write('Image.thumb.height', 100);
Configure::write('Image.thumb.width', 100);
// And more images sizes if you need that..

What do you need

Download an example app below to see it in action.

Download files

Back to posts list