I have a news blocks. These news are got from the database. What I need is to write $this->load->view('news'); on any of my pages and for the news to display. This implies that 'news' is a view and has display logic for the news AND has logic that calls the controller which calls the model to get the news (this part is what bothers me). I don't want to pass news to the view and inside the view pass it to the 'news' view.
Because news are going to be on roughly 70% of pages, I would like for this system to work (I want to use other views in such fashion). Is this possible?
You can check the Codeigniter HMVC extension:
Modular Extensions - HMVC
This is most useful when you need to load a view and its data within a view. Think about adding a shopping cart to a page. The shopping cart needs its own controller which may call a model to get cart data. Then the controller needs to load the data into a view. So instead of the main controller handling the page and the shopping cart, the shopping cart MVC can be loaded directly in the page. The main controller doesn’t need to know about it, and is totally isolated from it. You can work the same way with your news block.
I think it's a little bit tricky to try to explain everything on a simple SO answer and it has good documentation you can check out there.
Related
The website I'm working on has a navigation menu item called categories which is a drop-down containing some entries from the db (the users can adjust the categories from the admin panel.) The navigation is located in a base.html.twig file which is extended by all other twig files.
Question: What's the best way to get those entries? The only way that comes to my mind is use a call to {{ render(controller(...)) }} which would create a new request, what's a little overkill in my opinion and will slow the page in general down. Is there a better way to do it? Maybe an event which is called on every request and is able to transfer data to the view file?
You have two good options to achieve this :
Use render() in your twig template to call a specific method from a controller (as you said in your message)
Create a twig extension to render your menu, it's very simple : http://symfony.com/doc/current/cookbook/templating/twig_extension.html
In my opinion you should use the first option (a controller), since you only need to render your menu 1 time. Twig extension are better designed to be reused in several templates.
About your performance concern, don't worry, all you need is to cache your menu since it won't change often, and invalid the cache when the menu is updated in your backoffice.
Regards
I've searching trough google for a way of adding pagination into a module, but i could only find information about adding it into components like here:
How to add pagination for component front end (Joomla 2.5)
Is it posible to implement this same principles to make a pagination for a module?, or a different approach is needed?
I think this is not the correct way of doing to try to implement pagination in a joomla module. Normally, only component are made to be able to use standard Joomla pagination, because it uses itself models and view controller...
The example we see on the link you propose is using pagination from the view controller (view.html.php), witch extend JViewLegacy (witch is an alias for JView). Pagination is natively supported by it.
I imagine you need to show many items pages on a module, but maybe reload the page for it is not the best option. You can perhaps try to load more items, and to use a JS script to do pagination (even a slider can do it nicely), or simply to add a link to the whole section of the associated component.
You have the URL:
http:///www.site.com/controller/method/values/1/2/3
Do I have to always have the controller being called or can I have the view being called and instantiate the controller inside the view or in a bootstrap file referring to this view?
What I don't get it is if I need more than 1 controller on the view, how to archive that?
For example:
On my index page I want run a simple CMS, where the admin can change the text blocks and images of the site. That would be on the content management controller.
On my index page I also got the latest added products vitrine, what would be controlled by the controller products.
If I define www.site.com/contentmanagement or www.site.com to run the contentmanagement controller, how the product controller would be called?
Also, another example. On my menu I got a link to a page called aboutus, that would be a simple page and the only feature needed would be the content management controller to manage the texts blocks.
If I follow the pattern Im reading all over the place I will end with a link like:
http://www.site.com/contentmanagement/method/aboutus
?
Kinda lost here cause surely this URL will look weird. Would be much easier to have the URL calling the view http://www.site.com/aboutus and a boot file where I can tell the controller that should be loaded when the surfer is there ...
bootstrap would look like:
switch($view)
case: index
controller load contentmanagement
controller load product
case: aboutus
controller load contentmanagement
I appreciate any help or a light here, thanks.
by the way, Im coding in PHP.
Hm, if you want to have text blocks and images of the site (one controller), and products vitrine (second controller), then call the methods you need in one controller..
I would do it this way: when you request index page with all the elements you mentioned above, actually one controller is called, and it decides which view to show.. so in that controller, you call the all methods that you need, get the data, and pass it to the view.. if the methods are called from other controllers, just call that methods and get the data.. i often make some static methods in controllers, which I can call anywhere, so I don't have to instantiate whole object..
E.g. you call www.site.com/contentmanagement, controller is called, which will display index view, and in that controller, you call all methods you need, prepare the data, and pass that data to the final view which will be displayed..
Do I have to always have the controller being called or can I have (..blah blah..)?
It kinda depends on what you understand by "call".
Controller needs an ability to change state of both View and Model(s).
And each View need ability to request data (in Model2 MVC) from Model(s).
Thought Controller should not cause the rendering of View (which is common in all the RoR sycophants) much like View has not business in executing actions on the Controller.
What I don't get it is if I need more than 1 controller on the view, how to archive that?
Views and Controllers should have 1:1 relationship. If your view need more then one controller, you might want to look into HMVC architecture.
For example: On my index page I want run a simple CMS, (.. more blah .. ) how the product controller would be called?
CMS should be a separate application ( or at least module ) with multiple controllers.
If I follow the pattern Im reading all over the place I will end with a link like: http://www.site.com/contentmanagement/method/aboutus ?
Why not just http://site.com/cms/content/2/edit (where 2 is the ID for "about us" page). There is no law which states that URL structure for site administration must mirror the publicly available page .. hell .. it can actually cause increased vulnerability.
I am going to try to walk
What I don't get it is if I need more than 1 controller on the view,
how to archive that?
For example: On my index page I want run a simple CMS, where the admin
can change the text blocks and images of the site. That would be on
the content management controller. On my index page I also got the
latest added products vitrine, what would be controlled by the
controller products. If I define www.site.com/contentmanagement or
www.site.com to run the contentmanagement controller, how the product
controller would be called?
Having the URL to contains the controller's name is definitely nice, but it is not the requirement for MVC. So you don't have to necessary map your controller to the URL itself. A classic MVC does not tie itself to a particular naming convention, so you could call your product controller via different URL which then process the product and show the view for the product.The important for MVC is to have one controller that deals with sets of model and resulting in one view as the presentation layer. In your particular example, your entry point seems to be a single controller that interacts with both ContentManagement and Product Class/Module and the resulting interaction produce a single view.
bootstrap would look like:
switch($view)
case: index
controller load contentmanagement
controller load product
case: aboutus
controller load contentmanagement
Thus your original interaction above is not completely off, except that you are not really calling two controllers, but rather doing the following upon hitting index:
Load a controller, let's call this one IndexController
Load ContentManagement module to get the related content, you might want to put the info as part of your Model for the Index page
Load Product module to get related products, again put this into your Model
Pass the Model containing the info for rendering the page into the View
In your View, you render the Model that contains both Content from ContentManagement module and Product list from the Product module thereby producing a single view
If I follow the pattern Im reading all over the place I will end with
a link like: http://www.site.com/contentmanagement/method/aboutus ?
This is again not a requirement, you should follow what makes sense and easier for the users. Also, if you are required to follow the conventions, you could always make your URL pretty by using URL mapping.
What you are looking for is called HMVC and there are a couple of frameworks for that out there, like Kohana.
Also see this question:
What is the HMVC pattern?
I have a "standard" page layout.
A header, a footer, a main block of content on the left hand side and a sidebar on the right hand side.
Now this is all well and good, except the sidebar is replicated in each and every controller, but needs a controller to function. Sometimes the user might be logged in and therefore there will be some working out of name and such there. Also there is going to be a shopping cart there which will run from a MySQL database.
I don't want to replicate this code in each of my controllers.
How would I make a controller that will build the sidebar, load the view and everything that I can then "include" (like I would include a view) into the page.
I can forsee the creation of a sidebar class/object which I could instantiate and "add to the view" as it were.
How am I supposed to do this?
Thank you
Sounds like Modular Extensions-HMVC might be a good solution for you. The wiki I linked includes examples.
When I've had this issue in Codeigniter in the past I've built a hook that loads post_controller_constructor, executes some logic and then loads a sidebar.php view. It's fairly simple and doesn't require all that much effort.
The only issue is that if you're not using templating then it may mess with the order in which you call views. For example if you're used to:
public function index()
{
$this->load->view("header.php");
$this->load->view("my_awesome_page.php", $this->data);
$this->load->view("footer.php");
}
Then you'll have to alter it to be aware that the sidebar will be the last thing called and put the footer in there. Usually I'll have the Hook check the CI Object for a variable to see if there's a sidebar required and then if not just spit out footer.php anyway.
I'm fairly confident hooks are what you're looking for though.
I eventually created a library which did the stuff I needed. This works well. Libraries can be made effectively like simple controllers and included into them anywhere. :)
I developed an application with different MVCs using the Yii Framework
For example
I created a crud layer for Student Contact details and Student Courses etc.
All worked perfectly since each had its own menu, and when clicked eachs own view rendered.
Now my client wants everything on one page, and is quite persistent, we are talking about 7 MVC that need to be displayed on one page. Each MVC has it's own controller, model and view and own DB table. How can I render all of them on one page without re-writing the whole application? Is this possible.
If I understood your problem correctly, you simply want to merge all menu items and show the full navigation on each page.
By separating menus into standalone views and including each and one of them into a navigation view, you can have a well-structured non-repeating code.
$this->renderPartial('anotherView');
is pretty much everything you might need to know to get started. This is only callable in views as $this refers to the current controller object.
You can use views from other controllers:
$this->renderPartial('application.views.student_Contact.show',array('model'=>$model));
Hope this helps.