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.

Template Questions /

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

[SOLVED] Accessing Children functions in Template


Go to End


3 Posts   2877 Views

Avatar
Double-A-Ron

Community Member, 607 Posts

4 May 2009 at 12:28pm

Edited: 04/05/2009 2:49pm

I'm sure I've been here before, but can't find any old posts.

I have the following structure for a global ski resort website that I have inherited:

1. A CountryPage
2. A ResortPage (A child of CountryPage)
3. A HotelPage (A child of ResortPage)

Although these are related to each other in the site tree as actual pages, the information on the last one, HotelPage, is actually displayed one after the other on the ResortPage.

So a simplified setup of ResortPage.ss is as follows:


<!-- Resort Info -->
$Name
$Content

<!-- Hotels in this Resort -->
<% control Children %>
$Name
$Content
$GetPricing
<% end_control %>

This is all working well except for the "GetPricing". This is a function on HotelPage.php that returns a HTML table using data from an element on the HotelPage called "Pricing". This is a TableField, which in turn is an extension of DataObject.

This is the code in HotelPage.php

function GetPricing() {
		$submitLink = DataObject::get("Pricing", "ThispriceID = $this->ID");	
		$output = $this->makeTable($submitLink);
		return $submitLink;
	}
	
private function makeTable($PricingData) {
// Code for intelligently creating table based on $PricingData
{

This works perfectly if I look at the HotelPage directly, but the function isn't called when I'm trying to list these pages on the ResortPage using <% control Children %>. So I must have a scope problem.

Can anyone see a way around this?

Cheers
Aaron

Avatar
Double-A-Ron

Community Member, 607 Posts

4 May 2009 at 1:19pm

Some headway made:

I put the GetPricing function in the Parent ResortPage.php instead, and called it using $Top.GetPricing.

Now I need to work out how to send the ID of the current child to the function, which I beleive is a gotcha in SS. Ideally I want the command to be $Top.GetPricing({$ID}) however this doesn't pass the value, it simply outputs "(1529)" where the number IS the correct ID for the current record.

Any thoughts?

Cheers
Aaron

Avatar
Double-A-Ron

Community Member, 607 Posts

4 May 2009 at 2:49pm

Got it with a work around.

On the ResortPage.php file, under the ResortPageController class, I add a function called "getHotels". This function creates a custom DataObject, calls the function that creates the HTML pricing table, and adds that HTML as a field to the custom DataObject before returning.

ResortPage.php

function getHotels() {
	
		$CustomHotelPageSet = new DataObjectSet(); //Result dataset 
		
		$HotelDataSet = DataObject::get("LocationHotelPage", "ParentID = " . $this->ID);
		foreach ($HotelDataSet as $HotelDataObject) {
      $PricingHTML = $this->getPricing($HotelDataObject->ID);
      $item = $HotelDataObject->customise(array('PricingHTML' => $PricingHTML ));
			$CustomHotelPageSet ->push($item);
		} 
    
    return $CustomHotelPageSet;
	}

function GetPricing($hotel_id) {
      $submitLink = DataObject::get("Pricing", "ThispriceID = " . $hotel_id);   
      $output = $this->makeTable($submitLink);
      return $submitLink;
   }
   
private function makeTable($PricingData) {
// Code for intelligently creating table based on $PricingData
{

Then, on my template, it's as simple as this:

ResortPage.ss

<!-- Resort Info -->
$Name
$Content

<!-- Hotels in this Resort -->
<% control getHotels %> <!-- Note we no longer control Children here, but my custom function -->
$Name
$Content
$GetPricing
<% end_control %>

Hope that helps someone

Cheers
Aaron