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.

Archive /

Our old forums are still available as a read-only archive.

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

Custom Controls - Totally lost


Go to End


18 Posts   8423 Views

Avatar
Jona

Community Member, 19 Posts

3 September 2008 at 3:12pm

Edited: 03/09/2008 3:14pm

Hello community,

I am a new user of SS and have found it very powerful. However, I can't seem to find straight answers by searching (which I have been doing here and on the Wiki for about 7 hours now). I have seen _some_ code around here that explains how to add a custom control, but when I tried it, it didn't work.

Basically, I just want to be able to set $TemplateControlVariable to whatever value I want and use it across all Pages. Here's what I have.

class Page_Controller extends ContentController {
	function init() {
		parent::init();
		
		Requirements::themedCSS("layout");
		Requirements::themedCSS("typography");
		Requirements::themedCSS("form");
	}

	function TemplateControlVariable() {
    	return "test";
	}
}

Of course, I have a lot more in mind than something so simple, but getting this piece right is a major step. I'm familiar with PHP but not SS.

Thanks in advance for any help you can provide.

Avatar
ajshort

Community Member, 244 Posts

3 September 2008 at 4:02pm

Edited: 03/09/2008 4:04pm

Hey Jona,

you have the right idea - adding a method to a class will make it available in the $MethodName format whenever the class is rendered into a template (as classes, rather than a stack of variables are rendered using the SS template engine).

However, your problem could be one of two things:

1) You are adding the code to the wrong class. You have added your method into the Page_Controller class. This is fine when rendering the controller, but the method will not show up when you render a plain Page model (the Page class).

This will be the case when using a DataObject::get('Page') or similar, as it returns the Page model object rather than first linking it to a controller. Maybe try adding your method to the model rather than the controller.

2) Your template is not updating, SilverStripe parses a template into intermediate PHP code to allow for faster execution, then caches this. In order to force a cache rebuild, just append ?flush to the end of your URL.

edit: formatting messed up

Avatar
Sean

Forum Moderator, 922 Posts

3 September 2008 at 6:38pm

Edited: 03/09/2008 6:41pm

I don't see anything wrong with that example - even if it's in Page_Controller the template for Page.ss should still be able to render that template variable...

It's more a matter of standard to place more methods in the model over the controller, as opposed to actual requirement. There's also advantages like being able to call methods on the Page object, when using it in other classes.

Avatar
Jona

Community Member, 19 Posts

4 September 2008 at 6:58am

Thank you for your responses.

Ajshort, after reading your suggestion, I thought it may have something to do with inheritance or the file system (a file missing, uploaded to the wrong location, or overridden by another file). To ensure this isn't a simple placement error, let me explain the structure I have.

I am viewing the HomePage, an extension of Page. In my themes/themename/ directory, I have code/HomePage.php, code/Page.php (where the code I posted can be found), templates/HomePage.ss, templates/Page.ss, templates/Layout/HomePage.ss, and /template/Layout/Page.ss. In essence, edits I make to the templates/Page.ss file are reflected both on the HomePage and all other pages, with the exception of the content ($Layout), which differs between the HomePage and all other pages. If this is confusing (or poorly written, as the case may be), I can perhaps upload a .zip file that more clearly explains where I'm coming from.

Assuming that the structure above is correct, I have been putting the Page_Controller class's extension of ContentController in code/Page.php. Ajshort, you pointed out that this works when rendering the controller -- if I am looking at the HomePage, am I correct in my assumption that the controller is, in fact, being rendered? If not, could please explain how I would create a class extension of the model instead?

Thankfully, this does not appear to be a caching issue. I would feel quite silly if it was! The Wiki poignantly noted that using a ?flush=1 query string would reset the cache. (I have found that shift+reload is necessary most of the time despite that, however.)

Sean, your last comment hinted at something somewhat unrelated, but interesting. I was under the impression that it was more pragmatic (and conventional) to use private and protected variables to prevent the illegal reading or overwriting of variables among classes and/or subclasses. Am I misunderstanding you, or is this structure unique to SS?

Avatar
Sean

Forum Moderator, 922 Posts

4 September 2008 at 8:27am

Jona, that is also possible. However, if you do want to share a method between classes then it gives you that possibility, as functions in php obviously default to public. You can still make them private or protected as you see fit, however.

Avatar
Jona

Community Member, 19 Posts

4 September 2008 at 2:14pm

Ah, I see. That makes sense.

Do you have any recommendations concerning my other question or any idea as to why my current setup is not working as expected?

Avatar
spenniec

Community Member, 37 Posts

4 September 2008 at 2:24pm

Jona

You wrote

I am viewing the HomePage, an extension of Page. In my themes/themename/ directory, I have code/HomePage.php, code/Page.php (where the code I posted can be found)

If your code is under your theme directory then I'm pretty sure SS isn't loading it. Have you tried it under under mysite/code...

Avatar
Jona

Community Member, 19 Posts

4 September 2008 at 2:39pm

I am using a custom theme. I am seeing the appearance of the theme just fine -- it works as intended (although it took some work to figure out how to get that to occur). I did not want to keep files in mysite/ or tutorials/, so naturally I moved them to themes/myThemeName. When I view the homepage and subsequent pages on my site on the user side, I am seeing my theme -- it is loading the CSS and HTML, and when I edit my theme files, the changes are reflected on what appears on the user side of the web site. I am confident that my theme is working correctly at this point. What I do not understand is why my methods are not being picked up by SS -- the reference to my method is removed from the HTML that is output by SS entirely. Instead of outputting the method result (in this case, the string "test"), it outputs an empty string (""). Presumably this has to do with PHP's default behavior regarding Boolean values -- apparently, SS is calling for a method that it cannot find, and when it cannot find it, it returns a Boolean false, which equates to an empty string in PHP.

It would seem, under these circumstances, that there is something wrong with the code I have in Page.php. That, or possibly no inheritance is occurring on HomePage.php (which is an empty extension of Page.php), but I have no way to test this as the method is not working on HomePages or Pages. (In other words, the function should work on Pages even if it doesn't work on the HomePages, but I am not seeing it work in either case and cannot therefore conclude whether inheritance is working as expected.)

Go to Top