Mon 03 Nov 2008 |
Did you know? Overrides are not just for HTML!
Written by Anthony Ferrara
Arguably, one of the greatest features of Joomla! 1.5 is the ability to override nearly every single piece of HTML output that it produces. What most people don't realize, is that you can do the same thing with all the core components' classes! You can override controllers, models and views! What does this mean for you? You almost never need to actually modify the core of Joomla! All you need to override a controller, model or view (or multiple), is a simple plugin!
What can you override?
Well, you can directly override a controller, a model, and a view class (view layouts cannot be overridden in this manner, but can be using the template). This leaves the problem that what do you do for routers? Well, you can attack router build and parse rules to alter the routing behavior! So in short, you can override anything in Joomla, except the application class (JSite, JAdministrator, etc), plugins, modules, and certain includes that happen before the first plugin fires (anything loaded before onAfterInitialize). Anything else can be overridden!
How is this possible?
Very simple. If you look at JController and JModel, you'll notice that the code that instantiates the controller, model and view, it has if(!class_exists($class)) wrapped around the code used to load the respective class. What this means is that if you load your own class (of the same name), it will use that instead of the core class. Imagine the possibilities!
If you didn't already know, you can also add views to any component by simply adding the appropriate view folder (and files) to the component. Combine the adding of new views with overriding existing views, and you can change EVERYTHING in a component! So the system really is incredibly flexible.
So, how do we do this?
Well, in order to provide any semblance of performance, you'll only want to load the class if it's going to be used. Since the code uses require to load the class, jimport won't work. So how do you determine if it's going to be used? Simple, check the option variable in an onAfterRoute plugin event. Here's a basic concept (override the com_content controller):
class plgSystemComContentOverride extends JPlugin { public function __construct(&$subject, $config = array()) { parent::__construct($subject, $config); } public function onAfterRoute() { $app = JFactory::getApplication(); if('com_content' == JRequest::getCMD('option') && !$app->isAdmin()) { require_once(dirname(__FILE__) . DS . 'comcontentoverride' . DS . 'my_content_controller.php'); } } }
Are there limitations?
Yes. Unfortunately, there's no way as of yet to override parts of a class. You must override the entire class. This means, that you need to copy the entire class (but, it prevents changes from being deleted on upgrade)! But, be aware that any changes in new versions of Joomla should be merged back into this override (if there's a security fix in that particular file, the fix will be overridden until the override is changed).

2008-11-04 00:54:43
Nick
2008-11-05 21:33:50
I tested the HTML part earlier and it worked well. Just have to try this now.
2008-11-06 14:39:13
While I'm an enthousiast of extensibility, I'm surprised that this method presented is part of the official 1.5 API...
I didn't think that it would be "safe" to override a joomla class by replacing it completely, without being able to inherit from it, like in usual OOP...
It limits such overrides to only one extension, and in addition, as you well explained about updates, it is programmed hassles for upgrades, which could affect other extensions than the non-updated one...
Maybe that could be improved in 1.6 using php5 class extensions/methods overrides with normal parent calls ?
2008-11-10 10:59:59
I would test the HTML part and check whether it works well at me. Just have to try this now.
2008-12-03 09:09:05
is there a way to verride modules too?
2008-12-13 03:24:12
Views overriding is working well for me but I wasn't able to overide models.
What should be the right path in the template/html folder to use models overriding please ?
Regards.
2009-02-02 22:26:45
For example I am using sectionex to give me a list of all articles in a category. I have hacked it so it just displays them by date rather than by category but this had to be done in the model. I also added pagination (via model changes and template overrides).
I'd really like to know how to add the model file to my template so that any updates to section ex don't stop it working how I want.
But I cannot understand how to add the override to my template override file
Any extra help much appreciated
2009-03-11 14:10:59
can you give us the path and/or a complete howto to do what you explain.
i am very sorry but i try to find this on Google, but anybody talk about that...
2009-04-06 13:00:58
2009-08-18 13:53:55
Plus you can override only once.
Making this unplaned side-effect of the Joomla loader an "official API" through this blog makes matters worse.
Hope Joomla 1.6 will have a better way.
2009-09-29 21:36:21
It sounds good, even though version compatibility and security could be issues. I tried to implement it on a Joomla! 1.5.13, trying to override com_content same as you did... I tried a few things and it does not seem to override anything... Should it still work?
copied com_content under /plugins/system/comcontentoverride
I require_once the controller.php file
Any idea? I'll look at template overriding... I do not really like it... have to implement for all templates
Thank you!
Florian