phpfunctionsortingsilverstripepagecontrol

Silverstripe 3: create page control function to get images from grandchild pages and sort all randomly


I'm trying to get a specific image ($FeaturedImage) from every grandchild page (GalleryPage.ss) of my Portfolio Page (PortfolioPage.ss) and display them in a random order.

I can get the images using the template easily enough. PortfolioPage.ss

<% loop Children %>
 <% loop Children %>
   <% loop FeaturedImage %>
      <img src="$Url"></>
   <% end_loop %>
 <% end_loop %>
<% end_loop %>

But this will display them in the order of the pages in the menu.

After some research it seems best to create a function in the page controller, but I'm not sure how to write this.. (anyone with a link to documentation / tutorials on these would also be great).

Examples of similar code found so far: get Dataobjects from Children - SilverStripe 3.1 http://www.silverstripe.org/template-questions/show/23296

Silverstripe docs: http://doc.silverstripe.org/framework/en/topics/datamodel

I'm just not sure how to apply this to my code..thanks


Solution

  • Basically you need to create a function in your Portfolio Page Controller (or in whatever page you need this logic to be).

    Here are 2 examples. First one just gets all the existing FeaturedImage from the database and returns then in random order:

    function AllFeaturedImages()
    {
        return FeaturedImage::get()->sort('RAND()');
    }
    

    And this one get all the FeaturedImage from the page's children's children and return them in random order:

    function DescendantFeaturedImages()
    {
        $featuredImages = array();
    
        foreach ($this->Children() as $child)
        {
            foreach ($child->Children() as $grandChild)
            {
                $images = $grandChild->FeaturedImage();
                if ( $images )
                {
                    $featuredImages = array_merge( $featuredImages, $images->toArray() );
                }
            }
        }
    
        shuffle($featuredImages);
    
        return ArrayList::create($featuredImages);
    }
    

    If the FeaturedImage relation is just a has_one, this changes a little bit:

    function DescendantFeaturedImages()
    {
        $featuredImages = array();
    
        foreach ($this->Children() as $child)
        {
            foreach ($child->Children() as $grandChild)
            {
                $image = $grandChild->FeaturedImage();
                if ( $image )
                {
                    array_push( $featuredImages, $image );
                }
            }
        }
    
        shuffle($featuredImages);
    
        return ArrayList::create($featuredImages);
    }
    

    Then in your Portfolio Page template you can just loop through the FeaturedImage by calling the function name. So here, either $AllFeaturedImages or $DescendantFeaturedImages. In your case you'll get something like:

    <% loop $DescendantFeaturedImages %>
        <img src="$URL"/>
    <% end_loop %>
    

    I could find one example in the SilverStirpe tutorials using a Controller function: http://doc.silverstripe.org/framework/en/tutorials/2-extending-a-basic-site

    Let me know how this goes.