2009年7月16日 星期四

jommla的MVC之一

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


Developgin a Model-View-Controller Component Part 1

軟體開發框架是應用程式的基礎,開發人員能夠應用開發框架進行程式開發,joomla 1.5的開發框架釋放了強大的威力,所有的joomla的程式碼都經過嚴格的檢查並及程式碼的減量,這件文件會將使用框架,開發程式的過程展示出來。

這件文件只展示了如何開發一個hello world的component,在以後的教學文件中,這套開發框架將用來開發完整及多功能的程式,以便展現joomla的MVC設計模式。


Requirements

joomla1.5以上的版本


Introduction to Model-View-Controller

component背後的觀念相當簡單,可是一旦功能不斷增加或進行使用介面的客製化,程式碼會立刻變得複雜。

Mode-View-Controller是一種軟體設計模式,可以有效的組織程式碼,分離商業邏輯及畫面的顯示邏輯,這種設計模式背後的觀念是這樣的,把商業邏輯及顯示邏輯放在不同區塊,當改變顯示邏輯的時候,就不需要修訂商業邏輯的程式碼。

MVC component由三個部份組成,底下會簡短說明,如果要更完整的了解,參閱文件最後的相關連結。

Model

model負責包裝應用程式的資料,他會提供管理、操作及存取資料的方法,在我們的範例中,model將包含新增、移除及更新資訊的功能,他也包含了抓取資料庫資料的功能,通常,底層的資料存取應該被包裝在model中,如果應用程式後端的資料儲存系統由平面文字改成資料庫,model就應該是唯一需要變動的部份,而不是view或controller。

View

view負責從model中取出資料,與使用者互動,web應用程式的view就是html頁面,view從model中抓取資料,將資料填入template中,呈現給使用者,view並不會使資料被修改,他只會顯示從model中抓來的資料。

Controller

controller負責回應使用者的需求,web應用程式中,使用者的需求就是送出需求的頁面,controller會根據使用者的要求,使適當地回應,抓取model中的資料,並將model的資料送給view,controller 並不會在model中顯示資料,他只會觸發model中的method,並將model中的資料傳送給view,以便顯示有用的資訊。


Joomla! MVC Implementation

在joomla中,MVC設計模式使用三個類別:JModel、JView及JController,如果還需要與這三個類別更多的相關資訊,請參閱API手冊。


Creating a Component

這份文件的component,只需要五個檔案

site/hello.php - component的大門(進入位置)。
site/controller.php - 基本的controller
site/views/hello/view.html.php - view檔案
site/views/hello/tmpl/default.php - 輸出的樣板檔
hello.xml – 這個xml檔告訴joomla如何安裝這個component

進入點的檔案名稱必須與component的名稱相同,例如,如果你的component叫做"Very Intricate Name Component”,在安裝時,joomla會自動建立com_veryintricatenamecomponent目錄,進入點的檔案必須命名為veryintricatenamecomponent.php ,不然,這個component就不能運作,一些特殊字元,如底線'_',在joomla中有特殊意義,必須避免在joomla的component名稱或檔案中使用這些特殊字元。

這邊的site目錄就是component目錄。


Creating the Entry Point

joomla永遠透過單一進入點執行程式:前台應用程式的index.php或是後台程式的administration/index.php,應用程式會載入需要的component,根據url或post的資料,載入相關的component。

index.php?option=com_hello&view=hello

這會載入我們的主要檔案,這可以當做component的單一入口點:components/com_hello/hello.php,這個檔案的程式碼相當有代表性。

site/hello.php(site就是components/com_hello)


/**
* @package Joomla.Tutorials
* @subpackage Components
* components/com_hello/hello.php
* @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1
* @license GNU/GPL
*/

// No direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

// Require the base controller

require_once( JPATH_COMPONENT.DS.'controller.php' );

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

// Create the controller
$classname = 'HelloController'.$controller;
$controller = new $classname( );

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

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

第一行是安全性檢查。

JPATH_COMPONENT是目前component的絕對路徑,在我們的範例裡是components/com_hello,DS是系統的路徑分隔符號,不是斜線就是倒斜線,這由開發框架自動設定,開發人員不必因為轉換作業系統而去煩腦這些事。

載入基本的contorller以後,再檢查是不是還需要其他的controller ,這個component裡,我們只需要基本的controller,但這段程式碼還是留著,以後會用到。

JRequest::getVar()可以在url或post表單中接收變數,如果url是index.php?option=com_hello&controller=controller_name,我們可以在component中存取變數,如echo JRequest::getVar('controller');

