Changing the view from the controller *Technical, probably for c5 devs*

Permalink 1 user found helpful
One of the things that's always bothered me immensely about c5 is that the MVC model isn't what I'm used to (granted, mostly based on ASP.NET). Specifically, the controller doesn't control. Instead, it's called from the view in order to set up some variables (it's more of an include).

There are many theoretical arguments against this, but the practical result is that in cases where a single "page" (what I would assume to be the controller, but let's say "URL") could have >1 very different outputs, the view ends up with a really ugly branching. This occurs in a few c5 core views and drives me nuts. A few pages that basically look like:
if ($var [set from controller] == "1") {
[an entire webpage worth of HTML code]
} else if ($var == "2") {
[another webpage worth of HTML code]
} else {
[ditto]
}


I finally got so sick of this that I started mucking in the code, and think I found a somewhat simple solution, but I want advice as to whether this will cause unforeseen problems.

Right now, view->render() calls controller->setupAndRun() which calls my controller, stuff happens, controller returns, then the page is rendered based on the Page object, which was initially passed into render().

I've found that, in my controller, I can call:
$view = Page::getCurrentPage(); [this gets a reference to the global page object]
$view->cFilename = '/dashboard/lfc/plane.php';


And then, because of references, the render() method uses my new filename.

I don't mind getting into discussions about whether or not I'm doing the best thing, but I'm mostly interested in whether this hack will work in the long term.

Thanks,
James

jshannon
 
DavidMIRV replied on at Permalink Reply
DavidMIRV
First things first, editing the core itself is usually never a good idea I've found. If a major security or other major class bug is found you loose your upgrade-ability. At least without some level of running a diffs. speaking from experience.

Regarding the MVC. I totally agree and voiced this 2 years ago but probably on the IRC channel and not formally, Never continued because I have found you can override the views of your single pages.

$this->render('/path/to/my/view');

I use this literally all the time (Who wants to create a controller for every separate CRUD operation anyway?!)


Regards..
DavidMIRV replied on at Permalink Reply
DavidMIRV
Furthermore there is even a method to get this working for separate block rendering from its controller but as I recall its a bit more complicated, nothing major though.
jshannon replied on at Permalink Reply
jshannon
Hi. Thanks for the reply.

I completely agree about not modifying the core. Even though I'm mucking with the core, I'm not modifying it. What I'm doing getting /the/ Page instance, then changing one of its variables. So, yes, I realize that this variable name or purpose could be changed...

With that being said, I have two questions with your solution that I'd like your view on, because I might be wrong:

1. First, it seems a bit messy. The stack is basically View->render() -> Controller->setupAndRun() -> YourController->Action() -> View->render(). But, I guess there's no fundamental problem with this, and it's just the way it has to happen when the view comes first.

2. More importantly, I played with your solution a bit and followed the code and can't find a way to make it play nice with controllers that are part of a package or singles that are in the dashboard. It looks in
DIR_FILES_CONTENT which is DIR_BASE . '/single_pages'

so I did
$this->render('../packages/lerteco_flyingclub/single_pages/dashboard/lfc/plane');

But, oddly, this ends up with the front-end template rather than the dashboard. Have you ever tried with a dashboard?

Thoughts?

Thanks,
James