SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Tutorials - Big bits of code to help you do more

Adding an image to a blog post using Decorators and the SilverStripe Blog Module

The Silverstripe blog module is great and its made its way into many of my Silverstripe sites. However, for most designers it is missing one vital aspect; an image field for each post. In this tutorial I'm going to show you how to quickly add an image to the blog module without editing any of it's files, allowing hassle free upgrading in future.

The Wrong Solution

The easiest way to fix this issue is of course to just add the following to the Blog Modules core file BlogEntry.php:  

class BlogEntry extends Page
{
static $has_one = array(
 'BlogEntryImage' => 'Image'
);
}

 

However, what happens when you want to update your blog module with the latest source code? Do you really want to be adding your own extension every-time you update? No -we're lazy!

The Right Solution

The best way to add to an existing SilverStripe module is to decorate it with extensions.

Firstly create a file BlogEntryDecorator.php inside mysite/code like this;

<?php
class BlogEntryDecorator extends SiteTreeDecorator {
	function extraStatics() {
		return array(
			'has_one' => array(
				'AttachedImage'=>'Image'
			)
		);
	}
	
	function updateCMSFields(& $fields){
		$fields->addFieldToTab('Root.Content.Image', new ImageField('AttachedImage','An image for this Blog Entry');
	}
}

What this will do is setup the database to accept images to be attached to a blog entry; and then updates the cms with an uploader. You can of course replace the SilverStripe core ImageField with an Uploadify ImageUploadField if you have the Uploadify Module installed.

Next we need to tell SilverSripe to use the Decorator that we defined above. So we add the following to our _config.php file;

DataObject::add_extension('BlogEntry', 'BlogEntryDecorator');

Now we just need to extend the theme files to include the image. You can do this differently depending on how many changes your going to make. If your only going to be adding an image to the list of blog entries (ie the blog holder) then I would reccomend method 1, however if your going to change alot of the *.ss files for the blog module then I would reccommend method 2.

 

 Method 1: Add to my theme

Copy the file;

blog/templates/Includes/BlogSummary.ss

to;

themes/mytheme/templates/Includes/BlogSummary.ss

and add;

<% if BlogEntryImage %>
 <% control BlogEntryImage %>$CroppedImage(79,89)<% end_control %>
<% end_if %>

run /dev/build and your done!

 

 Method 2: Extending my theme

This is basically the same as above but as opposed to creating the file;

themes/mytheme/templates/Includes/BlogSummary.ss

you would create it under a different folder;

themes/mytheme_blog/templates/Includes/BlogSummary.ss

You can now use the folder structure 'mytheme_blog' to copy/edit the other .ss files that you will need to customise in your theme. ** You only need to copy the files that you are going to edit **

This allows you to quickly distinguish between theme files that are specific for a certain module. This may not be something that you would find useful now. But if you decide to use the theme as a basis for another site, or even just replicate the block formatting for Blog pages then you can do so with ease.

 

Special Thanks

Special thanks go to Aram Balakjian for their contributions to this post.

Matt Clegg avatar

Matt Clegg

  • Invader_Zim
    31/05/2011 6:36pm (4 years ago)

