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* - Can't seem to use Summary() and other data function on Virtual page properties


Go to End


3 Posts   1599 Views

Avatar
Double-A-Ron

Community Member, 607 Posts

4 March 2013 at 7:30pm

Version 2.4

I have a virtual page derived from a normal page. This normal page has a text field. You could even take the default Content field on a page as an example.

I then have a holder page to display a list of these pages and allow the user to click through to the page itself. This holder loops these using:

<% control Children %>
    $Content.Summary(40).
<% end_control %>

In the template, I am truncating the text in Content using $Content.Summary(40).

This works as expected where the child is a real data object. But when it is a virtual page, the output is blank. However in these cases if I just change the template to be $Content (without calling Summary), the text is output in full.

I found that the above is true for any native function supported by the datatype (in this case, and HTMLField)

Is this a framework limitation? Is there a workaround?

Avatar
Double-A-Ron

Community Member, 607 Posts

4 March 2013 at 8:22pm

Edited: 04/03/2013 8:32pm

Found the solution to this, and it seems that this is a Framework limitation.

I had to replace $Children with a custom method in the holder class file that detected if the current child was a virtual page, and load the real data object from the master content ID.

MyHolder.php - MyHolderController Class

        public function realPages() {
		$children = $this->Children(); 
		$return = new DataObjectSet(); 
		foreach ($children as $child) 
		{ 
			if($child->ClassName == 'VirtualPage') {
                                // Current child is virtual, get the real page
				$virtualPage = DataObject::get_by_id('VirtualPage', $child->ID); 
				$realPage = DataObject::get_by_id('Page', $virtualPage->CopyContentFromID);
			} else {
                                // Current child is real, just use it as it is
				$realPage = $child;
			}
		   $return->push($realPage); 
		} 
		return $return; 
	}

Then in the template change

<% control Children %>

To:

<% control realPages %>

The one thing with this is that the URL link and ID is that of the Virtual pages master, so I have to come up with some funky setters there.

Avatar
Double-A-Ron

Community Member, 607 Posts

4 March 2013 at 9:24pm

This is turning into a bit of a nightmare actually. After doing the above, I cannot find a way to provide the loop with the virtual page's $Link and $ID. Obviously the new method is returning the object of the page the virtual one derives from, but there doesn't seem to be a way to return a mix of the virtual page properties and the real page's properties that actually support using the built in methods.