Jump to content

template file as controller


pwired
 Share

Recommended Posts

Hi, in the wiki and forum I read about using a template file as a controller and then use any file to output. But it is very hard to find an example with code that shows how a template file is used as a controller and then how another file is used to output. Or maybe I already have seen it but have not recognized the code in it used as such. If anyone can show me an example with code, thanks.

Link to comment
Share on other sites

There's more than one way to achieve this and you can find more comprehensive examples around the forum, but this is roughly the concept I've been using (simplified a lot for this example.)

Let's say that you put this in your home template (/site/templates/home.php):

<?php
// this is your template file, or a controller if you will:
$view = new TemplateFile();
$view->some_param = "PW";
$view->filename = $config->paths->templates."views/{$page->template}.php";
echo $view->render();


Then you add a view file corresponding to filename you've defined at controller (in this case /site/templates/views/home.php):
 

<?php
// this is your view file:
echo "<h1>I'm view for {$page->template} and title is {$page->title}!<h1>";
echo "<h3>{$this->some_param} rocks!</h3>";
echo $page->body;

This should be a working example, though not very useful yet. You could expand it by having your view files (or templates themselves) include other files ("partials" or just "include files" depending on terminology, for a global header and footer etc.) or have multiple view files for each template.. and so on.

Of course you could also achieve similar results with includes instead of TemplateFile object, though I personally like how this method separates controller from view layer. As always, with ProcessWire imagination is your only limit :)

  • Like 3
Link to comment
Share on other sites

Thanks a lot for your example code. Splitting it up for controller and view, like you did, now it starts to make sense for me how the two are related. I still have to get used on all that api and php.

Link to comment
Share on other sites

Dear All,

I was thinking about this over the weekend. One of the things I've run into with some MODX web clients is that they wanted to have many different options for different template files, for various sections or page types. They were able to create a page and switch the template files at will. I'm considering this method:

- add a custom field: "template_file_name" (and a corresponding page to store the individual values in)

- add a select field to most of the templates, so that the template_file_name is accessible to all the pages, to choose the template file used for display purposes.

- create a small set of templates, containing my custom fields (perhaps 3, one for home, one for section lists, and one for articles)

- create corresponding, *unchanging* template files that have nothing in them, except the code to pull in the template file name from the page, followed by an include statement to run the custom template file. I would also set the user role to not allow switching the regular templates.

It seemed to me that this would provide the flexibility of having any number of custom template files that could be swapped out easily, without messing with the underlying template and field collection.

I also have to say that it seems that it would be easier if the "template" was named something different, e.g. "field collection definition". It's really quite different than the function of the template files, but the names are so close that it's easy to misspeak. It's also initially confusing.

Any thoughts?

Peter

  • Like 1
Link to comment
Share on other sites

Something like that would be fine. If i understand correctly you want clients who create a page to be able to choose some predefined options for the way the content is displayed on the front-end. I think you envision about the same but anyway:

Create a template called 'layouts'. This is only a container so only the title field needed and no template file.

Create a template called 'layout'. This is only for other pages to reference, so only the title field needed and no template file.

Create a page with template 'layouts'. Title can be anything, but layouts would probably make sense.

Create children pages with template 'layout' for each layout you want. Fill in some descriptive titles: 2 Columns, 3 Columns, 5 Columns 

Add a page reference field to each template you'd like to add layout choices to. The parent setting to 'layouts'. Call the field 'layout' or whatever works for the clients.

Now everytime a user who creates a page based on a template that has the page reference field, they can select wich layout they want.

On the corresponding templates files you can use $page->layout to choose the file to include.

About template vs template file: We've had discussions about this before but i must say i think that once you've taken a couple of moments to work with the system it's really quite obvious how the pieces fit together and what they do, or can do in PW.

  • Like 3
Link to comment
Share on other sites

Hello,

Peter, this seems like an excellent strategy -- dynamic includes that pick up the selection from a dropdown (page) decision to render a specific template! Going further, I can imagine expanding on this by allowing two, three, or more dropdowns, and with some logic rendering various combinations of layouts based on the choices.

A somewhat separate thought: in frameworks like Laravel, the controller (among other roles) determines the URL based on the function being called. I like this aspect of controllers. I wonder how we might use a ProcessWire controller to determine the URL, perhaps even building on the idea Peter describes?

