Jump to:

5450 Posts in 1672 Topics by 1197 members

Customising the CMS

SilverStripe Forums » Customising the CMS » compile sub pages on one page

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 1367 Views
  • Anatol
    Avatar
    126 Posts

    compile sub pages on one page Link to this post

    Hi,

    just in case this is useful for someone: I'm working on a Silverstripe site that is set up like a book with chapters and sub-chapters etc... each of them on an individual Silverstripe page. I also wanted to have a version that's easy to print; it's not much fun to go to every individual page, print, waste time and paper and possibly forget a few pages in the process. Thanks to the fantastic Silverstripe framework it only took a few minutes to create a 'compile' function to display the content of a parent and all it's children on one page. Here is how:

    add this to the Page_Controller class in /mysite/code/Page.php

    // a variable that stores if the current view is compiled or not - this is useful for the template (see below)
    public $isCompiled = false;

    // the 'compiled' method that is called when a user e.g. goes to the URL /a-page-with-subpages/compiled/
    public function compiled() {
       $data = array('Content' => $this->getChildrenContent($this));
       $this->isCompiled = true;
       return $this->customise($data)->renderWith(array('Page', 'Page'));
    }

    // same as above but this one compiles all pages of your website including all pages on the root level (e.g. /home/all_compiled/ )
    public function all_compiled() {
       $rootLevel = DataObject::get("Page", "ParentID = 0");
       $data = array('Content' => $this->getChildrenContent($rootLevel));
       $this->isCompiled = true;
       return $this->customise($data)->renderWith(array('Page', 'Page'));
    }

    // a method to get all the content of the current and child pages (recursive)
    private function getChildrenContent($pages) {
       $output = '';
       if(count($pages)) {
          foreach($pages as $page) {
             if(!($page instanceof ErrorPage) && $page->ShowInMenus){
                if ($page->Title != $this->Title) {
                   $output .= '<h2 id="'.$page->URLSegment.'">'.$page->Title.'</h2>'; // you can use the 'id' to use anchors
                }
                $output .= $page->Content;
                $whereStatement = "ParentID = ".$page->ID;
                $childPages = DataObject::get("Page", $whereStatement);
                $output .= $this->getChildrenContent($childPages);
             }
          }
       }
       return $output;
    }

    That's it. Try to access a page and add /compiled/ to the URL and you will get the page plus all content of the sub pages on one page. For a compiled version of all page content including all root level pages add /all_compiled/ to the URL

    All that's left to do is to add a link to the template:

    <% if Children %>
       <% if isCompiled %>
          <a href="$URLSegment/">view parent page only</a>
       <% else %>
          <a href="$URLSegment/compiled/">view all sub pages</a>
       <% end_if %>
    <% end_if %>

    or

    <a href="home/all_compiled/">view all content of this website</a>

    In a similar way as above you can build a menu with text anchors. See the site-map tutorial and just create links with a '#' to jump to the anchor. Thanks for the site-map tutorial - I borrowed heavily for the compile functions above.

    (This is for the default 'Page' page type. If you want to use this for other page types you probably need to do some tweaking.)

    Cheers!
    Anatol

    1367 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.