I have developed a full website with CakePHP framework and we'd like to make a very light version of the website for mobile devices (mainly iPhone/iPad).
Is there a way to use the existing website with a new sub domain (for instance mobile.mywebsite.com) which will render specific views? I would like to avoid copying and simplifying the current one to match the new one requirements. I do not want to have to "re-develop" a new CakePHP website and do the changes twice every time I need to change a controller action.
I've done this using a quick addition to the beforeFilter() in my app_controller.php file.
function beforeFilter() {
if ($this->RequestHandler->isMobile()) {
$this->is_mobile = true;
$this->set('is_mobile', true );
$this->autoRender = false;
}
}
This uses the CakePHP RequestHandler to sense if it's a mobile device visiting my site. It sets a property and view variable to allow actions an views to adjust themselves based on the new layout. Also turns off the autoRender because we'll take care of that in an afterFilter.
In the afterFilter() it looks for and uses a mobile view file if one exists. Mobile versions are stored in a 'mobile' folder inside the controller's view folder and are named exactly the same as the normal non-mobile versions. (ie. add.ctp becomes mobile/add.ctp)
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$view_file = new File( VIEWS . $this->name . DS . 'mobile/' . $this->action . '.ctp' );
$this->render($this->action, 'mobile', ($view_file->exists()?'mobile/':'').$this->action);
}
}
Dan's answer worked for me. However, I used file_exists instead of the File constructor and added the ability to use mobile layouts. The before filter was the same, but the afterFilter looked like this:
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$view_file = file_exists( VIEWS . $this->name . DS . 'mobile/' . $this->action . '.ctp' );
$layout_file = file_exists( LAYOUTS . 'mobile/' . $this->layout . '.ctp' );
$this->render($this->action, ($layout_file?'mobile/':'').$this->layout, ($view_file?'mobile/':'').$this->action);
}
}
You can use Theme feature in CakePHP 2.x for mobile layout.
Simply do:
if($this->RequestHandler->isMobile())
$this->theme = 'mobile';
I found this better, as you can share View file on mobile and desktop theme easily.
I modified this technique for a CakePHP 2.1 app. Here is my beforeFilter()
:
public function beforeFilter() {
if ($this->request->isMobile()){
$this->is_mobile = true;
$this->set('is_mobile', true );
$this->autoRender = false;
}
}
And here is my afterFilter()
:
function afterFilter() {
// if in mobile mode, check for a valid view and use it
if (isset($this->is_mobile) && $this->is_mobile) {
$view_file = file_exists( 'Views' . $this->name . DS . 'mobile/' . $this->action . '.ctp' );
$layout_file = file_exists( 'Layouts' . 'mobile/' . $this->layout . '.ctp' );
if($view_file || $layout_file){
$this->render($this->action, ($layout_file?'mobile/':'').$this->layout, ($view_file?'mobile/':'').$this->action);
}
}
}
This helps account for deprecated verbiage and constants in CakePHP 2.
The simple solution is to create a new 'mobile' layout with respective stylesheet(s) and turn it on in AppController:
public $components = array('RequestHandler');
public function beforeRender() {
parent::beforeRender();
if ($this->RequestHandler->isMobile()) {
$this->layout = 'mobile';
}
}
It is important to do that in beforeRender()
in case if you change $this->layout
in your controllers' methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With