I wonder if this might also be one of the solutions for another discussion underway: http://processwire.com/talk/topic/3145-multiple-views-for-templates/

Thanks,

Matthew

Link to comment
Share on other sites

-snip-

A somewhat separate thought: in frameworks like Laravel, the controller (among other roles) determines the URL based on the function being called. I like this aspect of controllers. I wonder how we might use a ProcessWire controller to determine the URL, perhaps even building on the idea Peter describes?

I wonder if this might also be one of the solutions for another discussion underway: http://processwire.com/talk/topic/3145-multiple-views-for-templates/

Thanks,

Matthew

Matthew, a framework like Laravel is mostly based on the concept of routing. This is really an almost completely blank canvas. The routes describe what happens at specific points, this can be controller actions but something completely else just as well. Out of the box controllers say nothing about url's. You structure 'your' application from the ground up.

PW on the other hand already is an application (a CMS/CMF) so a lot of choices have already been made. It's a very flexible app so you can override most of the behaviours but i'm not sure what you mean when you mention a ProcessWire controller.

  • Like 1
Link to comment
Share on other sites

Hello,

SiNNuT, I was referring to the core assumption in Laravel (and CodeIgniter) that your controller is a URL, with each function more or less a segment. But I know that using routes instead of controllers is becoming more general practice now, especially with Laravel.

I actually see more flexibility with ProcessWire, in some of the ideas we are discussing here.

By "ProcessWire controller," I was just making a shorthand reference to the ideas presented in this discussion.

Thanks,

Matthew

Link to comment
Share on other sites

A somewhat separate thought: in frameworks like Laravel, the controller (among other roles) determines the URL based on the function being called. I like this aspect of controllers. I wonder how we might use a ProcessWire controller to determine the URL, perhaps even building on the idea Peter describes?

I'm not very familiar with Laravel, but (if I'm reading your post correctly and you're not talking about something entirely different here..) this sounds similar to how Zend Framework interprets URLs by default: /controller/action/, ie. /index/index/ (or just /index/, in this case latter /index/ is optional) means "use index action of index controller". Typically this would execute indexAction() method of IndexController class.

If this is the concept you're talking about, that's easily achievable with PW -- setup a template (such as home) that checks for $input->urlSegment1 and if found, checks if a file matching that is found and runs it. Alternatively you could do all of this within one file, exactly like ZF is doing, so that home.php is a controller in which you specify different actions (functions, if blocks or whatever you prefer) and then run correct one based on urlSegment1 (and if no matching action is found, default to "index".)

This could be an effective strategy in certain special situations where you're trying to build more "app-like" structure with PW (or individual app-like part of larger PW site), but as a default it wouldn't really work; routing in PW is based on the idea that each URL segment is a page and not an action like it is in certain other frameworks.

This is logical considering the that focus of PW is clearly more in developing web sites than in building web applications, effectively setting it apart from "raw" web application frameworks.

Link to comment
Share on other sites

setup a template (such as home) that checks for $input->urlSegment1 and if found, checks if a file matching that is found and runs it.

The downside of this technique is that if someone creates a page with the same name in the tree, it will unintentionally override this behavior.

Link to comment
Share on other sites

The downside of this technique is that if someone creates a page with the same name in the tree, it will unintentionally override this behavior.

 

True. Should've added that within this context you should actually put a page with same name as said template to first level of your tree to avoid situation you've described above; ie. if you're having home template function as a controller this way, you should actually redirect users to /home/ and make that page your new home page.

 

This, of course, feels a bit hackish since root page ("/") would still be there, though not in use. Wouldn't be the first time this is done, though, so I wouldn't worry about that too much.. and if it's a huge problem, you could always make your root URL behave as index action of index controller with no other actions -- or something like that.

 

Anyway, let's make it clear right here and now that I'm definitely not suggesting anyone should try follow the steps I've mentioned here -- at least not without a very good reason, in which case slight hackishness should be tolerable. Just going with the flow here and throwing ideas around :)

Link to comment
Share on other sites

Dear SiNNut and Matthew and All,

Thanks for your feedback. SiNNut, you stated exactly what I meant. :-) Thank you.

I think the blend of PW as a framework and CMS is excellent. I'm planning on using PW in both capacties.

For example, I might have a page, like "/members/" that runs a PW API web app.

But when they leave that url branch, and go back to the main home page, the other pages will all be run via the CMS.

Still exploring this idea.

Peter

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...