現在 ,我們有了基本的controller—HelloController在com_hello/controller.php中,如果有需要, HelloControllerController1可以新增到com_hello/controller1.php中,controller的命名規則是這樣:{Componentname}{Controller}{Controllername}。

當controller建立後,controller會以url指定的網址執行工作,index.php?option=com_hello&task=sometask,如果沒有指定task,就會執行預設的task,預設的task是display,當設定為display時,變數view可以決定要顯示的內容,其他task是save, edit, new...。

controller可以重導頁面,通常一項task,如save完成後,最後一項程式敘述是最後的重導頁面。

主要進入點程式(hello.php)會將控制權交給controller,controller會執行request中指定的task。

我們並沒有在程式中使用php程式的結束符號:?>,這樣的用法可以避免,程式碼輸出時產生不必要的空白,這是joomla1.5預設的寫法,被應用到純php的程式檔。



Creating the Controller

我們的component只有一項工作—向世界打招呼,所以,controller非常簡單,不需要操作任何資料,我們需要做的就是載入適當的view,我們的controller中只有一個method:display(),大部份的功能都已內建在JController類別中,我們要做的全部事情只是呼叫JController::display()方法。

site/controller.php基本類別的程式碼如下:
/**
* @package Joomla.Tutorials
* @subpackage Components
* @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1
* @license GNU/GPL
*/

// No direct access

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport('joomla.application.component.controller');

/**
* Hello World Component Controller
*
* @package Joomla.Tutorials
* @subpackage Components
*/
class HelloController extends JController
{
/**
* Method to display the view
*
* @access public
*/
function display()
{
parent::display();
}

}

JController類別的建構子一定會註冊display()方法,除非用別的方法另外註冊,display會被設定為預設task。

這段程式碼中的display()方法並不必要,因為它只是呼叫parent constructor,不過,這倒是很好的線索,讓我們發現controller裡頭發生了什麼事情。

Jcontroller::display()會從request中決定view及layout,並載入view,設定layout,當你在component中建立選單,menu manager會讓administrator可以選擇view,指定layout,view是指一群資料的組合,layout決定view如何組合排列。

在我們的component中,我們只有單一的view,叫做hello,及單一的layout(default)。



Creating the View

view的工作非常簡單,他抓取要顯示的資料,再把資料送到template,資料送到template是使用JView::assignRef 方法。


site/views/hello/view.html.php的程式碼如下:


/**
* @package Joomla.Tutorials
* @subpackage Components
* @link http://docs.joomla.org/Developing_a_Model-View-Controller_Component_-_Part_1
* @license GNU/GPL
*/

// no direct access

defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.application.component.view');

/**
* HTML View class for the HelloWorld Component
*
* @package HelloWorld
*/

class HelloViewHello extends JView
{
function display($tpl = null)
{
$greeting = "Hello World!";
$this->assignRef( 'greeting', $greeting );

parent::display($tpl);
}
}



Creating the Template

joomla的template及layout是一般的php檔案,可以用來排列從view中傳來的資料,由JView::assignRef 方法指定的變數,可以在template中使用$this->{propertyname}變數,進行存取。

我們的template非常簡單,我們只要顯示從view中傳來的祝福語,這個檔案是site/views/hello/tmpl/default.php:


// No direct access

defined('_JEXEC') or die('Restricted access'); ?>

greeting; ?>





Wrapping It All UP – Creating the hello.xml File

你可以手動安裝component,使用ftp拷貝檔案,再手動修改資料庫,建立package,由joomla做安裝會是比較有效率的做法,package包含了不同的資訊。

基本的component描述(名稱)、版權敘述

需要拷貝的檔案

選擇性的:一個php檔案,進行安裝及反安裝的操作

選擇性的:一個sql檔案,進行資料庫資料的安裝及移除

檔案格式是xml,底下是hello.xml的檔案內容




Hello

2007-02-22
John Doe
john.doe@example.org
http://www.example.org
Copyright Info
License Info

1.01

Description of the component ...




controller.php
hello.php
index.html
views/index.html
views/hello/index.html
views/hello/view.html.php
views/hello/tmpl/default.php
views/hello/tmpl/index.html




Hello World!



hello.php
index.html







如果你仔細觀察這個檔案,你會發現需要拷貝的檔案,有一些並沒有討論到,例如index.html檔案,這個檔案是避免目錄下的檔案被全部列出,攤在使用者面前,一些伺服器沒有設定好,就會有這個問題,index.html檔案內容如下:



這是一個非常簡單的空白頁面。

另一個檔案是hello.php,這是admin section的進入點,暨然我們沒有admin section的進入點,他呈現的內容會跟index.html相同。