Difference between revisions of "JController and its subclass usage overview"

From Joomla! Documentation

Line 37: Line 37:
 
  protected function addToolbar()
 
  protected function addToolbar()
 
  {
 
  {
   ....
+
   ...
  
 
   if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) {
 
   if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) {
 
     JToolBarHelper::editList('article.edit');
 
     JToolBarHelper::editList('article.edit');
 
   }
 
   }
 +
 +
  ...
 
   }
 
   }
  

Revision as of 13:47, 18 May 2012

Joomla 1.6Joomla 1.7

Preface[edit]

You should be familiar with Joomla! 1.5 MVC pattern before starting reading this topic. If you are not, please read other topics on this wiki.

Introduction[edit]

In Joomla! 1.6, lots of MVC improvements were added. These improvements make a developer's task easier. In Joomla! 1.5, there is only one Controller class named JController. In Joomla! 1.6, JControllerAdmin and JControllerForm have been added as subclasses of JController. So there is a different usage for these three classes in Joomla! component development. This is a pattern used by most of the Joomla! core components such as com_content and com_banners.

Joomla! 1.5 Joomla! 1.6
JController JController
JControllerAdmin
JControllerForm

If you look at the admin code for com_content ($JOOMLA_INSTALLATION/administration/components/com_content), you will find controller classes located in two places: the root folder and the controllers folder. In the root folder there is a file named 'controller.php', this is the master controller of the component. It is a direct subclass of JController. In the controllers folder, there are many files named according to entities in the component e.g. article and articles. These controllers subclass either JControllerAdmin or JControllerForm.

Master Controller[edit]

The master controller found in the root folder is only responsible for the display task. This is the default task for JController. If you look at JController::getInstance in com_content/content.php, only the component name was passed as a parameter. In JController, it uses the task variable (from the request) to determine what Controller class to load. If the task variable contains a dot (.), it assumes that this variable is in the form of controller.task or controller.method. You should know that task variable specifies method of controller to run. Then in this case, it will load controller class in controllers folder and rewrite task variable to real task. If the task does not contain a dot (.), JController will load the master controller located in the root folder. To simplify, we will refer to controllers in 'controllers' folder as subcontroller. You may notice that in the master controller, a default view is also specified. If there is no view variable in the URL request, this one will be used. So in general, we can conclude:

  • To use the master controller, specify a view variable as view name to use or default one will be used.
  • To use a subcontroller, specify the task variable in the form of controller.task, clearly specified CONTROLLER_NAME.CONTROLLER_METHOD.

We can categorize display into two types: presenting a list of records (list view) and showing a detailed record item to the user (e.g. edit form). If we look at the articles view in com_content which displays a list of records to the user, we may notice that toolbar buttons are added according to user rights.

$JOOMLA_INSTALL/administrator/components/com_content/views/articles/view.html.php

 protected function addToolbar()
 {
   ...

   if (($canDo->get('core.edit')) || ($canDo->get('core.edit.own'))) {
     JToolBarHelper::editList('article.edit');
   }

   ...
  }


For example, article edit, its task variable is article.edit. This request will load the article subcontroller and execute the edit method. You may have a question, this mean we will display edit form to user. That is right! for general we do that but in Joomla! 1.6 core component, it just set article id to be edit in user session and redirect it to URL like &view=article&layout=edit. And this will be handled by master controller and edit form will be presented to user. So in this case, all display will be handled by master controller and need views.

  • If a view name is not defined in URL, default view is used and a default task (display) will be executed. We use this to display a list of records. For example, index.php?option=com_content.
  • If a view is defined but the task is not, master controller loads specified view and executes display method. This is also used to display a list of records. For example, index.php?option=com_content&view=articles.
  • If a view is specified with a task (but not in the dot format), master controller loads the specified view and executes method specified by task. This case is used to display edit form, or to present one item of record to user. An example is index.php?option=com_content&view=article&layout=edit.

When master controller creates view, it normally loads a model having the same name as the view and pushes model into the view. Then view's display method is called. Doing this, in view we can get data from model using function like $this->get("Items"). In this case, view will look for method getItems in model and execute it. Doing this, we can use one controller for display all information type in component. But many views still required. This reduces the controller class and, of course, reduces code produced by developer.

Subcontrollers[edit]

Subcontrollers will handle all CRUD tasks. For tasks such as save, delete & publish that clearly do not need a view, the subcontroller just deletes or updates records and redirects the user back to list view. In this case the user must select at least one item of record, and we usually give the name of the controller in plural form such as "articles.delete", "articles.publish_up" or "articles.publish_down". This subcontroller is generally inherited from JControllerAdmin which suppress display method by default.

The other type of CRUD, such as add or edit, at a first glance should prepare data and present the form to user. But in core component for Joomla! 1.6, they did not do like that. Looking at this kind of subcontrollers (for example ContentControllerArticle) one can see that they always are inherited from JControllerForm. But no form was presented to user in this request, it just stores item (the ID of the article) in user's session variable and redirects to master controller. As a task variable was not specified, the display method is executed as a default task.

For example: first request being processed by subcontroller may contain task=article.edit and cid[]=3. Subcontroller will create URL like "index.php?option=com_content&view=article&layout=edit" and redirect the user to master controller.

Contributors[edit]