If you want to reuse code in views Symfony has two basic mechanisms: partials and slots. Partials are nice because you can define global partials (you can use them in any module) and module partials (they are only available in a certain module).
However, in CakePHP you only have regular templates and elements, the latter being available in every view, no matter which model/controller you are in.
Does CakePHP have anything like Symfony's partials? It would nice for example to avoid duplicating forms code for a model. You can have two templates (add and edit) that "include" a common form.
I know you can still use elements, but having a "local" elements directory for a module seems to keep things more organized. Can you suggest a workaround to simulate this?
Thanks!
Why not create a view (module_partial.ctp) inside the controller specific view directory. This will keep the code specific to the controller you want it to pertain to. So lets say you have a books controller. You want to add a BooksController specific form to some of your books views.
Create a view in the views/books/ directory called: search_partial.ctp
The search_partial.ctp will contain the HTML code you want.
Then, in any view, just call:
<?php echo $this->render('search_partial'); ?>
This will not prevent other controllers views from loading it, but it keeps the code base readable and segregated as you expect.
ALL of the globals would go into views/elements.
You can put elements in plugins.
You can do something like $this->element('something'); in the layout and have the element in a plugin and/or the main app views folder like such...
App/plugins/a_plugin/views/elements/something.ctp //only called when a controller from 'a_plugin' is called.
App/views/elements/something.ctp // called if the current plugin does not have 'something.ctp' in the elements folder
For not duplicating views like add/edit look at this https://github.com/infinitas/infinitas/blob/beta/app_controller.php#L389
Related
In Swift, you have views, views, and more views. and i'm trying to make a dynamic list of views that is varied by the files in a group.
Im aware that the groups are not saved on app creation
I cant use Init() in a view because that implies that the view was activated by an outside source (NavigationView for example)
Having a static variable is saved on app startup so i could probably do something like that.
But Essentially i'm trying to be lazy/clever and do something that you can do in java, like iterate through every class in a package and instantiate those objects as you need. I want a NavigationView that's Dynamic, like i can add an Annotation (attribute in this case, but probably not helpful for my problem, just an ides) to my Views, and have a for loop iterate through an array that contains all my possible view objects and give me a navigationView for that.
I COULD just make a Statically configured list of Views ie [v1(), v2(), v3(), v4()...] and just do a ForEach through that and work that way, i just don't want to have to configure that in the main file when i cold probably do it dynamically (if possible) and just write a new class, and at the top put like an annotation and have it auto add to an Array that i'm managing dynamically.
I know you can iterate through files, but files on compile are not in the same structure (no folders etc...) but even if i could i don't know how to do that, and add all vies to a large Set of views for a navigation pane. Like a ForEach of [arr of views] each becoming a navigation link. and i can get the Name of the View by doing View.name or whatever
TLDR:
I want to have my Views Automatically Add themselves to a Static data list (Array of Views probably) and be able to have a navigationView Dynamically just add it to the clickable NavViews and replace this:
With something that is just a loop of all my possible views that i've declared somehow.
Is this possible? if so how would i go about doing something like this
also, i know its probably not the best idea, but for the sake of learning id like to understand how to do this, then maybe a better way of going about what i want so i don't have a centralized place, and i can make it dynamic
I have a controller for posts and an element for comments. I want to include the posts view somehow in comment element. Is this possible to include the PostsController view into an element?
I know how to include elements but never heard or thought of including Controller views.
You can get the data for the PostsController view using requestAction. If you want to include view-layer code in two different places, pull it into an element - that's what they're for.
I am new to Cakephp and indeed OOP, so forgive me if i haven't fully grasped the MVC concept yet. I have search a lot but cannot find an answer - perhaps my way of working below is not correct. I hope you can help.
I am building a site which will have many elements relating to their tables and data. I intend to use a view to pick and choose the relevant elements and any parameters needed.
For example, the homepage of my site will have two elements - a latestusers element and a latestscores element. I am trying to use a view not related to either the users or scores models/controllers, stored in 'other/index.ctp'.
I have tried using set() to pass a variable from the users controller (latestusers action) into the other/index.ctp view, but the viewVars remain empty. Could this be due to scope of the variable (i think it is fine for a view in the users folder, i.e. a view specific to the users controller).
I could achieve what i want to do by using global variables, but i think this is missing the point of MVC/OOP. Would be grateful for any suggestions.
I can include code if need be - it is fairly basic at this stage - but i feel my problem lies with how i am going about things, not the code itself.
Cheers,
James
Yes, the issue is with the scope. If you're going to use variables in the element you'll need to pass them in from your view. So the flow would look something like this
Controller $this->set()s the variable into your current view/layout
Your view/layout calls $this->element with the current element path.
Your element uses those variables.
In number 2 you need to pass your variables as an array of data. This section on the cookbook gives more information : http://book.cakephp.org/view/1081/Elements
<?php echo$this->element('helpbox',
array("helptext" => "Oh, this text is very helpful."));?>
Note - I didn't understand part of the question. Just want to make sure you are passing data to the correct view. You should not be calling the view of another controller in your active controller.
Your other/index.ctp should be an element and that element should be called from your layout.
Many models in my app are similar, and I've automated the creation of each CTP for the standard CRUD for each. In other words, the ctp files themselves for each model are identical. I pass the fields used to create the form as an array to a helper. I find though I'm just creating the same files over and over in separate view directories. Is there a way I can refer to say 1 add.ctp for each of the model controllers? I hope my question is clear enough. Thanks.
$this->render('/controller/view');
You can render any view from any controller, so if you want to create one "index" view and its generic enough that you are just passing $data in, you could render the same view each time.
You could take it one step further and create that view in your elements folder to completely detach it from your controllers.
http://book.cakephp.org/view/980/render
https://github.com/infinitas/infinitas/blob/beta/app_controller.php#L389
Using cakePHP my goal is to combine the index view of two or more controllers in one layout page.
Example:
I have controllers for: news, events, links.
I want to show the last five entries from each table in one layout page.
Also, when one of the links from the views is selected it should take the user to the respective view for that record.
I have read through the books section on views but don't see how making a view into an element would accomplish this.
What confuses me is how to combine from three separate controller/views into one layout?
Thanks
Create methods in your News, Event and Link models for fetching the last 5 records. Then in your controller either include the models in the Controller::uses property, or in the action use ClassRegistry::init() to get access to the model, e.g.
function my_action() {
$news = ClassRegistry::init('News')->getRecent();
$events = ClassRegistry::init('Event')->getRecent();
$links = ClassRegistry::init('Link')->getRecent();
$this->set(compact('news', 'events', 'links'));
}
You can then call these model methods from any controller action, keeping your application DRY.
In your my_action.ctp view, and indeed many other views, just render the elements e.g.
// my_action.ctp
<?php
echo $this->element('recent_news');
echo $this->element('recent_events');
echo $this->element('recent_links');
?>
Your elements can then just iterate over the $news (or whatever) variable displaying the items with links to the 'view' actions in their respective controllers.
Just because a controller matches a model, doesn't mean you can't use other models in it.
First I would say that views and controllers are not necessarily tied together -- Cake will implicitly add the view specified by the file heirarchy / naming convention, but this doesn't necessarily have to be the case. So try to think of the views as decoupled from the controller (which is one of the main purposes for using the MVC architecture).
Assuming your three views (A,B,C) are exactly how you want them copied, put them into an element (which is just a view file located in the special APP/views/elements/ directory). Now you can use them in either layouts or other views, just by making a call to $this->element( 'elementName', array( 'options' ) ).
Basically, just abstract the code you want to display into elements, then insert those elements into the desired layouts.
You can set up your controller to use the RequestHandler and then make your view elements capable of fetching their own data from separate controllers in your application.
This link explains it better than I can
http://bakery.cakephp.org/articles/view/creating-reusable-elements-with-requestaction
One thing to keep in mind is that the controller actions you are calling should account for caching their own data so you don't do unnecessary database queries.