Insight Joomla! (DAY 3): M-V-C Component Design

62 篇文章 0 订阅

M-V-C Component Development


First of all, I will discuss this topic basing on Joomla official site's document. And after that I working out the theory, I will explore in-depth by examing Joomsport. And finally, go to some conclusion by designing the component for Cosmos myself.


mvc-compon-file-org-struct


notes: 

        1. a letter 'm' inside a circle with purple, indicates that the file's name or folder structure is mandatory, actually the controllers, models and views folders' name are also mandatory; 
        2. all the words enclosed with '<' and '>', are just place holder, it will be replaced in a specific case, for example, if you create a component named sport, then '<component name>' should goes 'sport', the <component name>.php should be sport.php, the class name in main controller file shoud be SportController
        3. the red-color comments inside boxes are explaining for what are the file or folder be there;
        4. the light-blue comments inside boxes are introducing the classes reside in the php files, they always have relationship with regards of their naming convensions, in addition, '->' means 'estend';
        5. for readablity, the linked model, view and controller files are rendered with the same color, for example, the brown is used for sub-controller-1.


By official white paper, the structur of a Joomla! component's file orgnization can be demostrated by the above figure. And let me explain further, in assumption that we are doing a component named sport, and it has two kind of content: team and match.


Entry point and main controller


A component always has an entry point, it would be <component name>.php (sport.php, in our case), and its name is mandatory, and one controller.php, which is main controller. The entry point will always pass the control to proper controller, by default, if no sub controller required, to the main controller--namely, the controller.php under root directory of component. 


Controllers directory


And the folder 'controllers' is for all the sub controller files, in the sport case, it should have two sub controllers: team and match. Then it should have two files: team.php and match.php.


Models directory


It may have a counter-part file according to the main controller, if so, the file should be <component name>.php, (in our case sport.php). And it may also have other extra models file, in our case it should have two models for team and match, so two files should reside: team.php and match.php.



Views directory


Under this directory, each view is represented by a folder instead of a single php file, because view separate the logic and presentence, it has a handling file and a layout file. And the former is must be view.html.php, whereas the latter is placed in a sub folder named 'tmpl', it may be default.php, or form.php, depending on its functionality. If it is for collecting data from user, then form.php applied, otherwise, default.php is used for just showing some data. 


If you want create one view for matching your main controller, you should name its folder with component name, like 

--/sport/

--/sport/tmpl/

--/sport/tmpl/default.php

--/sport/view.html.php


and you may also have other views, in our sport case:


--/team/

--/team/tmpl/

--/team/tmpl/default.php

--/team/view.html.php


--/match/

--/match/tmpl/

--/match/tmpl/default.php

--/match/view.html.php



Tables directory


This folder is optional, if you have a accrospending table in database to your sub controller, then you may need it. If so, the php files shoube be named with your sub controllers' name, like team.php and match.php in our case.



The PHP script in the files


Entry point:


The entry point file is usually the place to initiate the process, its general structure:


// Require the base controller
require_once (JPATH_COMPONENT.DS.'controller.php');

// Require specific controller if requested
if($controller = JRequest::getVar('controller')) {
	require_once (JPATH_COMPONENT.DS.'controllers'.DS.$controller.'.php');
}

// Create the controller
$classname = '<component name>Controller'.$controller;
$controller = new $classname();

// Perform the Request task
$controller->execute( JRequest::getVar('task'));

// Redirect if set by the controller
$controller->redirect();

As you see, inside the entry php file, it only loads the controller file, and get the task parameter, then call execuate method of controller, to pass the control to controller. It may check the controller parameter to see if the specific sub controller is requested, if so, then the control will passe to the requested sub controller.


This file's function will not vary too much.


Main Controller:


The basic structure:


class <component name>Controller extends JController
{
	/**
	 * Method to display the view
	 *
	 * @access	public
	 */
	function display()
	{
		parent::display();
	}

}

It always define a child class of JController with name <component name>Controller, (in our case: SportController). And it must have one method override: display(), because the default value for task parameter is display. Inside display() method, you may determine which view and layout to present, before you call parent's display(). 


The class may have one crossponding method for each task in the system, means you can customize the logic. Suppose you add one task named 'team', then you should define method named 'team()', and so on.......


