Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

Routing rule breaks access to Page fields and functions


Go to End


2 Posts   1075 Views

Avatar
cmc

Community Member, 33 Posts

22 May 2016 at 4:06am

Edited: 22/05/2016 4:08am

How do I fix the problem of routes in config.yml breaking access to Page fields?

This in my config.yml to handle routes with custom parameters (https://docs.silverstripe.org/en/3.2/developer_guides/controllers/routing/).

Director:
  rules:
    'mypage': 'MyPage_Controller'

When that rule is included in the config.yml it's not possible access fields and functions defined in the MyPage class via the MyPage_Controller or template. If I remove the rule from config.yml the fields and functions are accessible, but routes with many parameters don't work.

<?php
//MyPage class
class MyPage extends Page {
    private static $singular_name = 'My Page';
    private static $plural_name = 'My Pages';

    //Not accessible if route to controller specified in config.yml
    private static $db = array(
        'MyPageVar' => 'Int',
    );
    
     //Not accessible if route to controller specified in config.yml
     public function getMySpecialVar() {
 	 return $this->MyPageVar;
     }
    
}

//MyPage_Controller class
class MyPage_Controller extends Page_Controller {

    private static $allowed_actions = array(
        'index',
        'detail',
        'category',
        'tag',
        'search',
        'detailsearch',
    );

    private static $url_handlers = array (
        'detailsearch/$Key1/$Value1/$Key2/$Value2/$Key3/$Value3/$Key4/$Value4/$Key5/$Value5' => 'detailsearch',
    );
 
    //...
    //some other code
    //...

    /**
     * UseMyPageVar() 
     * 
     * @return Boolean
     */
    public function UseMyPageVar() {
    	//Empty if route to controller specified in config.yml
        Debug::show($this->MyPageVar);
        Debug::show($this->Title);
        Debug::show($this->Content);
        //Error if route to controller specified in config.yml
        Debug::show($this->getMySpecialVar());
        
        return true;
    }

}

Fields also are not accessible in template if route specified in config.yml

<!-- ok if no route specified, empty if route specified in config.yml -->
<p>MyVar: {$MyPageVar}</p>
<p>Title: {$Title}</p>
<p>Content: {$Content}</p>

Avatar
cmc

Community Member, 33 Posts

24 May 2016 at 6:23am

In case anyone having the same problem checks this thread, here's the code I'm using to access Page fields in the Controller

//MyPage_Controller class
class MyPage_Controller extends Page_Controller {

    private $_page; //holds reference to page that's lost with custom routing        

    //ContentController uses route, which has been changed to
    //   'MyPage_Controller' by routing rule, to initialize 
    //   page reference. Can't find anything so reference
    //   not set. (set to -1)
    public function init() {
        parent::init();

        //Initialize using default route overwritten in routing rule
        //    This will break if URL segment changed in CMS  
        $route = array_search($this->URLSegment,
                        Config::inst()->get('Director', 'rules'));
        $link = str_replace($this->URLSegment, $route, $this->Link());
        $this->_page = $this->Page($link);
    }


    //Use private var to access page fields 
    public function MyPageVar() {  
        Debug::show($this->_page->MyPageVar);
    }

    //expose $Content to templates
    public function Content() {
        return $this->_page->Content;
    }

    //Can't use Title() so expose Page Title as $PageTitle
    public function PageTitle() {
        return $this->_page->Title;
    }
}