Customizing layouts with CakePHP based on the current record - cakephp

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.

Related

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+)

render a blank view in cakephp

i need to prevent a view to be rendered in a specified case but i can't understand how to prevent it to render.
I tried
$this->autoRender=false
but nothing happened, probably because i'm using an API engine that manage rendering differently from regular controllers. Anyone know any trick to do this?
Using $this->layout = 'ajax' does not seem to be enough.
But using these both lines works:
$this->layout = 'ajax';
$this->render(false);
While searching for a solution, I found this answer. Now when using CakePHP 2.4.x, you could use the following code in your controller:
$this->layout = false;
This will lead to just the view being rendered, without a layout.
It's an old question. The current cake-version is 3.x and there is a easy way to use a blank layout.
Only add the in the controller:
$this->viewBuilder()->autoLayout(false);
Try to use ajax layout $this->layout = 'ajax' this is the default empty layout, which is used for ajax methods.
public function function_without_layout(){
$this->viewBuilder()->autoLayout(false);
echo "hello Brij";
exit;
}
$this->layout = false; is deprecated in CakePHP version 3.
Use $this->viewBuilder()->autoLayout(false); for CakePHP version 3.
Add this in your controller:
$this->autoRender = false;
This works in my project.
The CakePHP 3 autoLayout(false) method from the other answer will still have the system try to locate a corresponding view/template file for the action you're calling. Since I needed no output at all, this didn't work for me, so I needed to also render an empty template.
Creating a blank .ctp file for every empty action you might need isn't an option really, because you'd normally want to have one and reuse it. CakePHP 2 had a $this->viewPath property which would let you configure the controller to look into the app/View folder, but it's CakePHP 3 alternative still looks into the corresponding controller and prefix folders. There is a not-so-obvious way to force CakePHP3 to look for a template in a root view path.
Create src/Template/my_blank_view.ctp
Add the following to your controller action:
$this->viewBuilder()->layout(false);
$this->viewBuilder()->templatePath('.'); // this
$this->viewBuilder()->template('my_blank_view');
Also, I'm using $this->viewBuilder()->layout(false) instead of autoLayout(false) because the latter kind of implies that there might be another layout set later, where the layout(false) just explicitly sets that there's no layout needed.
without knowing anything about API engine you're using, maybe try to make empty layout with empty content and call it in controller as $this->layout = 'empty_layout'

How to have multiple layouts for 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).

CakePHP global variables in model

I am making one CakePHP project with Auth component. When I log in I got Session variable with user data. At the moment I am using this variable in controllers to pass data to the model.
$user = $this->Session->read('Auth');
$costs = $this->Posts->get_quartal_cost($user, $quartal, TRUE);
As I am using this in many controllers/models I am thinking that this is not DRY approach, so I wanted to make it better - something in AppModel(?)
Do you have some advice how to do that better?
Thanks
You could use the beforeFilter event in your AppController and do something like this:
public function beforeFilter()
{
if ( $this->Session->check('Auth') )
Configure::write('Auth', $this->Session->read('Auth'));
}
From anywhere in your controllers, models and even views, you'll be able to access it by using echo Configure::read('Auth');. See the Configuration class documentation for more information.

How to load custom plugins in CakePHP?

I'm writing a poll plugin for a website based on CakePHP. The plugin works good if I access it from its own URL (eg. myapp.com/plugin/controller) but I need to call it from different pages. I would like to include it as a widget in every page.
I'm looking for a method like $myplugin->renderPoll($pollId); but I really didn't find any information about how to instantiate the Polls class. I tried with App::import and ClassRegistry::init with no luck.
Any suggestion ?
Thank you
Looks like you are trying to create some sort of Helper to create poll cross views? I would suggest creating a Helper for that particular class. Simply create a helper in plugins/plugin_name/views/helpers/foo.php, and in each controller (or in app_controller.php) that you need it, include the helpers as $helpers = array("PluginName.Foo"); and inside your view, you should be able to use the methods defined in foo.php by calling $foo->renderPoll($pollId).
//app/plugins/plugin_name/views/helpers/foo.php
class FooHelper extends AppHelper {
var $name = "Foo";
function renderPoll($id=0) {
//...
}
}
Use Elements! They're small blocks of presentation code that need to be repeated from page to page, sometimes in different places in the layout.
Check this link out: http://book.cakephp.org/view/1081/Elements
I guess this link explains everything you need.

Resources