Sub-Controller:


The class name's pattern for sub controller is as:


class <component name>Controller<sub-controller name> extends JController
{
	/**
	 * Method to display the view
	 *
	 * @access	public
	 */
	function display()
	{
		parent::display();
	}

}

Suppose you have a file team.php under /controllers directory, then the drived class defined here should be SportControllerTeam. So you see: all the controller class must inherit base class JController.


Views:


The PHP files in this folder should have structure:


class <component name>View<view name> extends JView
{
	function display($tpl = null)
	{
		$var = // get the data and assign to variable
		$this->assignRef( '<var name>',	$var );

		parent::display($tpl);
	}
}

All view class must inherit JView. Please note that, <view name> can be:

        1. <component name>, in case you would like to create a view matching the main controller;
        2. <sub-controller name>in case you would like to create a view matching a sub controller;
        3. <other view name>, whatever name you give.


It get data from models (not must) or somewhere; push that data into template using JView::assignRef method.


As for sub-controller view, the class name pattern is the same, but the third section is sub controller name, take team view for example, the class should be:


class SportViewTeam extends JView
{
	function display($tpl = null)
	{
		$var = // get the data and assign to variable
		$this->assignRef( '<var name>',	$var );

		parent::display($tpl);
	}
}

The default.php or form.php always contain much html to form the page's layout, and they can use $this to reference the data that pushed into template previously:


<h1><?php echo $this-><variable name>; ?></h1>



Models:


Similar to View and Controller, the classes defined in this folder should match the pattern: <Component>Model<model name>. And <model name> can be:


  1. <component name>, in case you would like to create a view matching the main controller;
  2. <sub-controller name>in case you would like to create a view matching a sub controller;
  3. <other model name>, whatever name you give.


If you have sport.php in this folder, then you should tend to map it to the main controller, bacause 'sport' is just exactly component name. Then it code should be something like:


class SportModelSport extends JModel
{
	/**
	 * Gets the greeting
	 * @return string The greeting to be displayed to the user
	 */
	function get<variable name>()
	{
		// do something

		return $<variable name>;
	}
}


Tables:


Let's say, you have a table named team, in database, to store the information for teams, and you have controller named team as well, and corrosponding model and view classes defined, then undoubtedly you will use your team controller to handle data with team table in database.


In this case you can add a file named team.php into tablesfolder, and it will define a class drived from JTable like:


class TableTeam extends JTable
{
	/**
	 * Primary Key
	 * Team Id
	 * @var int
	 */
	var $tid = null;

	/**
	 * @var string
	 */
	var $<other var name> = null;

	/**
	 * Constructor
	 *
	 * @param object Database connector object
	 */
	function TableTeam(& $db) {
		parent::__construct('#__team', 'tid', $db);
	}
}


So, the class name's pattern is 'Table<table name>', and <table name> usually be <controller name>.


Auto-Linkage Behind Naming Convention


Let's use our example to descript this features of Joomla! system.  Suppose we have sport component, with team and match sub controller. So, for team controller, you may have these files and the classes defined inside:


PHP filesClasses
controllers/team.phpSportControllerTeam -> JController
views/team/view.html.phpSportViewTeam -> JView
models/team.phpSportModelTeam -> JModel
tables/team.phpTableTeam -> JTable

So, we are just be stick to the naming convention, and then what convenience system will provide?


    • In SportViewTeam class, you can simply use &$this->getModel method to get reference of SportModelTeam, without specifying model's name;
    • In SportModelTeam class, you can simply use &$this->getTable ,ethod to get the reference toTableTeam, without specifying table's name;
    • In SportModelTeam class, if you define a variable named '$_teamName' and a method getTeamName to return $_teamName, then in SportViewTeam class, you can simply use &$this->get('TeamName') to get the value of $_teamName.


Please note one trick that, the sample code always use & before one variable to obtain the reference instead of one copy of the value.


refs:


http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1

http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_2_-_Adding_a_Model

http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_3_-_Using_the_Database

http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_4_-_Creating_an_Administrator_Interface

http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_5_-_Basic_Backend_Framework

http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_6_-_Adding_Backend_Actions

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值