Manually render a single page - how?!

Permalink
Hi,

So I'm developing a site that wants to display all of the pages on the home page (for the most part). In doing so, I'm trying to make this easy to manage for the client by giving them actual pages to edit for each 'section' of the site. However that is providing more challenging than I thought.

The current code I have is this:

<?php 
  defined('C5_EXECUTE') or die("Access Denied.");
  global $c;
  $old_c = $c;
  // render page object
  $_v = View::getInstance();
  $old_theme = $_v->getTheme();
  $oldDirectory = $_v->getThemeDirectory();
  // change theme
  $theme = PageTheme::getByHandle('blankTheme');
  $_v->setTheme($theme);
  foreach ($pages as $page) {
    if ($page->getCollectionID() != HOME_CID) {
      $c = $page;
      $page_name = strtolower( $c->getCollectionName() );


You'll already notice some 'funky' stuff in there - namely the whole theme change. Let me explain - this is a page list template. It takes in the pages, assigns them to be '$c' and then proceeds to try and render the page view. Normally, this would include the header and the footer however we have created a new theme called "blankTheme" (our current theme being called "newTheme") which contains an empty header and footer, as there is no real way to output this otherwise it seems - I've tried creating 'empty' templates within the same theme but they are never picked up.

So at least this seemed to work. However, I have another problem now in that when it tries to render a single page, it doesn't pick up any content whatsoever, and just returns me empty content. I've tried all sorts of methods to get the single page content to show, but no matter what I do it's always blank. The only time it renders is when loading the page up by visiting the URL. Even when I change the render action to be

$_v->render($c);


I still get nothing back (I'm aware in the example I'm using 'default', but I've tried setting it to the single pages name with still no avail).

There is definitely content on the page, however it will not render any of it (not even the HTML) and $innerContent is definitely empty.

I've asked similar things in the past and have had no joy, however seeing as I've just wasted a few hours of my life on this, I feel I have to at least ask. So if you have any ideas, it would be amazing to hear them.

Thank you for taking the time to read.

Dan.

 
A3020 replied on at Permalink Reply
A3020
Hi Dan,

What if you use this on top of the foreach?

$req = Request::get();
$req->setCurrentPage($c);

Adri
Danives replied on at Permalink Reply
Hey,

Thanks for answering - sadly that doesn't seem to do anything :( might be along the right lines though.
MattWaters replied on at Permalink Reply
MattWaters
To borrow an approach we used on the "Blog Index" custom template for the Page List block, here's how we might get content from regular pages...

Loader::model('page_list');
      $pl = new PageList();
      $pages = $pl->get();
      foreach($pages as $page) {
         echo '<h2>' . $page->getCollectionName() . '</h2>';
         echo '<hr />';
         $a = new Area('Main');
         $a->disableControls();
         $a->display($page);
      }


But that doesn't render the single page content, and I didn't really see anything too helpful as far as methods in the page or single_page models.

You can do this, though, while looping through, to check if it's a single page:

if($page->isGeneratedCollection()) { /* do something */ }


And get the single page's file name:

$page->getCollectionFilename();


Not sure if that gets you any further than you already were.
Danives replied on at Permalink Reply
Hey,

Thanks - I didn't know about the "isGeneratedCollection" method so that is handy to know! However you are sadly right, hasn't helped with the generation of the single page, haha. Can't figure it out, hm.

Thanks very much for the info though!

(Also, I had done it previously using a similar method to the one you showed, but nearly every section is going to end up as a single page with a different layout.)
Danives replied on at Permalink Reply
Hey,

I'd like to thank the two people that helped with this; I finally figured out how to do it. The full code has been listed below, but the solution was actually when determining it was a single file, was simply to include the file directly as opposed to using the render method!

I've still not worked a cleaner way of doing the theme reset stuff so that'll have to stay in for now: unless anyone knows better than me?

Thanks again,

Dan :)

<?php 
  defined('C5_EXECUTE') or die("Access Denied.");
  global $c;
  $old_c = $c;
  // render page object
  $_v = View::getInstance();
  $old_theme = $_v->getTheme();
  $oldDirectory = $_v->getThemeDirectory();
  // change theme
  $theme = PageTheme::getByHandle('blankTheme');
  $_v->setTheme($theme);
  foreach ($pages as $page) {
    if ($page->getCollectionID() != HOME_CID) {
      $c = $page;
      $page_name = strtolower( $c->getCollectionName() );
fischershaw replied on at Permalink Reply
So this does not actually work, at least for the generated collection named '/login'. I have seen many answers to the question of how a /login page can be displayed based upon code within a single page, but none appear to really function.

Is there a way to render the /login page from within a single page based on my own criteria? Something like (which does not really work because there is nothing to include in the specified directory because.... its generated):
$u = new User();
if (!$u->isLoggedIn()) {
   $v = View::getInstance();
   $theme = PageTheme::getByHandle('blankTheme');
   $v->setTheme($theme);
   $page = Page::getByPath('/login');
   if ($page->isGeneratedCollection()) {
      $pkg = Package::getByID($page->getPackageID());
      $currentPath = $page->getCollectionPath();
      $pathToFile = SinglePage::getPathToNode($currentPath, $pkg);
      include(DIR_FILES_CONTENT . $pathToFile);
   } else {
      $v->setCollectionObject($page);
      $v->render('default');
   }