Jump to:

17452 Posts in 4473 Topics by 1971 members

Archive

SilverStripe Forums » Archive » Different top images according to top level menu

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

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

Page: 1
Go to End
Author Topic: 2967 Views
  • Bitmand
    Avatar
    Community Member
    5 Posts

    Different top images according to top level menu Link to this post

    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?

  • Nathan Cox
    Avatar
    Community Member
    99 Posts

    Re: Different top images according to top level menu Link to this post

    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.

  • Ingo
    Avatar
    Forum Moderator
    801 Posts

    Re: Different top images according to top level menu Link to this post

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

  • blueskies
    Avatar
    Community Member
    42 Posts

    Re: Different top images according to top level menu Link to this post

    @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)?

  • blueskies
    Avatar
    Community Member
    42 Posts

    Re: Different top images according to top level menu Link to this post

    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

    2967 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.