My understanding of the CakePHP2 doc leads me to believe I can create a simple plugin that consists of a single view and that view can (if done correctly) override the default view.
For example, if the application has a app/View/Pages/foo.ctp that simply displays the text "Foo", then a Plugin in app/Plugin/Bar/View/Pages/foo.ctp that contains the text "Bar"
I've made sure that the bootstrap.php loads the plugin with CakePlugin::load('Bar');
And I've deleted app/tmp/cache//
From what I understand I'm not required by Cake to need a Controller or Model.
Yet, the application only displays "Foo" instead of the intended override of displaying "Bar".
From what I've described, what parts of my understanding or implementation approach seem wrong? (And why?) And what are the simple/better ways to implement this plugin view?
TIA
(I have read http://book.cakephp.org/2.0/en/plugins.html and http://book.cakephp.org/2.0/en/views.html)
Themes?
A theme is just a collection of template files that can be used to override the templates used in an application; whereas plugins also contain classes - are you looking for themes?
Creating a template in a plugin is not enough
Alone is not sufficient to just create a template file and load a plugin. To render it you'll need to either:
Explicitly render the file
I.e. In any controller:
$this->render('Bar.template_name')
Create an actual plugin
I.e. Create plugin files:
$ Console\cake bake plugin Bar
$ Console\cake bake controller Some --plugin Bar
$ etc.
$ echo "Something" > Plugin/Bar/View/Some/index.ctp
And request: http://yourapp.com/bar/index
See the docs on how to create a plugin for more information.
Related
When I currently use ./cake.bat bake template Genres or ./cake.bat bake template Genres --prefix admin, then the templates are used from these locations:
cakephp\bake\src\Template\Bake\Template\view.twig
cakephp\bake\src\Template\Bake\Template\index.twig
cakephp\bake\src\Template\Bake\Template\add.twig
cakephp\bake\src\Template\Bake\Template\edit.twig
I want to different versions of all these templates when I bake with the admin prefix. I tried creating a Bake Theme.
I ran ./cake.bat bake plugin AdminTheme
Then I placed the desired template files in plugins/AdminTheme/templates/Bake/Template/.
Ran ./cake.bat bake template Genres --theme AdminTheme
Got Error: "AdminTheme" is not a valid value for --theme. Please use one of "Bake, Migrations, WyriHaximus/TwigView"
Prefixes won't affect the template source, the path is pretty much hardcoded in \Bake\Shell\Task\TemplateTask::getContent(). One way to uses different templates is to bake each action separately, and use the action argument, and optionally the alias argument to use the default name for the output, something along the lines of this:
bin\cake bake template Genres admin_index index --prefix Admin
That would use the Template/admin_index.ctp|twig file, and write to Template/Admin/Genres/index.ctp.
As for your bake theme, the template folder structure in your theme plugin has to be:
AdminTheme/src/Template/Bake/Template/
not
AdminTheme/templates/Bake/Template/
Also make sure that your plugin is actually being loaded, ie check that $this->addPlugin('AdminTheme'); exists in your Application class' bootstrap() method, or for earlier versions Plugin::load('AdminTheme'); in your config/bootstrap.php file.
See also Bake Cookbook > Extending Bake > Creating a Bake Theme
I want Bake to add a custom TimestampBehavior to every table which has the fields created_at, modified_at, proved_at. I also want to remove the Validators for these fields.
Whether a model is added the TimestampBehavior is programmed in Bake/src/Shell/Task/ModelTask.php. I don't want to edit the file in the vendor folder, because my file might be overridden by an update.
Moving the file to my plugins folder doesn't work since i get the error message "class ModelTask is already defined".
Is it possible to extend the ModelTask somehow or to use a custom ModelTask.php in my plugins folder for bake to achieve my goal?
Thanks for your help!
Moving the file to my plugins folder doesn't work since i get the error message "class ModelTask is already defined".
It doesn't work because you probably haven't changed the namespace. Fix the namespace to the one the plugin uses and you're done. You can even extend classes of the same name by using uses Foo as Bar and then Foo extends Bar.
What is the best configuration and parameters for ctags in a CakePHP project?
I want to be able to auto-complete ctp files, Components, Behaviours, Models and Helpers?
Check these github repositories, I have found then and they are so good for work with php and cakephp
https://github.com/amix/vimrc
https://github.com/ndreynolds/vim-cakephp
This solution requires 1 line in your .ctags file and two lines in your .vimrc file, so it's fairly minimal.
tl;dr
.ctags:
--langmap=php:+.ctp
.vimrc:
# Controller -> Component
map <leader>t yiw<cr>:tag /^<C-R>"<CR>
# View -> Helper
map <leader>h yiw<cr>:tag /^<C-R>"Helper<CR>
Add Views to your tags
This solution is mostly for jumping between files. I'll try and add auto-completion at a later date.
Add this to your ~/.ctags options file to include CakePHP views as PHP files:
--langmap=php:+.ctp
Then I'm assuming you've done ctags -R . at the root of your project (that's what I've done at least). This out of the box should pick up PHP syntax and class definitions.
Auto-completion (general)
I found the auto-completion (omni-completion from Ctrl+XCtrl+O) doesn't work very nicely with PHP, e.g. if I type $this-> and then try to auto-complete it doesn't find any tags.
The fix for this was to use install phpcomplete.vim. This will find methods within your class.
However that won't auto-complete connected models.
Models
By default ctags should work for all Controller -> Model jumping as the Model name is the same as the class name.
Behaviors
These again should be fine as you don't specify the name of the behavior you just have the method name which depending on how independent the name is it should get found - or at least it will be in the list of tags.
Components
There's no direct way of mapping these, I couldn't see a way of mapping them through the ctags --regex options. ctags recognises that they are classes but doesn't know the xxx -> xxxComponent mapping.
However there is one slight trick. You can do a tag search on the beginning of the class name (source)
:tag /^Email
will find
class EmailComponent
You can then map this in your .vimrc
map <leader>t yiw<cr>:tag /^<C-R>"<CR>
This copies the word that you've got the cursor over and then pastes it into the tag command and executes it. My leader is set to ,, so I can type ,t and it takes me to the corresponding component under the cursor.
Helpers
Ok, another slight hack in the .vimrc file:
map <leader>h yiw<cr>:tag /^<C-R>"Helper<CR>
Using ,h, this will jump you from $html->... to
class HtmlHelper extends AppHelper {
But it doesn't work for functions inside e.g. if your cursor is over script in $html->script, it will not take you to the HtmlHelper script method. So it's a work in progress.
I have a plugin installed that has its own layout overrides for different controllers. However I'm having trouble understanding the mechanism for modifying the paths.
In the plug-in controller if I tell it to use my layout
$this->layout = 'default_dashboard';
Which is in app/Views/Layout and references an image in app/webroot/default_images.
All the relative links work fine to default_images when I do this, but would like to use some of the Plugin template overides for other actions.
However if I modify the default.cpt file to include some of the images, like say a logo that is used in default_dashboard.ctp. It is unable to map to the same image location.
For example in default.ctp:
echo $this->Html->image('default_images/logo.png',array('alt' =>
'Logo','width'=>'284','height'=>'82'));
produces a path to /img/default_images/logo.png. The Plugin is configured to use the /img location, whereas I want to direct to /default_images in this case. I could make this ../default_images/logo.png, but this isn't very clean.
In addition I have js and css which is having a similar problem. Can someone please explain the mechanism for using a site-wide default.ctp so that it works with inherited plugin templates?
From hard coding the links into the template not using the Html Helper, I see that the browser's relative path is confused because of the routing. For example the first one works with the root specified, the second doesn't.
<img src="/default_images/logo.png" alt="works" width='284' height='82'>
<img src="default_images/logo.png" alt="lost" width='284' height='82'>
What's the best way to make sure that the Plugin layouts and non-plugin layouts can all find the correct path to /default_images ?
Following are the steps that you can follow to resolve relative path problem:
Create a file abc_constants.php in app\Config folder.
Include the file in app\Config\bootstrap.php
require_once(abc_constants.php);
abc_constants.php should contain:
define('HTTP_HOST', "http://" . $_SERVER['HTTP_HOST'].'/');
define('SITE_URL', HTTP_HOST.'your_app_name/');
define('IMAGE_HTTP_PATH', SITE_URL.'app/webroot/default_images/');
Use these constants in your view file accordingly.
<?php echo $this->Html->image(IMAGE_HTTP_PATH.'logo.png',array('alt' => 'Logo','width'=>'284','height'=>'82'));
It looks a bit lengthy process at first time, but once implemented, you can use these constants in Ajax calls in view files, controller's code etc.
I am trying to display an uploaded image with the Media Plugin of CakePHP.
I added the helper to the controller helper array: var $helpers = array('Media.Media');. Then, in my view, I have this code: echo $media−>file($news['Attachment'][0]['dirname'].DS.$news['Attachment'][0]['basename']);. But the problem is that, it outputs this error:
Undefined variable: media− [APP/views/news/view.ctp, line 3]
What could be the problem?
By the way, if a plugin has a model User in app/plugin/users/models/user.php and i create a new model called User in the app/models folder which one will be loaded?
Thanks in advance for any help!
First off if you are using 1.3.x refer to helpers via $this->HelperName->method(), there could be a variable called $media being set in some method. you can check this by doing var_dump($media);
The other option is that something has maybe unset it. Its very strange that you have the helper set but the variable is not set. It could also be due to adding the $helpers array to the wrong controller, you can try add it to app_controller and see if that works. if it does you had it in the wrong place.
If i got your second question correct, and we are talking about auto loading, a plugin controller will first look for the model in its own plugin directory, if it is not found there it will fall back to the app/models directory.
if you are loading it manually via the $uses array, it depends on the version of cake and how you do it. In previous versions 1.x even $uses = array('User'); would load the plugin model as cake would auto add the plugin prefix. This has changed for 2.0 afaik.
For other methods of loading a model, such as $this->loadModel('User); would load from app/models and $this->loadModel('PluginName.User') would load from the app/plugins/plugin_name/models dir.
Edit:
you are right that is funny having the error show $media- and there is the problem. did you copy that code from some site? − is not - you have a utf8 char in the code which is what its complaining about.