Jump to:

23358 Posts in 17875 Topics by 2862 members

General Questions

SilverStripe Forums » General Questions » Design Critiques Requested - Remote Content Wrapper Page

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

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

Page: 1
Go to End
Author Topic: 1044 Views
  • Ben Gribaudo
    Avatar
    Community Member
    181 Posts

    Design Critiques Requested - Remote Content Wrapper Page Link to this post

    Hello,

    I am working on a custom page type that allows a remote web resource (say, a forum) to be mounted in a SilverStripe site. To the end user, the mounted resource looks and feels like it is apart of the SS site (consistent template and navigation).

    Example:
    If the wrapper page is inserted at http://mysite/mount/ and is set to wrap content from http://othersite/forum/, a request for http://mysite/mount/page1/ will be forwarded to http://othersite/forum/page1/. When content is received back from othersite, the page wraps that content in the appropriate SS template.

    Would you have time to critique this code?

    In particular, some thoughts/questions I have:

    • In WrapperPage's Children() method, how do I set the Page's URL?
    • Do I need to define stageChilden() and liveChildren() in WrapperPage?
    • In case you're wondering, I would like to eliminate the multiple calls to $this->loadRemotePage() by calling it once from WrapperPage's constructor, however, when I define a __construct() method on WrapperPage, the PHP script hangs. I have yet to debug this problem.
    • Is there a way to eliminate the overriding of handleAction in the controller? Right now, without that override, only requests for http://mysite/mount/ will work. Requests for pages like http://mysite/mount/page1/ will return a not-found error.

    FYI, I'm developing against nestedurls.

    Thank you,
    Ben

    <?php
    // Code by: Ben Gribaudo - www.bengribaudo.com
    require_once 'HTTP/Request.php';

    class WrapperPage extends Page {
       public static $db = array(
          'SourceURL' => 'Varchar(500)',
          'ContentSelector' => 'Varchar(100)'
       );
       public static $has_one = array();
       public static $allowed_children = array();
       private $remotePageLoaded = false;
       
       public function getCMSFields() {
          $fields = parent::getCMSFields();
          $fields->removeFieldFromTab("Root.Content.Main", "Title");
          $fields->removeFieldFromTab("Root.Content.Main", "Content");
          $fields->addFieldToTab('Root.Content.Main', new TextField('SourceURL', 'Source URL (No Query Strings)'));
          $fields->addFieldToTab('Root.Content.Main', new TextField('ContentSelector', 'Content Selector (XPath)'));
          return $fields;
       }
       
       public function onBeforeWrite() {
          $this->Title = $this->MenuTitle;
          return parent::onBeforeWrite();
       }

       public function Children() {
          $this->loadRemotePage();
          $children = new DataObjectSet();
          foreach ($this->Children as $childTitle => $childLink) {
             $page = new Page();
             $page->Title = $childTitle;
             // Doesn't work!
             //$page->URL = $this->Link() . $childLink;
             $children->push($page);
          }
          return $children;
       }

       public function Title() {
          $this->loadRemotePage();
          return $this->Title;
       }
       
       public function Content() {
          $this->loadRemotePage();
          return $this->Content;
       }   
       
       private function loadRemotePage() {
          if (!$this->remotePageLoaded) {
             $currentURL = '/' . $this->CurrentPage()->request->getVar('url');
             if (preg_match('/^' . preg_quote($this->Link(), '/') . '/i', $currentURL)) {
                $subUrl = str_ireplace($this->Link(), '', $currentURL);
             } else {
                $subUrl = '';
             }
             
             $remotePage = new RemotePage(new WebPageLoader(new HTTP_Request()), $this->SourceURL, $this->Link(), create_function('$url', 'header("Location: $url"); exit();'), create_function('$cookie, $expires', 'setcookie($cookie["name"], $cookie["value"], $expires, $cookie["path"]);'));
             $xPathDoc = $remotePage->load($subUrl, $_GET, $_POST, $_COOKIE);
             $this->Title = $xPathDoc->queryFirstAsHTML('/html/head/title');
             $this->Content = $xPathDoc->queryFirstAsHTML($this->getField('ContentSelector'));
             // children eventually will be populated from data contained in the xPathDoc
             $this->Children = array('Topic1' => 'topic1', 'Topic2' => 'topic2');
             $this->remotePageLoaded = true;
          }
       }
    }

    class WrapperPage_Controller extends Page_Controller {
       // $action parameter is ignored
       public function handleAction($action) {
          try {
             return $this->renderWith($this->getViewer('index'), $this->dataRecord);
          } catch (RemotePageLoadError $exception) {
             return $this->httpError(500, '500 Internal Server Error');
          }
       }
    }
    ?>

    1044 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.