How to have multiple layouts for cakephp? - cakephp

I am quite confused on how to have my own layout for each page in cakephp. Currently, there is a default.ctp which I have modified to have my main layout and included the $content_for_layout code. So whatever I have entered in the pages\home.ctp gets reflected. But I want to have a login and register layout and also their individual pages. How can I go about achieving this? Should I even edit the default.ctp? Or create another layout for my main page?
Please assist.

You can specify a different layout in your Controller methods, e.g.
function index() {
$this->layout='my_index_layout'; //app/views/layouts/my_index_layout.ctp
}
function view($id) {
$this->layout = 'my_view_layout'; //app/views/layouts/my_view/layout.cpt
}

But I want to have a login and register layout and also their individual pages.
The "layout", as understood in Cake, is mostly the header and footer. And it sounds like you are referring to the layout of content. You can do the layout of content in each individual view file.
Should I even edit the default.ctp? Or create another layout for my main page?
Yes, it is there for you to modify. If you want more layouts, you can create more in that folder and specify the layout in the controller (otherwise, it defaults to "default" layout).

Related

CakePHP 2.x How to determine view path in controller in beforeRender() or earlier?

I have the need to determine what app path my controller method will use for serving up the view before it does so. I'm using a theme but I also have many non-themed view files. I'm switching my themes based on domain name (2 domains point to the same Cake install) but need to exclude the non-themed views from rendering inside my theme.
This may sound confusing. Here's what is currently happening if a URL is accessed that does not have a theme view associated with it:
domainA.com/examples/index will render the view app/View/Examples/index.ctp with the layout from app/View/Layouts
domainB.com/examples/index will render the view app/View/Examples/index.ctp BUT with the layout from app/View/Themed/MyTheme/Layouts
This is because the "MyTheme" theme does not contain a view file for this controller-method pair (this is intentional). So I would like to instead have the following established:
domainB.com/examples/index continues to render the view app/View/Examples/index.ctp BUT INSTEAD with the layout from app/View/Layouts
This should only happen, of course, if and only if there is no view file within the "MyTheme" directory structure.
I think this is what you are looking for $this->View->viewPath.
You can use this in any controller call back function or action.

CakePHP : having different layout files for backend and frontend

Is it possible to have 2 different layout files in the app > view > Layouts folder. The reason that I'm asking this is that I already have my backoffice, but don't know how to proceed in making the structure for the frontoffice.
The routes of the views in my backoffice use the prefix admin and use the default.ctp as layout. I actually want that file to be admin_default.ctp so I can use the default.ctp for my frontoffice views.
My question now is how can I separate those layout files. What I want to achieve is that some controllers/views use default.ctp (front) and other controllers/views use the admin_default.ctp (back). Is this a good approach or is it better to consider an alternative?
simply you can use $this->layout to specify your custom layout in controller.
this article may be useful for your question
In your AppController's beforeFilter, just check if it's admin prefix, and set the layout accordingly:
class AppController extends Controller {
public function beforeFilter() {
if($this->params['prefix'] == 'admin' && $this->name !== 'CakeError') {
$this->layout = "admin"; // set the layout
}
}
//...
Another nice thing you can do after determining it's the admin is is force SSL (often a good idea for back-ends):
$this->Security->requireSecure(); // inside the above if block

Why ajax calls doesn't load the layout in CakePHP 2.3

I am wondering why if i use jquery $.load function or some pluging such as fancybox to load content dynamically on the site, the layoug is not loaded but only the view as if it were an element.
My $.load() calls a controller action as if it was a normal link, like:
$('#demo').load("http://"+ document.domain +"/tables/users/edit/", {input : data}, function(dat){
//whatever
});
This is not something I personally dislike, like this I avoid creating elements and calling them using $this->render('/Elements/xxxx', false); from my controllers.
I want to know if this is the proper way to work with or if it is some kind of cheat or bug of cakephp.
How should we treat this type of content which is not a proper "view" (as won't have a layout, headers...etc), but an "element" loaded dynamically? As a view? As an element?
Thanks.
Check /Layouts/ajax.ctp this is the layout that is rendered for ajax calls. Usually you don't want to have all the header and footer around the element you request when doing an ajax call.
Burzum is on the right track.
Your controller will load the default layout unless you tell it to use /Layouts/ajax.ctp. So in your edit function you'd want to switch layouts depending on how the function is being called. For example:
if($this->request->is('ajax')){
$this->layout = 'ajax';
}// else use controller default...or specify another layout to use here.

How to preserve layout through different views of same controller in cakephp

I'm using cakephp and I have set a simple site, when rendering index() it works fine
but when programming other methods of the same controller, the views for them do not show the
background, it's like it cannot find the images, I thought the layout would be preserved for all views.
Your View/Layouts/default.ctp layout file will always be used unless specified otherwise. If it's not showing a background, it's like you're using an incorrect path for the image, css...etc.
If you want to apply a layout to all methods of a particular controller (but not all other controllers) then use a theme.
Controller Code:
class MyThingController extends AppController {
public $theme = 'MyTheme';
....
}
Next you have to put your layout file in:
/app/View/Themed/MyTheme/Layouts/default.ctp
Then all methods in your controller will use this layout by default.
See here for more info: enter link description here
(note: this answer applies to Cake version 2.1+)

Customizing layouts with CakePHP based on the current record

Does anyone have recommendations on how to customize the layout sitewide based not on the current view, but the data associated with the view? In most cases, the models we are using have an associated Club id, so would have to customize the layout header image, css, etc, depending on which Club the current page is associated with.
Here is what I am thinking so far.
Call a function in the model associated with the current controller, which gives you the layout parameters.
In appController, beforeRender, set layout parameters for the club.
This doesn't seem very elegant, because each model would have to have this function, and how would I call the right model if beforeRender is defined in the app controller?
Some tips would be great!
Russel,
you might want to look at this.
Simply create a file in layouts called "dashboard.ctp" then if your view is index, your function would be something like this...
function index() {
$this->User->recursive = 2;
$this->layout = 'dashboard';
$this->set('users', $this->paginate());
}
The important line being $this->layout = 'dashboard';
What we ended up doing is checking in the app controller for the domain the site is currently being loaded from, then setting the layout based on this information (have a layout for each domain the site needs to look customized for). Not a great solution but it works fine.

Resources