Force CakePHP plugin to use its own layout - cakephp

I have written a CakePHP plugin https://github.com/anuj9196/CakePHP-App-Installer
The plugin is using default.ctp layout from plugin_path/src/template/layout/default.ctp
When there is some other theme used in the host application. Like in my case I have setup one in AppController's beforeRender()
$this->viewBuilder()->setTheme('DashboardTemplate');
DashboardTemplate is in application's /plugin/ directory.
Now, when I access my plugin's URL using example.com/installer/install
The template loads on top of DashboardTemplate theme.
How can I disable them in plugin's AppController?
The AppController inside plugin directory contains
<?php
namespace Installer\Controller;
use App\Controller\AppController as BaseController;
class AppController extends BaseController
{
// nothing here
}

Remove the theme by using beforeRender() in your plugin's AppController.
<?php
namespace Installer\Controller;
use App\Controller\AppController as BaseController;
class AppController extends BaseController
{
/**
* #param \Cake\Event\Event $event The beforeRender event.
* #return \Cake\Http\Response|null|void
*/
public function beforeRender(Event $event)
{
try {
return parent::beforeRender($event);
} finally {
$this->viewBuilder()->setTheme(null);
}
}
}

You can switch between layouts in your view and controllers fairly easily.. using plugin syntax
// inside controller
$this ->layout = 'Plugin.layout';
//inside view template
$this ->layout = 'Plugin.layout';
If you just want to disable the theme, use Mathew's method above. But be careful that will disable the theme for the whole application not just this plugin in case some of your app code is ran after your plugin

Related

CakePHP - Adding a JS file to the 'script' block from a controller's beforeRender callback

Is it possible to add a js file to view from a controller beforeRender()? Is it advisable? If not, and if I cannot use a View, should I just use the Event System?
Basically the idea is to have a plugin that I created inject a JS file into 'script' block of the Theme plugin (Separate plugin)
After some more attempts I decided to go thru and use the Event System. I accomplished it this way:
<?php
namespace App\Event;
use Cake\Event\EventListenerInterface;
class ApplicationListener implements EventListenerInterface {
public function implementedEvents() {
return [
'View.beforeLayout' => 'injectJsFile'
];
}
public function injectJsFile(Event $event, $layoutFile){
$event->getSubject()->Html->script('myscript', ['block' => 'script']);
}
}
This does the job for me, but if there is a controller way or a better Event System way, I would love to hear it.

How to set application layout in plugin controller in cakephp 3.x?

I am new to cakephp 3 and I don't know how to add our application layout to specific plugin controller.
My folder structure like below:
<pre>
projectName(folder)
->Plugins(folder)
->PluginsName
->src
->controller
->UsersController
->src(folder)
->Template(folder)
->Layout(folder)
->login.ctp
</pre>
How can I use this login.ctp layout in my plugins controller (UsersController)?
You can add layout in specific function by following way.
// Set the layout.
$this->viewBuilder()->setLayout('login');
// Before 3.4
$this->viewBuilder()->layout('login');
// Before 3.1
$this->layout = 'login';
if you need add it in full controller then you can add it in beforeRender
public function beforeRender(Event $event)
{
parent::beforeRender($event);
$this->viewBuilder()->setLayout('Admintheme');
}
Ref: beforeRender and Layout

Relocating Cake's default layouts folder

I'm working on a CakePHP 1.2 app where I don't have control over the /app directory and have relocated my views folder to, say /path/to/mycomponent/views and can render my views by setting my controller's default view path
var $viewPath = "mycomponent/views";
I have some layouts (including basic.ctp) under /path/to/mycomponent/views/layouts
Is there a way to render my views inside a specific layout?
Calling this from my controller gives me a page not found error:
function index()
{
$this->autoLayout = true;
$this->pageTitle = 'Browse items';
$this->render("browse", "basic");
// also tried: $this->render("browse", "/path/to/mycomponent/views/layouts/basic.ctp");
}
Finally got it to work by adding a path to the viewPaths array of the app configuration. This code goes in you controller constructor or in the override beforeFilter metod:
$config = Configure::getInstance();
$config->viewPaths[] = " /path/to/mycomponent/views/";
Now I can just specify the following:
$this->layout = 'basic';
And my controller's views render in the basic.ctp layout.
Just for any further reference.
I believe in cakePhp 2.x it's to be done this way.
public function beforeRender() {
parent::beforeRender();
$this->layout = 'mylayout';
}
which would go to the path: /app/View/Layouts/mylayout.ctp
Note:
If you want to modify the view paths for some controller, add before the controller class declaration:
App::build(array('View' => '/Folder/'));
class ExampleController extends AppController{...}
which will set the path for all rendered view for Example controller to /app/Views/Folder/
so the full example would be:
App::build(array('View' => '/Folder/'));
class ExampleController extends AppController{
public function beforeRender() {
parent::beforeRender();
$this->layout = 'mylayout';
}
public function index() {
$this->render('Home');
//This will load view: "/app/Views/Folder/Home.ctp"
//From layout: "/app/Views/Layouts/mylayout.ctp"
}
}

Cakephp plugin layout is applying to all pages

I am facing a strange error in cakephp2.0. I have created two layouts - one for plugin and one for front end users. Whenever I take the front end and after that if I take the plugin in the url, the front end layout is getting applied to all pages coming under plugin and vice verse. After 8-10 refresh it will take the correct layout. How to avoid caching of layout variable in this case ?
VideosController under app/Controller folder
App::uses('AppController', 'Controller');
class VideosController extends AppController
{
public function index()
{
$this->layout = 'default';
$this->set('videos', $this->Video->find('list'));
}
}
My plugin Main controller
class AdminAppController extends AppController
{
var $layout = 'admin';
}
Another controller inside my plugin
App::uses('AdminAppController', 'Admin.Controller');
class VideosController extends AdminAppController
{
public function index()
{
$this->Video->recursive = 0;
$this->set('videos', $this->paginate());
}
}
You can set parts of your view to not be cached, or you could clear the cache every time the layout is changed. Check: http://book.cakephp.org/2.0/en/core-libraries/helpers/cache.html

Why CakePHP 2.0 is not using my AppController?

I have just upgraded to Cakephp 2.0 alpha, and immediately faced a problem. The app_controller.php in the app/ folder is not loaded in my controllers. Instead controllers use the CakePHP own AppController.php in the lib/Cake/Controller/AppController.php.
I have tried renaming the app_controller to AppController.php aswell but its not working. I have tried deleting the whole file and then copying the lib/Cake/Controller/AppController.php file and then editing it but not working.
I have also tried deleting cache files.
I just simply use:
class AppController extends Controller {
public function beforeFilter() {
die;
}
}
And the application wont die.
My controller is also simply just:
class NewsController extends AppController {
function beforeFilter() {
parent::beforeFilter();
}
function index() {
}
}
So what I could be doing wrong? Im also using Windows 7 + Netbeans with Subversion to update project (if that has anything to do with it :p).
Did much of searching and didn't look from most obvious place: Github cakephp docs: https://github.com/cakephp/docs/blob/master/en/controllers.rst . I thought they were still 1.3 docs but it appears they are updated. Since they are now updated, it says that I should put the old app_controller.php into Controller folder and camel case it to AppController.php.
Create file AppController.php in app/Controller directory
class AppController extends Controller {
public $helpers = array('Html', 'Form', 'Javascript');
public function beforeFilter() {
die('app/Controller/AppController.php file called');
parent::beforeFilter();
}
}

Resources