Jump to:

3445 Posts in 1031 Topics by 872 members

Template Questions

SilverStripe Forums » Template Questions » renderWith() makes navigation disappear

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

Page: 1 2
Go to End
Author Topic: 8082 Views
  • schellmax
    Avatar
    Community Member
    126 Posts

    renderWith() makes navigation disappear Link to this post

    hello,
    i'm trying to render a page through the action of another pages controller like so:

    function showPage {
       $page = DataObject::get_by_id('Page',7);
       return $page->renderWith('Page');
    }


    when i visit the url (somepage/showPage), page with id 7 is rendered, but the navigation (using controls like Menu(2) etc) disappears.

    i found a post concerning the same problem in the forum archives, but without any replies:
    http://www.silverstripe.org/archive/show/160453

    am i getting something wrong about renderWith()?

  • dio5
    Avatar
    Community Member
    501 Posts

    Re: renderWith() makes navigation disappear Link to this post

    Isn't renderWith() supposed to get an array of parameters?

    so this would become:

    $page->renderWith(array('MyPage', 'Page'));

  • schellmax
    Avatar
    Community Member
    126 Posts

    Re: renderWith() makes navigation disappear Link to this post

    thanks for the answer, but according to the docs both parameter types are allowed:
    from http://doc.silverstripe.org/doku.php?id=templates&s=renderwith#calling_templates_from_php_code:

    ... $controller->renderWith("TemplateName"); ...

    ... renderWith() can also be passed an array of template names. If this is done, then renderWith() will use the first available template name. ...

    strange enough, in my case the use of a single string doesn't do the trick, i have to pass an array like Array('ProjectPage', 'Page'), even though 'ProjectPage' is not a template but a layout (in the 'layouts' folder) to render a ProjectPage.

    as for the missing navigation, i got it working again using the following instead of Menu(2):

    <% control Parent.Children %>

    not sure wheter it's a bug or my misunderstanding of renderWith - there's no overly detailed explanation on in this the docs...

  • jam13
    Avatar
    121 Posts

    Re: renderWith() makes navigation disappear Link to this post

    That's how it's supposed to work AFAIK. Normal rendering behavoir is to follow the class inheritance chain to get potential template names, but when you use renderWith it requires you to explicitly define the list of templates to try. So if you just use 'ProjectPage' then it finds that for the Layout template but when it fails to find a main template called ProjectPage it doesn't look for 'Page'.

  • schellmax
    Avatar
    Community Member
    126 Posts

    Re: renderWith() makes navigation disappear Link to this post

    oh i understand - thanks for pointing this out.
    maybe there's also a reasonable explanation for the 'Menu(2)' not working?...

  • simon_w
    Avatar
    Forum Moderator
    473 Posts

    Re: renderWith() makes navigation disappear Link to this post

    Menu() is defined in the Controller class, so if you call renderWith() in your Page subclass, the method doesn't exist in a place where it can be called. If the method calling renderWith() is in your Controller, then Menu() should work.

  • schellmax
    Avatar
    Community Member
    126 Posts

    Re: renderWith() makes navigation disappear Link to this post

    that's a good hint, but even though the method calling renderWith is in a class extending Page_Controller, none of my controller methods are available in the ProjectPage.ss layout??

    i even have to call the init() function of PageProject_Controller before the renderWith statement to have the required js (via requirements::javascript) loaded.

    here is the method i'm calling via url 'showproject/project/7' (inside showproject_controller):

       function project($action) {
          $projectPage = DataObject::get_by_id('ProjectPage', $action['ID']);
          ProjectPage_Controller::init(); //loads necessary js
          return $projectPage->renderWith(Array('ProjectPage','Page'));
       }


    any further hints appreciated...

  • ajshort
    Avatar
    Community Member
    244 Posts

    Re: renderWith() makes navigation disappear Link to this post

    This is the correct behaviour - you're calling renderWith() on your ProjectPage class, which is not attached to the controller by default, which means you can't access any of those methods.

    Firstly - is there a reason you're using an action to render another page? It would be much simpler to directly link to the page. It seems that this is what you're currently trying to do, so I would reccomend just using the $Link method in your template and link directly to the page in order to avoid duplicate content + hack problems etc.

    On the other hand, if the ProjectPage isn't a sub-class of SiteTree, it makes sense to render in an action. The best way to do this is to create a custom action template - you do this by making a template called (Class)_(action).ss - in this case PageProject_project.ss

    You can then modify your project method to something like this:

    public function project() {
       return array (
          'ProjectPage' => DataObject::get_by_id(...)
       );
    }

    You can then use <% control ProjectPage %> in your template.

    If you are really stuck with using an action to render a SiteTree object, you can do something like this to couple it to a controller: (I'm presuming your using 2.2.x)

    public function project() {
       $controller = new ProjectPage_Controller(DataObject::get_by_id('ProjectPage', ...));
       $controller->init();
       
       return $controller->getViewer('index')->process($controller);
    }

    8082 Views
Page: 1 2
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.