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.

Archive /

Our old forums are still available as a read-only archive.

Moderators: martimiz, Sean, biapar, Willr, Ingo, simon_w

Different top images according to top level menu


Reply


5 Posts   3031 Views

Avatar
Bitmand

Community Member, 5 Posts

8 June 2007 at 10:16am

Edited: 08/06/2007 10:16am

Hi there,

I have my first SS site up'n'running, but I am not sure how I solve this problem.

The image at the top of the page should change according to top level menu item.

I suspected something like looping through Menu(1) and if $LinkingMode is 'current' or 'section' then display an image like <img src="$Link"..> ($Link should then point to some static images).

Actually, using $Link in src for the img tag, probably isn't the greatest idea .. there has to be a better way .. or?

Is this at all the way to do it? :)

Avatar
Nathan Cox

Community Member, 99 Posts

8 June 2007 at 12:47pm

Hi,

I had a similar issue with a site I'm working on...each page had a banner at the top, and I wanted it to inherit the banner image from it's parent page if it didn't have one set, and so on up the tree, then to the homepage as a last resort. I don't know if what I did is the BEST solution, but it works for me.

What I did was add a "banner" image field to the Page object so users can select the banner nicely in the CMS, then I added a getBanner() method to the PageController that you call in the template with $getBanner.

Basically what it does is start at the current page and loop through $page->getParent() until one of them has a banner, and return it's Link. I put the link into style="background-image:url($getBanner);", since that's what worked best for my setup.

Of course, I'm probably overcomplicating it...there might even be an easier way to get an object's oldest ancestor.

Avatar
Ingo

Forum Moderator, 801 Posts

10 June 2007 at 1:56pm

@nathancox: thats exactly the way we came up with for several silverstripe-clients as well - so not necessarily overcomplicated :)

Avatar
blueskies

Community Member, 42 Posts

16 February 2008 at 12:35am

Edited: 16/02/2008 12:44am

@nathancox

Could you please post some example code?! I'm dying to do the exact same thing but I can't find the exact syntax on how to write the code that loops through the parents, etc. Or could you point me in the right direction (the docs are still a bit difficult to search through)?

Avatar
blueskies

Community Member, 42 Posts

16 February 2008 at 12:08pm

Ok. After banging my head on the desk a few times trying to figure out the syntax (I'm a noob with the Silverstripe framework) here's my solution:

Case: This shows 2 header images which are added to the Page PageType. If they're not available on the current page, we'll search through all the parents to find some.

In Page.php

class Page extends SiteTree {...
static $has_one = array(
      'HeaderImage1' => 'Page_Image',
      'HeaderImage2' => 'Page_Image',
   );
... }


Notice the reference to the extended Page_Image class, and not the Image class (see Page_Image class below).

In the Controller class we need to grab the header image, if we have one. If we don't have one, then we'll call a recursive function which loops through parents, and parents of parents, etc untill we find a header image we can use. The whole $Number thing is simply because we had 2 headerimages in this particular case and wanted a generic function.

class Page_Controller extends ContentController {...
   function grabHeaderImage($Number) {      
      $HeaderImage = $this->getComponent('HeaderImage'.$Number);
      
      if(!empty($HeaderImage->ID)){
         $HeaderImage = $HeaderImage->Thumbnail();// see the Page_Image class below to see what ->Thumbnail() does
      } else {         
         $HeaderImage = $this->getParentHeaderImage($this, "HeaderImage".$Number);
         $HeaderImage = $HeaderImage->Thumbnail();      
      }      
      return $HeaderImage;
   }
   
   /* This is a recursive funtion used in grabHeaderImage: It requests the HeaderImage1 of the parent
      If it's found, it's returned. If it's not found, it calls itsself again   */
   private function getParentHeaderImage($CurrentPage, $HeaderNumber){      
      $Parent = $CurrentPage->Parent;      
      
      if(is_object($Parent)){
         $HeaderImage1 = $Parent->getComponent($HeaderNumber);
         
         if(!empty($HeaderImage1->ID)){
            return $HeaderImage1;
            // We found the current header! Let's return it!
         } else {
            return $this->getParentHeaderImage($Parent, $HeaderNumber);
            // We didn't find a header,so we have to call ourselves again
         }
         
      } else {
         return false;
      }
   }

...}


At the end of the Page.php (after we extend the controller) we want to work some magic on the image with resizing,etc.

class Page_Image extends Image {...
   // define different GD functions to resize uploaded photos, see the GD page in the
   // SilverStripe documentation for different functions for resampling   
   function generateThumbnail($gd) {
      $gd->setQuality(90);
      return $gd->resizeByWidth(288);
   }   
...}


And in the template the real magic happens:

<div class="headerimg1" style="background:url(<% control grabHeaderImage(1) %>$URL<% end_control %>) top center no-repeat;"></div>                        
<div class="headerimg2" style="background:url(<% control grabHeaderImage(2) %>$URL<% end_control %>) top center no-repeat;"></div>


Note that if you don't need the parent->parent loop then calling the following from the template works with the new generateThumbail function:
$HeaderImage1.Thumbnail.URL

Inspired by: http://doc.silverstripe.com/doku.php?id=imageupload

Hope this helps somebody! Any comments/suggestions are welcome :-)