如何添加組件到joomla?
首先需要初始化一個基本的joomla組件,我們先把這個組件命名爲test, 如何初始化?有很多途逕,但衹需要學一種,其他的就無所謂了。
現在我們學的是通過把代碼打包成zip,並上傳到joomla後台extension管理裡面自動展開的辦法。
初始化組件
先隨便找個地方建個目錄,名稱叫com_test, 然後添加以下文件和目錄,
其中 ./ 代表com_test目錄自身, 裡面包含的目錄(例如site)需要我們自己手動新建:
./test.xml
./site/test.php
./site/index.html
./admin/index.html
./admin/test.php
./admin/sql/index.html
./admin/sql/updates/index.html
./admin/sql/updates/mysql/index.html
./admin/sql/updates/mysql/0.0.1.sql
以上文件裡面有很多的index.html, 實際就是防人員輸入目錄名直接遍歷到目錄結搆, 現在的一鍵安裝包環境一般都把目錄結搆給禁了, 但爲了兼容喒們筆記裡的xml文档, 最好還是建立一下, 免得報錯。
緊接著我們說說文件内容, 按照文件路逕一個一個用sublime之類的編輯器(本站就有下載)把代碼内容填進去:
./test.xml
<?xml version="1.0" encoding="utf-8"?> <extension type="component" version="3.0" method="upgrade"> <name>test</name> <!-- The following elements are optional and free of formatting constraints --> <creationDate>March 2018</creationDate> John Doe</author> john.doe@wkwkk.com</authorEmail> http://www.wkwkk.com</authorUrl> <copyright>Copyright Info</copyright> License Info</license> <!-- The version string is recorded in the components table --> <version>0.0.1</version> <!-- The description is optional and defaults to the name --> <description>Description of the test component ...</description> <!-- Runs on update; New since J2.5 --> <schemas> <schemapath type="mysql">sql/updates/mysql</schemapath> </schemas> </update> <!-- Site Main File Copy Section --> <!-- Note the folder attribute: This attribute describes the folder to copy FROM in the package to install therefore files copied in this section are copied from /site/ in the package --> <files folder="site"> <filename>index.html</filename> <filename>test.php</filename> </files> <!-- Administration Menu Section --> <menu link=index.php?option=com_test>test</menu> <!-- Administration Main File Copy Section --> <!-- Note the folder attribute: This attribute describes the folder to copy FROM in the package to install therefore files copied in this section are copied from /admin/ in the package --> <files folder="admin"> <!-- Admin Main File Copy Section --> <filename>index.html</filename> <filename>test.php</filename> <!-- SQL files section --> <folder>sql</folder> </files> </administration> </extension>
./site/test.php
這裡是test前台主文件
./admin/test.php
這裡是test後台主文件
所有com_test下面的index.html全部留空白。
插件的打包和安裝
接下來把這些代碼打包成com_test.zip, 在壓縮時把壓縮方案選擇成直接存儲, 也就是不壓縮, 然後上傳到後台當中菜單的Extensions->manage->install界面, 上傳安裝即可。
追加一個前台視圖和基本控制器給組件
joomla的組件也遵循了mvc的套路,不懂mvc的兄弟姐妹沒關系, m模型c控制器v視圖, mvc這種概念性的東西, 先了解到這裡就行, 這裡說一下v也就是View視圖層的追究方法。
首先我們修改./site/test.php的内容, 代碼替換成:
<?php // No direct access to this file defined(_JEXEC) or die(無效訪問); // Get an instance of the controller prefixed by Test $controller = JControllerLegacy::getInstance(Test); // Perform the Request task $input = JFactory::getApplication()->input; $controller->execute($input->getCmd(task)); // Redirect if set by the controller $controller->redirect();
觀察這個文件頭部,其中這段代碼
defined(_JEXEC) or die(無效訪問);
出現在好多文件的頭部, 目的是爲了防止黑客從外部瀏覽器敲鏈接直接訪問, 盡管這是一種比較落後的防止被黑客玩弄的方式, 但joomla一直熱衷使用, 對付著用吧。
接下來創建./site/controller.php, 也就是控制器文件, 代碼内容爲:
<?php // No direct access to this file defined(_JEXEC) or die(無效訪問); /** * Test Component Controller * * @since 0.0.1 */ class TestController extends JControllerLegacy { }
接下來創建./site/views/test/view.html.php, 它是一個視圖處理文件, 代碼如下:
<?php // No direct access to this file defined(_JEXEC) or die(無效訪問); /** * HTML View class for the HelloWorld Component * * @since 0.0.1 */ class TestViewTest extends JViewLegacy { /** * Display the Test view * * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return void */ function display($tpl = null) { // Assign data to the view $this->msg = 這裡是Test視圖裡插入的msg變量内容; // Display the view parent::display($tpl); } }
創建./site/views/test/tmpl/default.php, 這就是視圖模板, 代碼如下:
<?php // No direct access to this file defined(_JEXEC) or die('無效訪問'); ?> <h1><?php echo $this->msg; ?></h1>
當然了, test.xml也發生了三行變化, 以下是代碼:
<?xml version="1.0" encoding="utf-8"?><extension type="component" version="3.0" method="upgrade"> <name>Hello World!</name> <!-- The following elements are optional and free of formatting constraints --> <creationDate>January 2018</creationDate> <author>John Doe</author> <authorEmail>john.doe@example.org</authorEmail> <authorUrl>http://www.example.org</authorUrl> <copyright>Copyright Info</copyright> <license>License Info</license> <!-- The version string is recorded in the components table --> <version>0.0.2</version> <!-- The description is optional and defaults to the name --> <description>Description of the Hello World component ...</description> <!-- Runs on update; New since J2.5 --> <schemas> <schemapath type="mysql">sql/updates/mysql</schemapath> </schemas> </update> <!-- Site Main File Copy Section --> <!-- Note the folder attribute: This attribute describes the folder to copy FROM in the package to install therefore files copied in this section are copied from /site/ in the package --> <files folder="site"> <filename>index.html</filename> <filename>helloworld.php</filename> <filename>controller.php</filename> <folder>views</folder> </files> <!-- Administration Menu Section --> <menu link=index.php?option=com_helloworld>Hello World!</menu> <!-- Administration Main File Copy Section --> <!-- Note the folder attribute: This attribute describes the folder to copy FROM in the package to install therefore files copied in this section are copied from /admin/ in the package --> <files folder="admin"> <!-- Admin Main File Copy Section --> <filename>index.html</filename> <filename>helloworld.php</filename> <!-- SQL files section --> <folder>sql</folder> </files> </administration> </extension>
建立joomla後台管理用的插件基本控制器、視圖和模型
以我們當前的插件test舉例,首先要改動插件在後台的入口文件,那麽./admin/test.php的代碼需要修改成以下的樣子:
<?php // No direct access to this file defined(_JEXEC) or die('無效訪問'); // Get an instance of the controller prefixed by Test $controller = JControllerLegacy::getInstance(Test); // Perform the Request task $controller->execute(JFactory::getApplication()->input->get(task)); // Redirect if set by the controller $controller->redirect();
回看上文的代碼,覺得很前台的代碼似乎一模一樣對吧。
初始化後台控制器
基本控制器的路逕是./admin/controller.php, 代碼修改如下:
<?php // No direct access to this file defined(_JEXEC) or die('無效訪問'); /** * General Controller of Test component * * @package Joomla.Administrator * @subpackage com_helloworld * @since 0.0.7 */ class TestController extends JControllerLegacy { /** * The default view for the display method. * * @var string * @since 12.2 */ protected $default_view = Tests; }
注意這個Tests,是默認顯示的視圖名稱,關聯到後面的控制器名稱尾巴和視圖文件夾名稱。
初始化後台視圖
筆者認爲joomla的視圖實現的比較麻煩,現在新式的開發框架,display()函數已經封裝好並嵌入到框架内核當中,開發者提交控制器變量給模板變量,display(模板名稱)這種寫法,用一行語句來發起就是了,不會像joomla這麽費勁。
首先要寫視圖渲染方法文件,路逕是./admin/views/tests/view.html.php,代碼修改如下:
<?php // No direct access to this file defined(_JEXEC) or die('無效訪問'); /** * Test View * * @since 0.0.1 */ class TestViewTests extends JViewLegacy { /** * Display the Test view * * @param string $tpl The name of the template file to parse; automatically searches through the template paths. * * @return void */ function display($tpl = null) { // Get data from the model $this->items = $this->get(Items); $this->pagination = $this->get(Pagination); // Check for errors. if (count($errors = $this->get(Errors))) { JError::raiseError(500, implode(, $errors)); return false; } // Display the template parent::display($tpl); } }
其次就是寫視圖模板文件,路逕是./admin/views/tests/tmpl/default.php, 代碼如下:
<?php // No direct access to this file defined(_JEXEC) or die('無效訪問'); ?> <form action="index.php?option=com_test&view=tests" method="post" id="adminForm" name="adminForm"> <thead> <th width="1%"><?php echo JText::_(COM_TEST_NUM); ?></th> <th width="2%"> <?php echo JHtml::_(grid.checkall); ?> </th> <th width="90%"> <?php echo JText::_(COM_TEST_TESTS_NAME) ;?> </th> <th width="5%"> <?php echo JText::_(COM_TEST_PUBLISHED); ?> </th> <th width="2%"> <?php echo JText::_(COM_TEST_ID); ?> </th> </thead> <tfoot> <?php echo $this->pagination->getListFooter(); ?> </tfoot> <?php if (!empty($this->items)) : ?> <?php foreach ($this->items as $i => $row) : ?> <?php echo $this->pagination->getRowOffset($i); ?> <?php echo JHtml::_(grid.id, $i, $row->id); ?> <?php echo $row->greeting; ?> <?php echo JHtml::_(jgrid.published, $row->published, $i, tests., true, cb); ?> <?php echo $row->id; ?> <?php endforeach; ?> <?php endif; ?> </form>
上文代碼當中有一些奇怪的常量,例如COM_TEST_TESTS_NAME,是語言輸出常量。因爲本文求的是實用簡練,沒寫這套東西,實際開發當中可以換成我們想要的,或者直接把一些文本名稱寫死,不用搞這麽複襍。Joomla官方的學習路線比較詭異,生生要讓學習者先學會i18n也就是國際化,實際是沒有什麽好處的,我們先把最基本的功能實現了,再實現周邊的才是正確的學習方法。
筆者在這裡提醒讀者,這個模板衹是一個樣本,實際開發當中,joomla的方法不必一個一個都學會,按自己需要的來。