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.

Template Questions /

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

[solved (indirectly)] Can't get $Top to work in control loop for custom properties/methods

Go to End

6 Posts   1527 Views


Community Member, 33 Posts

15 July 2010 at 12:05pm

Edited: 17/07/2010 8:14am


I cannot get access to a top level controller's methods or properties in an IF statement within a control loop:

Here is the code in the template:

<% control Children %>
    <div class="nav-item">
    <% if ID == Top.GetVideoPageId %>
        <a class="navigation-link-selected" href="$Top.URLSegment/?vpid=$ID">$MetaTitle</a>
    <% else %>
        <a class="navigation-link" href="$Top.URLSegment/?vpid=$ID">$MetaTitle</a>
    <% end_if %>
<% end_control %>

The current controller has a method called GetVideoPageId which just returns the VideoPageId property.

The issue is this line of code:

<% if ID == Top.GetVideoPageId %>

When I run this, I get a blank page, and no error log entries. I've put the site in dev mode and no joy there either, I get the same problem

Initially I tried

<% if ID == Top.videoPageId %>

to access the property directly with the same results.

I thought Top could be used to access the current controller from within a template control loop? Where I use $Top in the URLs, it is working fine. Have I just got the syntax wrong for the If statement?



Community Member, 33 Posts

15 July 2010 at 12:06pm

I should add that both the property and the method have public scope.


Community Member, 33 Posts

16 July 2010 at 11:01pm

Anyone? Please don't condemn me to using global variables to track this id! ;)


Community Member, 33 Posts

17 July 2010 at 8:14am

I did it another way: I identified the SQL supplied when doing a DataObject::get() call on a page type, converted this into a SQLQuery object, and added an extra field which returned 1 if the id == videopageid otherwise 0.

In addition, I checked for the stage GET var, and if it set to 'Stage' , I strip out the _Live suffixes form table names.

Seems like I'm using a sledgehammer to crack a nut though - there must be a better way.


Community Member, 253 Posts

17 July 2010 at 9:40am

Edited: 17/07/2010 9:40am

Damn, it sucks no one has helped you out with this.

First thing i would start with is comparisons in the templating language are done with a single '='. Second to that is that you cant compare variables to variables in the template either (i think).

The best way to solve this problem is to create a function in your page controller that does the comparison for you and returns true or false. Then just address that function in the <% if %>

something like:

return $this->ID == $this->GetVideoPageId();


Community Member, 33 Posts

20 July 2010 at 4:05am

Hi Pigeon,

Many thanks for the reply.

I thought = and == were equivalent in the templating engine? Clearly I was wrong, which would explain a few things :)

I did finally realise myself that you cannot compare variable with variable. I am indeed using a function - the problem was mainly that because I am always showing the holder page, and only embedding the data from the Video Pages below depending on which page had been selected, I could not get the page record to check against the current selected id (passed to the top level controller via the url)

I solved it as above, by including the currently selected page id on every row in a query and then checking for equality of id=current_video_page_id in a function which I then called in the template, but had to use SQLQuery rather than DataObject as the latter did not allow me to customise the field list.

Since then however, after reading a bit more deeply in the Silverstripe book's later chapters, I think that what I really should have used was a DataObjectDecorator instance. I'm not 100% sure of that as I only read it last night at around 2AM, so I was a little sleepy, but I think that that may be right.

Again, many thanks for your assistance.