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 (indirectly)] Can't get $Top to work in control loop for custom properties/methods


Go to End


6 Posts   1872 Views

Avatar
Sparrowhawk

Community Member, 33 Posts

15 July 2010 at 12:05pm

Edited: 17/07/2010 8:14am

Hi,

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 %>
</div>            
<% 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?

Thanks

Avatar
Sparrowhawk

Community Member, 33 Posts

15 July 2010 at 12:06pm

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

Avatar
Sparrowhawk

Community Member, 33 Posts

16 July 2010 at 11:01pm

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

Avatar
Sparrowhawk

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.

Avatar
dhensby

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();

Avatar
Sparrowhawk

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.