Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Adding alt tag info and resizing custom ImageFields


Go to End


7 Posts   7615 Views

Avatar
Happysadhu

Community Member, 33 Posts

29 July 2009 at 4:47am

Hello,
I would like to be able to both specify alt tags, for accessibility reasons, and resize my custom ImageFields.

I know that I could do the following in my StaffHolder.ss template for adding unique alt tags:
<% control AllChildren %>
<li>
<div class="staffname"><h3>$Title</h3><</div>
<div class="staffphoto"><img src="$Photo.URL" alt="$AltText" /></div>
<div class="staffdescription">$Content</div>
</li>
<% end_control %>

Defining $Photo and $AltText in StaffPage.php as:

<?php
class StaffPage extends Page {
static $db = array(
'AltText' => 'Text'
);
static $has_one = array(
'Photo' => 'Image'
);

function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab("Root.Content.Images", new ImageField('Photo'));
$fields->addFieldToTab("Root.Content.Images", new TextField("AltText"));
return $fields;
}

But how would I also set a proportional width in the ss file (in this case, 150 pixels wide)?
I am aware of this function: $Photo.SetWidth(150) -- but not how to combine the various imagefields functions.

In other words, how can I both set the width and add unique alt tags to my custom image fields in my templates?

Thanks,
Sam

Avatar
Double-A-Ron

Community Member, 607 Posts

29 July 2009 at 8:22am

Edited: 29/07/2009 8:27am

Try:

<% control AllChildren %>
<li>
<div class="staffname"><h3>$Title</h3><</div>
<% control Photo.SetWidth(150) %>
<div class="staffphoto"><img src="$URL" alt="$Top.AltText" /></div>
<% end_control %>
<div class="staffdescription">$Content</div>
</li>
<% end_control %> 

http://doc.silverstripe.org/doku.php?id=built-in-page-controls - about 3/4 of the way down.

Cheers
Aaron

Avatar
Happysadhu

Community Member, 33 Posts

29 July 2009 at 8:51am

Hi,
Thanks for your quick response!

Following your code, I get the image to output at the specified width of 150 pixels, but no AltText?
I've tried both <img src="$URL" alt="$Top.AltText" /> and "img src="$URL" alt="$AltText" />.
No Luck either way. Any more ideas?

Sam

Avatar
Happysadhu

Community Member, 33 Posts

29 July 2009 at 9:22am

Hi again,
As a test, I replaced $Top.AltText with $Top.Title as in <img src="$URL" alt="$Top.Title" />

<% control AllChildren %>
<li>
<div class="staffname"><h3>$Title</h3></div>
<% control Photo.SetWidth(150) %>
<div class="staffphoto"><img src="$URL" alt="$Top.Title" /></div>
<% end_control %>
<div class="staffdescription">$Content</div>
</li>
<% end_control %>

What was outputted was not the title of each child page (each Staff Page) - as it does with <div class="staffname"><h3>$Title</h3></div> - but the title of the Staffholder page. The Staffholder page has no alt text. So maybe that's why $Top.AltText within the control loop is not working (i.e. empty)? Perhaps the function $Top completely breaks out of the loop to get the variable defined -- in this case, both the <% control AllChildren %> loop and the nested <% control Photo.SetWidth(150) %> loop?

Looking forward to more suggestions,
Sam

Avatar
martimiz

Forum Moderator, 1391 Posts

1 August 2009 at 1:39am

Hi Sam,
I was looking for the same thing. Don't know if you've found a solution yet, but this slight change seems to be workings:

<div class="staffname"><h3>$Title</h3></div>
      <div class="staffphoto">
            <img src="<% control Photo.SetWidth(150) %>$URL<% end_control %>" alt="$Title" />
      </div>
      <div class="staffdescription">$Content</div> 

Avatar
Happysadhu

Community Member, 33 Posts

2 August 2009 at 2:19pm

Edited: 02/08/2009 2:26pm

Hi,
I'll have to give your suggestion a try - eloquently simple.

My solution is a little more involved.

First I added a Page_Photo array and then a function at the bottom of my staffpage.php which defines Page_Photo after the Page_Controller. (Page_Photo is an arbitrary name, you can put what you want.)
....
static $has_one = array(
'Photo' => 'Page_Photo'
);
}

class StaffPage_Controller extends Page_Controller {
}

class Page_Photo extends Image {
function generateSmallImage($gd) {
$gd->setQuality(100);
return $gd->resizeByWidth(150);
}
}
?>

In my StaffHolder.ss template I added the following:

<% control AllChildren %>
<li>
<div class="staffname"><h3>$Title</h3></div>
<div class="staffphoto"><img src="$Photo.SmallImage.URL" title="$TitleText" alt="$AltText" /></div>
<div class="staffdescription">$Content</div>
</li>
<% end_control %>

If I wanted I could have added more functions to the php file like:

function generateLargeImage($gd) {
return $gd->resizeByWidth(300);
}

So, that I could have the option of doing this in my ss template file <div class="staffphoto"><img src="$Photo.LargeImage.URL" title="$TitleText" alt="$AltText" /></div>

I figured this out largely from the following recipe:
http://doc.silverstripe.com/doku.php?id=recipes:customising_image
This document gives you some image manipulation functions
http://doc.silverstripe.org/doku.php?id=image

I found the following comment added at the bottom of http://doc.silverstripe.com/doku.php?id=gd interesting:
Blue Skies writes "In combining some functions I had the problem that doing it the "one $gd per line" way resulted in some functions not working or some functions overriding effects of previous functions.

As it turns out: some functions do create a new instance, others don't. So you have to chain certain functions to get the desired effect. For example, to use a resize, turn to greyscale and a set quality in one function, use:"

public function generateLogoGrey($gd) {
$gd = $gd->PaddedResize(70, 30)->greyscale();
$gd->setQuality(100);
return $gd;
}

The main advantage of creating a image class function, as above, is that you can combine several functions. However, regarding my original post, where I simply wanted to resize the image and have custom alt and title tags the solution suggested in the above post looks much easier to implement.

Sam Miller

----------
My complete StaffPage.php looks like:

<?php
class StaffPage extends Page {
static $db = array(
'AltText' => 'Varchar(50)',
'TitleText' => 'Varchar(50)'
);
static $has_one = array(
'Photo' => 'Page_Photo'

);

function getCMSFields() {
$fields = parent::getCMSFields();
$fields->addFieldToTab("Root.Content.Images", new ImageField('Photo'));
$fields->addFieldToTab("Root.Content.Images", new TextField("TitleText"));
$fields->addFieldToTab("Root.Content.Images", new TextField("AltText"));
// $fields->removeByName("Sidebar");
$fields->removeFieldFromTab("Root","Sidebar");
return $fields;
}

static $defaults = array(
'ShowInMenus' => false
);
static $allowed_children = array('none');
}

class StaffPage_Controller extends Page_Controller {

}

class Page_Photo extends Image {

function generateSmallImage($gd) {
$gd->setQuality(100);
return $gd->resizeByWidth(150);
}
}
?>

Avatar
martimiz

Forum Moderator, 1391 Posts

2 August 2009 at 8:21pm

Hi Sam,
I confess I took a long (though slightly different) road too at first - didn't see what was right in front of me :-) I just really wanted to keep resizing out of the code - or the CMS..