Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
How to get 404 View using Template
  • I have been playing for a while, trying to get my 404 message to run through the template. As I understand it, I have to submit content to the template and then use the variables I define to access those parts of the content. How, therefore, do I use a ViewModel as in the Welcome example where the ViewModel is used to decide upon the message? This is so that if I can still get things like site-wide headers, footers etc so if I change the layout drastically I don't have to edit the 404 to correspond. Thanks Edit: Controller:
    class Controller_404 extends Controller_Template
    {
    
     /**
      * The basic welcome message
      * 
      * @access  public
      * @return  Response
      */
     public function action_index()
     {
      $this->template->title = ViewModel::get_message();
      $this->template->content = Response::forge(View::forge('404'), 404);
      
      //return Response::forge(ViewModel::forge('404'), 404);
     }
    }
    

    ViewModel:
    class View_404 extends ViewModel
    {
     /**
      * Prepare the view data, keeping this in here helps clean up
      * the controller.
      * 
      * @return void
      */
     public function view()
     {
      $messages = array('Aw, crap!', 'Bloody Hell!', 'Uh Oh!', 'Nope, not here.', 'Huh?');
      $this->get_message = function() { return $messages[array_rand($messages)]; };
     }
    }
    

    If I create a function get_message() in the ViewModel then when I try to access it I get an error saying it is not defined. If I call view() I get an error telling me I shouldn't be calling it.
  • Why not simply do
    $this->template->content = Response::forge(ViewModel::forge('404'), 404);
    

    Basically, where you can use a view, you can use a viewmodel.
  • Ashley Bye wrote on Tuesday 28th of February 2012:
    How, therefore, do I use a ViewModel as in the Welcome example where the ViewModel is used to decide upon the message?

    I probably wouldn't have done it that way. But, if you want to insert data in the view model and then access it from a template controller, you have to do it in the before method. The viewModel isn't rendered until after the controller executes. That means the view method also doesn't fire until after the controller. That's why you use the before method.
    class View_Test extends ViewModel
    {
     public function view() {}
     
     static public function get_message()
     {
      $messages = array('Aw, crap!', 'Bloody Hell!', 'Uh Oh!', 'Nope, not here.', 'Huh?');
      return $messages[array_rand($messages)];
     }
     
     public function before($data = null)
     {
      parent::before(); // Without this line, templating won't work!
      $this->set('title_before', $this->get_message());
     }
    }
    
    Notice also the required view method. You'll also have to create a standard view file since it's also required. It can be empty. It just has to exist. In the controller, if you want to access a viewModel property, you have to either intantiate it first using forge or call it from child class. The following code shows examples of both approaches.
    class Controller_Test extends Controller_Template
    {
     public function action_index()
     {
      $viewModel = ViewModel::forge('test');
      
      $this->template->title = View_Test::get_message();
      $this->template->title_before = $viewModel->get('title_before');
      $this->template->content = Response::forge(View::forge('404'), 404);
    
      $this->response->body = $this->template;
     }
    }
    
    As far as your random message goes, save yourself some headaches and just create a method.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion