Jump to content

Template/Display Mode


Michael Fillier
 Share

Recommended Posts

Looking in to PW as an alternative to Drupal.

Just wondering if there is any way to define the template file on render. I read in another post about setting a variable before render and checking for that in the template. ($useThumb, was the example to render a thumbnail) But I wanted to keep my templates clean and create, for example a teaser.php template file. Inside of that I would use something like a switch($page->template) statement on $page->template to write out the html for the corresponding type.

For example, say I have a video, blog and image type. I could simply have them all use the teaser template file on the homepage. So the real question is, can I switch the page template dynamically and will I be able to access the "original" template in the new template. Here is a code sample to demonstrate:

// home.php

$videos = $pages->find("parent=/video, featured=1, limit=3, sort=-date");

echo "<h2>Featured Videos</h2>";

foreach($videos as $video) {

//set teaser template

$video->render();/* Want to render using the teaser.php template */

}

// REPEAT for blog and image, all use sample template

// teaser.php

switch($page->template) {

case "video":

echo '<div class="teaser video"><div class="field-video">{$page->video}</div></div>';

case "blog":

echo '

<div class="teaser-blog">

<div class="title">{$page->title}</div>

<div class="date">{$page->date}</div>

<div class="summary">{$page->summary}</div>

</div>

';

break;

}

  • Like 1
Link to comment
Share on other sites

A example code how to set a templatefile on runtime

$t = new TemplateFile($config->paths->templates . "./another.php");
// send vars explicitly possible
// $t->set( "somevar", $somevar );
// $t->set( 'input', $input);
echo $t->render();

However I think you might like the template option i the advanced setting to use another template instead.

post-100-0-15620100-1342180660_thumb.png

Also your example works using the render method of a page.

Have a template video.php that includes teaser.php.

Then use your example code as is.

Link to comment
Share on other sites

If I understand correctly, you want to change the rendering context at runtime if certain conditions are met. You have a few options.

1. You could set your $video to have a different template file before calling $video->render();

/site/templates/home.php

$video->template->filename = 'teaser.php';
echo $video->render();

2. Or you could throw up a flag that your video.php template file knows to look for:

/site/templates/home.php

$input->whitelist('teaser', 1);
echo $video->render();

…and in your video.php:

/site/templates/video.php

if($input->whitelist('teaser')) {
 include('teaser.php');
} else {
 // render full video page
}

The advantage here is that all your video rendering code is together in one file.

3. Or you could include your teaser.php from home.php manually:

/site/templates/home.php

$_page = $page;
$page = $video; // substitute $page before including teaser.php
include('./teaser.php');
$page = $_page; // return $page to it's original state

4. Or you could isolate the teaser rendering to a function (perhaps included from another file):

/site/templates/functions.inc

function renderTeaser($page) {
 return "<p><a href='{$page->url}'>{$page->title</a><br  />{$page->summary}</p>";
}

/site/templates/home.php

include('./functions.inc');
echo renderTeaser($video);

This last option is the one I'd be most likely to take as I think it's probably one of the lowest overhead, it's easily reusable across different templates, and requires very little consideration wherever you use it. Here's another way you can do the same thing, by actually adding a renderTeaser() function to the Page class at runtime:

/site/templates/functions.inc

function renderTeaser(HookEvent $event) {
 $page = $event->object;
 $event->return = "<p><a href='{$page->url}'>{$page->title</a><br  />{$page->summary}</p>";
}
$this->addHook('Page::renderTeaser', null, 'renderTeaser');

And now you can do this:

echo $video->renderTeaser();

Btw that line that has $this->addHook(); has null as the 2nd argument because the function is outside of a class. Some people create auto-loading modules to contain rendering functions, in which case that 2nd argument is the module's object instance.

Edited by ryan
Corrected error: changed template->setFilename() to template->filename
  • Like 5
Link to comment
Share on other sites

Great solutions! Thanks guys. I especially like the function approach of renderTeaser(). I could put my switch in there and use that function to define all of the different teasers displays. The flag option is also good to keep the code all together for the different "types".

Link to comment
Share on other sites

1. You could set your $video to have a different template file before calling $video->render();

/site/templates/home.php

$video->template->setFilename('teaser.php');
echo $video->render();

should be

...
$video->template->set('filename', 'teaser.php');
...

$template->setFilename() is protected.

  • Like 1
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

×
×
  • Create New...