    Thanks for this article. And good timing. This is the perfect answer to a question raised on the official forums some hours ago :-)

    Cheers

  • Matt Clegg
    31/05/2011 7:17pm (4 years ago)

    Wow, sheer coincidence.. can you provide a link to the particular post in the forum?

  • Invader_Zim
    31/05/2011 9:31pm (4 years ago)

    Of course, it's here: http://silverstripe.org/blog-module-forum/show/15872

    Cheers

  • nekrasov
    14/07/2011 1:44am (3 years ago)

    You are missing a ')' in line 12 of BlogEntryDecorator.php:

    [Corrected]
    $fields->addFieldToTab('Root.Content.Image', new ImageField('AttachedImage','An image for this Blog Entry'));

    And the code for templates (according to your ImageField) must be:

    <% if AttachedImage %>
    <% control AttachedImage %>$CroppedImage(79,89)<% end_control %>
    <% end_if %>

  • Matt Clegg
    14/07/2011 7:49pm (3 years ago)

    Yes, well spotted.

    Not to point fingers but it looks like someone from SSBits had edited my code...

  • nekrasov
    15/07/2011 4:20pm (3 years ago)

    Just to point out:

    It's not necessary to use the control for AttachedImage (we have only an image per entry)

    We might rewrite the code for templates like this:

    <% if AttachedImage %>
    $AttachedImage.CroppedImage(79,89)
    <% end_if %>

  • juneallison
    16/07/2011 3:37pm (3 years ago)

    Thanks for sharing this! I haven't tried this out yet, but wanted to know if this only creates the image field in the admin area or if it will also show the image field on the front end. As the blog module allows you to edit posts from the front end as well. (if logged into the admin) Thanks!

  • nekrasov
    18/07/2011 11:32pm (3 years ago)

    With the code of this tutorial you only can upload images in the admin area.

    To upload and attach image to a blog entry, I recommend you to use the module uplodify and do some tweaks to the blog module. (I don't know how to override or overload the BlogHolder to not hack the core.)

    I show you how to do this in 3 easy steps:

    1. Donwload and install de uplodify module if you have not already installed it (http://www.leftandmain.com)

    2. Open the file 'blog/code/BlogHolder.php'
    and insert the following line of code in the function BlogEntryForm()
    [below the line 232: new $field("Author", _t('BlogEntry.AU'), $membername),]:

    new FileUploadField('AttachedImage', 'Upload an image', array (
    'buttonText' => 'Upload an Image')),

    (include the comma)

    3. In the same file, below the line 278 insert the following code:

    $blogentry->AttachedImage = $form->datafieldByName('AttachedImage')->dataValue();


    You're done!

    Now you can upload and attach an image in frontend to a blog entry.

  • nekrasov
    19/07/2011 12:19am (3 years ago)

    [CORRECTION]
    You don't need to add the 3 step above. With the line of code described in step 2 is enough.

  • juneallison
    22/07/2011 4:01pm (3 years ago)

    @nekrasov thanks so much for your help! I'll give this a try.

  • juneallison
    22/07/2011 4:41pm (3 years ago)

    @nekrasov Ok, so I downloaded an installed the module, rebuilt the database. I added in your bit of code and the upload button appears on the front end. When I attempt to add an image, it won't attach and I just have a message that says "No File Attached"

    Any suggestions? Thanks!

  • nekrasov
    22/07/2011 10:21pm (3 years ago)

    To help you better, I need to know:

    1. Which version of Silverstripe you are running?

    2. What is your development environment ? (XAMP, MAMP, WAMP, PHP version)

    3. Versions of Blog Module and Uplodify

    4. Check the memory allocation in php.ini
    search for: max_execution_time, max_input_time, memory_limit, post_max_size, upload_max_filesize
    and try to increase their values.

    I remember that in a recent version of Silverstripe there were problems with the extensions JPG or JPEG (uppercase) when you were trying to upload an image.

    With the release of Silverstripe 2.4.5: Bugfix: Valid file uploads with uppercase extensions blocked from being web accessible

    Check the changelogs: http://doc.silverstripe.org/sapphire/en/changelogs/2.4.5

    I hope you find this information helpful.

  • Matt Clegg
    26/07/2011 1:24pm (3 years ago)

    @juneallison You should really use;"new ImageUploadField" instead of "new FileUploadField". It might be better if you raise a forum ticket for your issue (as it sounds like it relates to Uploadify)? You may also get more help over there?

    @nekrasov -If you read through the above article it will show decorating (override or overload) a module -instead of hacking away at files.

    Also the idea of using <% if AttachedImage %> is so it follows standard with; http://www.ssbits.com/snippets/2009/resizing-an-image-in-a-custom-img-tag/

  • nekrasov
    26/07/2011 5:38pm (3 years ago)

    @juneallison!

    OK, I don't know why you can't upload the image with uplodify.

    But there is another option to achieve this:

    Use the class SimpleImageField instead of FileUploadField
    Summary: SimpleImageField provides an easy way of uploading images to Image has_one relationships.

    Just change the line that you added to BlogHolder.php with the following:

    new SimpleImageField('AttachedImage', 'Upload an image'),

    That's all!
    I really hope all of this works for you!
    -----------------------------------------------------

    @Matt Clegg
    You're right, if you want to customize the img tag or have major control then use:
    For example: <% if AttachedImage%><% control AttachedImage %><img src="AttachedImage(90,60).URL" title="some" class="foo" /><% end_control %><% end_if %>

    I have read the article, and I know how to decorate or extend modules but in the case of BlogHolder I have not found the way to override the class BlogEntryForm.

  • nekrasov
    26/07/2011 5:42pm (3 years ago)

    Correction to the above post:
    <% if AttachedImage%><% control AttachedImage %><img src="$CroppedImage(90,60).URL" title="some" class="foo" /><% end_control %><% end_if %>

  • Matt Clegg
    26/07/2011 10:39pm (3 years ago)

    @nekrasov http://www.sspaste.com/paste/show/4e2f3a4e8bfff -untested, but it should help?

  • Nobrainer Web
    06/09/2011 10:52pm (3 years ago)

    I just love finding a post like this, very basic and explaining how to use a decorator - K.I.S.S. is how we learn.

    Thanks Matt

  • Terry Apodaca
    15/09/2011 11:58pm (3 years ago)

    I know we shouldn't just copy/paste, but I did :(

    Line 12 in the Decorator will error. You are missing a closing ) parenthesis.

  • Matt Clegg
    25/09/2011 9:14am (3 years ago)

    see above; http://www.ssbits.com/tutorials/2011/adding-an-image-to-a-blog-post-using-decorators-and-the-silverstripe-blog-module#PageComment_643

  • BigMoose
    18/11/2011 9:55pm (3 years ago)

    This tutorial was fantastic. I am a total noob, and was able to get this up and running without any hassles, thank you so much!

    I do have one question though. How could this be extended to allow the uploading of more than one image per blog posting. Suppose a user wanted to upload 3 or 4 photos?

    Again, I am a total noob, so of course one could just make multiple image upload fields, but of course that too eventually has a limit depending on how many of these fields have been created. Might get a little ugly. So is there a way for the user to say they have more photos to upload for a single posting?

  • Matt Clegg
    18/11/2011 11:39pm (3 years ago)

    Hi BigMoose,

    Thanks for your feedback.

    If you want multiple images there are 2 simple options;
    http://www.sspaste.com/paste/show/4ec6ec1ae8764

    The second one requires that you install 'uploadify';
    http://www.leftandmain.com/silverstripe-modules/2010/08/26/uploadify/

  • BigMoose
    21/11/2011 1:36am (3 years ago)

    Thanks, I'll take a look at these two options.

  • BigMoose
    21/11/2011 3:43am (3 years ago)

    Okay, I am attempting option 2 -- using uploadify. All seems good except I am unsure as to how to make use of the images in my template. I assume MultipleImageUploadField creates an array, but I am ignorant as to how to use this $AttachedImage in the template file to show all the images in that array. Sorry for such noobie questions.

  • Matt Clegg
    21/11/2011 9:45am (3 years ago)

    It very similar to the example above; http://www.sspaste.com/paste/show/4eca1d56b376c

    Hopefully that will make sense for you

  • BigMoose
    21/11/2011 2:06pm (3 years ago)

    Brilliant! Thank you so Matt! This all makes sense now.

  • Matt Clegg
    21/11/2011 2:13pm (3 years ago)

    great -just remember to 'Like this post' so you can easily find it again (if you need to)

  • Dave2011
    25/12/2011 1:00am (3 years ago)

    Great help !!!!!!!!!

  • kBits
    13/06/2012 12:41am (3 years ago)

    Heeeeeelp. This code just slaughters my site. I'm using exactly as posted, fixed the typo with the missing ")" as noted, but still it gives me the white screen of death with "problem accessing the CMS". Using SS 2.4.5, what could I be missing?

  • kBits
    13/06/2012 12:42am (3 years ago)

    Can someone post this as a download with it actually working so I can see what the heck I did wrong?

  • Dan Marsden
    11/07/2012 11:33am (2 years ago)

    I have this script working in my blog module - however, is there a way to extend this to work in the blogadmin module (by Mark Guinn) too?

  • SSK
    18/03/2013 9:25am (2 years ago)

    Is this script compatible with Silverstripe 3.0.x? I get this when running dev/build:
    Parse error: syntax error, unexpected T_STRING, expecting T_FUNCTION in ../mysite/code/BlogEntryDecorator.php on line 3
    and I can't figure out what caused this.

  • rollins
    01/08/2013 12:28am (1 year ago)

    I found a way to do this in Silverstripe 3.0.2 and it's right there in the documentation. http://doc.silverstripe.org/framework/en/tutorials/2-extending-a-basic-site

    I already had a Blog page type set up so it was simply a matter of copying the BlogHolder.php and BlogEntry.php files into mysite/code and adding in the new image tab/uploader code and then integrating it into my theme.

    It tells you how to do everything in the tutorial for setting up a staff page.

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image Martijn van Nieuwenhoven
7 article image Darren-Lee
8 article image Roman Schmid
9 article image Matt Clegg
10 article image dalesaurus

View full leaderboard


Advertisement