在本教程中,我們將創建在Magento的一個新的“品牌”企業,可以通過管理面板來管理。 一旦我們完成后,您將能夠創建,更新和刪除,可以在前端獨立觀看品牌,更以同樣的方式,你可以與現有的實體,如“產品”和互動“類別”。
此外,我們將我們的新品牌實體與其他Magento的實體,如產品相關聯。 這個過程本身是很漫長的,因為我會詳細解釋每一個步驟,但它確實是容易,一旦你知道怎么了,它是Magento的平臺有多么強大可以用最小的努力一個很好的例子。
我們將涵蓋以下主題:
- 在Magento中創建一個新品牌的實體。
- 瀏覽,篩選和排序品牌在Magento的管理面板。
- 創建,更新和刪除的品牌在管理面板。
- 創建一個品牌列表,查看前端頁面。
- 聯營公司品牌與產品。
- 顯示產品的品牌聯想在前端。
- 整個包括圖像。
本教程是指的Magento社區版1.8.0.0,在寫作的時候可用的最新版本。 但是代碼和原則適用于所有最近的Magento版本,社區和企業。
雖然我試圖盡可能詳盡越好,我的解釋, 注釋的代碼有時是解釋某些事情的最好方法 ,所以你會發現很多評論中的代碼片段。 該代碼段在末尾鏈接到包含更多的用途和項目比都包含在本教程中,向您展示如何擴展的事情,你將了解這里。
創建我們的模塊
首先創建以下文件夾和文件結構。 從目前來看,所有的文件將是空的。 通常情況下,這些文件和文件夾將在根據需要一段時間來創建的,但為了本教程中,我們將投入一切就緒了前面。
像往常一樣,我假設你已經知道創建一個Magento的模塊的基礎知識 ,并熟悉這個步驟,無需任何解釋。
app - code - community - SmashingMagazine - BrandDirectory - Block - Adminhtml - Brand - Edit - Form.php - Edit.php - Grid.php - Brand.php - Helper - Data.php - Model - Resource - Brand - Collection.php - Brand.php - Brand.php - controllers - Adminhtml - BrandController.php - etc - adminhtml.xml - config.xml - sql - smashingmagazine_branddirectory_setup - install-0.0.1.php - etc - modules - SmashingMagazine_BrandDirectory.xml
模塊安裝腳本
對于我們的模塊是任何使用,我們需要一個地方來存儲我們的數據。 因此,我們需要編寫一個模塊的安裝腳本來創建數據庫表來保存我們的品牌實體的信息。 安裝腳本存儲在模塊內的兩個地方, /sql
和/data
。 前者是物理變化,以您的Magento的實例,如數據庫架構的更新,而后者是從現有的架構填充或刪除條目。
在我們的例子中,我們添加了一個新的表。 因此,編輯該文件在sql/smashingmagazine_branddirectory_setup/install-0.0.1.php
用下面的代碼:
<?php $this->startSetup(); /** * Note: there are many ways in Magento to achieve the same result of * creating a database table. For this tutorial, we have gone with the * Varien_Db_Ddl_Table method, but feel free to explore what Magento * does in CE 1.8.0.0 and earlier versions. */ $table = new Varien_Db_Ddl_Table(); /** * This is an alias of the real name of our database table, which is * configured in config.xml. By using an alias, we can refer to the same * table throughout our code if we wish, and if the table name ever has * to change, we can simply update a single location, config.xml * - smashingmagazine_branddirectory is the model alias * - brand is the table reference */ $table->setName($this->getTable('smashingmagazine_branddirectory/brand')); /** * Add the columns we need for now. If you need more later, you can * always create a new setup script as an upgrade. We will introduce * that later in this tutorial. */ $table->addColumn( 'entity_id', Varien_Db_Ddl_Table::TYPE_INTEGER, 10, array( 'auto_increment' => true, 'unsigned' => true, 'nullable'=> false, 'primary' => true ) ); $table->addColumn( 'created_at', Varien_Db_Ddl_Table::TYPE_DATETIME, null, array( 'nullable' => false, ) ); $table->addColumn( 'updated_at', Varien_Db_Ddl_Table::TYPE_DATETIME, null, array( 'nullable' => false, ) ); $table->addColumn( 'name', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array( 'nullable' => false, ) ); $table->addColumn( 'url_key', Varien_Db_Ddl_Table::TYPE_VARCHAR, 255, array( 'nullable' => false, ) ); $table->addColumn( 'description', Varien_Db_Ddl_Table::TYPE_TEXT, null, array( 'nullable' => false, ) ); $table->addColumn( 'visibility', Varien_Db_Ddl_Table::TYPE_BOOLEAN, null, array( 'nullable' => false, ) ); /** * These two important lines are often missed. */ $table->setOption('type', 'InnoDB'); $table->setOption('charset', 'utf8'); /** * Create the table! */ $this->getConnection()->createTable($table); $this->endSetup();
我們的初始化模塊
在這一點上,我們還沒有一個活躍的Magento模塊;我們只是有一些文件夾和空文件和一個安裝設置腳本,不會做任何事情。 這是有意的。 在接下來的步驟中,我們將填充app/etc/modules
的XML文件,并配置config.xml
,使Magento的知道去哪里尋找我們的安裝腳本,在下次訪問該網站后,將觸發我們的安裝腳本的內容,運行。
如果我們全面完成這些任務的另一種方式(即先配置的模塊,然后填入安裝腳本),然后有機會的Magento會認為我們的模塊是在0.0.1版本,而我們的安裝腳本仍空的,并且作為結果,該腳本將有效必須被跳過。 所以,限制面掌時刻為你們,我試圖保持步驟盡可能安全的順序。
配置我們的模塊
編輯該文件在app/etc/modules/SmashingMagazine_BrandDirectory.xml
,并添加以下,以使我們的模塊:
<?xml version="1.0"?> <config> <modules> <SmashingMagazine_BrandDirectory> <active>true</active> <codePool>community</codePool> </SmashingMagazine_BrandDirectory> </modules> </config>
你會注意到我們使用的是社區codepool。 這BrandDirectory模塊不包含任何客戶特定的代碼或自定義。 相反,它將包含對我們的新的實體,它可以在其他的模塊中使用,這取決于使用的情況下的構造塊。 因此,該社區模塊可以被投進任何Magento的實例,并原樣使用,無需任何代碼需要被改變。 如果要求每次使用代碼更改,那么這將是更適合本地代碼庫。
現在,我們要告訴Magento的,我們有一個版本號,這實際上將決定哪些設置腳本運行,在哪里可以找到安裝腳本的模塊。 編輯etc/config.xml
有以下內容:
<?xml version="1.0"?> <config> <modules> <SmashingMagazine_BrandDirectory> <!-- This is the version number that our module is currently at. In order for setup scripts to run, their version number must be less than or equal to this value. As we add upgrade scripts, we increment this value. The next time your Magento instance is accessed, Magento will compare values in the DB table 'core_resource' against this value. If the DB is lower, it will attempt to run any setup scripts for the module and then update the database table to match this value. --> <version>0.0.1</version> </SmashingMagazine_BrandDirectory> </modules> <global> <models> <!-- This is the Model alias referred to in install-0.0.1.php. --> <smashingmagazine_branddirectory> <!-- This tells Magento where to find resource materials for this module. --> <resourceModel>smashingmagazine_branddirectory_resource</resourceModel> </smashingmagazine_branddirectory> <!-- This alias must match the above <resourceModel/> value. --> <smashingmagazine_branddirectory_resource> <entities> <!-- This is the table alias referred to in install-0.0.1.php. --> <brand> <!-- This is the actual name of the database table. --> <table>smashingmagazine_branddirectory_brand</table> </brand> </entities> </smashingmagazine_branddirectory_resource> </models> <resources> <!-- This must match our folder name in the module sql folder. --> <smashingmagazine_branddirectory_setup> <setup> <!-- This defines which module the setup scripts in this location belong to. --> <module>SmashingMagazine_BrandDirectory</module> <!-- In each setup script, this value determines the class of $this. --> <class>Mage_Eav_Model_Entity_Setup</class> </setup> <!-- This is only relevant if you have multiple database connections. --> <connection> <use>core_setup</use> </connection> </smashingmagazine_branddirectory_setup> </resources> </global> </config>
是一切工作這么遠嗎?
來吧,訪問您的網站的任何頁面 – 主頁就行了。 Magento的會發現,它具有在0.0.1版本的新模塊,但它有這個模塊,在沒有記錄core_resource
數據庫表。 這遺失的項目將觸發Magento的尋找一個安裝設置腳本并執行其內容。
如果一切順利…
如果一切順利的話,那么它會看起來像什么也沒發生。 Magento的頁面可能需要幾分鐘的時間更長的時間來加載,而我們的安裝腳本的內容是運行(即在新的數據庫表被創建),然后頁面會不斷加載正常。 您現在有兩個任務要執行,檢查,一切都已經如預期:
- 保證Magento的知道你的模塊,而模塊是通過去激活
System → Configuration → Advanced → Advanced
。 - 通過任一終端或類似PHPMyAdmin的東西進入你的數據庫,看看是否Magento的創造了一個新的表,
smashingmagazine_branddirectory_brand
。
如果所有的不順利…
如果一切不順利,那么它也可能看起來像什么都沒有發生,只是這一次沒有什么事情發生了! 這樣做的原因可能是錯別字在config.xml
,嚴重命名文件夾或文件(注意大小寫敏感)或別的東西。 經過前面的步驟,仔細檢查,一切都是理所應當的。
在另一方面,你可能會看到一個錯誤消息 – 也許是“PHP的致命錯誤”或報告頁面,根據錯誤的嚴重程度。 用你的調試技巧,以找出問題并糾正它,再仔細檢查在本教程前面的所有步驟。
“出錯。 我如何再試一次嗎?“
從頭再試一次,你可以執行以下操作 – 不是所有的可能需要,根據Magento的多遠,得到了什么事情之前。 您將需要直接訪問你的數據庫,因為這無法通過Magento的執行:
- 在
core_resource
表,刪除單列smashingmagazine_branddirectory_setup
。 - 刪除
smashingmagazine_branddirectory_brand
表。
創建我們的助手
我們實際上并不需要定義的任何自定義功能在輔助本教程。 但是,我們將添加菜單項到使用一個幫手翻譯目的的管理面板,因此我們可以簡單地創建一個Helper/Data.php
,忘掉它。
<?php class SmashingMagazine_BrandDirectory_Helper_Data extends Mage_Core_Helper_Abstract { }
創建我們的模型
接下來,我們需要創建模型和資源模型,使我們可以在創建和保存持久的品牌數據到數據庫中,顯示了我們在Magento管理面板電網品牌信息,并顯示我們的品牌客戶在前端。
品牌型號
我們需要定義一個模型,使開發人員能夠與我們的品牌實體進行交互。 我不會去到任何更詳細的比,因為人們比我聰明毫無疑問已經解釋過什么是模型呢,可以隨意搜索了一些文章。 現在,我會堅持讓我們的模型做的,我們需要工作,以繼續我們的教程。 因此,編輯Model/Brand.php
與此:
<?php class SmashingMagazine_BrandDirectory_Model_Brand extends Mage_Core_Model_Abstract { const VISIBILITY_HIDDEN = '0'; const VISIBILITY_DIRECTORY = '1'; protected function _construct() { /** * This tells Magento where the related resource model can be found. * * For a resource model, Magento will use the standard model alias - * in this case 'smashingmagazine_branddirectory' - and look in * config.xml for a child node <resourceModel/>. This will be the * location that Magento will look for a model when * Mage::getResourceModel() is called - in our case, * SmashingMagazine_BrandDirectory_Model_Resource. */ $this->_init('smashingmagazine_branddirectory/brand'); } /** * This method is used in the grid and form for populating the dropdown. */ public function getAvailableVisibilies() { return array( self::VISIBILITY_HIDDEN => Mage::helper('smashingmagazine_branddirectory') ->__('Hidden'), self::VISIBILITY_DIRECTORY => Mage::helper('smashingmagazine_branddirectory') ->__('Visible in Directory'), ); } protected function _beforeSave() { parent::_beforeSave(); /** * Perform some actions just before a brand is saved. */ $this->_updateTimestamps(); $this->_prepareUrlKey(); return $this; } protected function _updateTimestamps() { $timestamp = now(); /** * Set the last updated timestamp. */ $this->setUpdatedAt($timestamp); /** * If we have a brand new object, set the created timestamp. */ if ($this->isObjectNew()) { $this->setCreatedAt($timestamp); } return $this; } protected function _prepareUrlKey() { /** * In this method, you might consider ensuring * that the URL Key entered is unique and * contains only alphanumeric characters. */ return $this; } }
品牌資源模型
正如我在介紹上述模型,我不會進入任何更多的細節還不如說是資源模型的工作是保持和檢索數據庫中的數據。 所以編輯Model/Resource/Brand.php
與此:
<?php class SmashingMagazine_BrandDirectory_Model_Resource_Brand extends Mage_Core_Model_Resource_Db_Abstract { protected function _construct() { /** * Tell Magento the database name and primary key field to persist * data to. Similar to the _construct() of our model, Magento finds * this data from config.xml by finding the <resourceModel/> node * and locating children of <entities/>. * * In this example: * - smashingmagazine_branddirectory is the model alias * - brand is the entity referenced in config.xml * - entity_id is the name of the primary key column * * As a result, Magento will write data to the table * 'smashingmagazine_branddirectory_brand' and any calls * to $model->getId() will retrieve the data from the * column named 'entity_id'. */ $this->_init('smashingmagazine_branddirectory/brand', 'entity_id'); } }
品牌資源集合
最后,我們需要一個資源集合,允許迭代通過我們的品牌的事情,比如管理面板電網和前端列表頁面。 編輯Model/Resource/Brand/Collection.php
與此:
<?php class SmashingMagazine_BrandDirectory_Model_Resource_Brand_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract { protected function _construct() { parent::_construct(); /** * Tell Magento the model and resource model to use for * this collection. Because both aliases are the same, * we can omit the second paramater if we wish. */ $this->_init( 'smashingmagazine_branddirectory/brand', 'smashingmagazine_branddirectory/brand' ); } }
創建我們的管理員塊
最繁重的工作,現在已經完成。 數據庫是準備被填充,而模型和資源模型準備填充它們。 我們只需要創建接口這樣做。 我們將通過創建和配置管理模塊,以顯示我們的品牌作為網格在管理面板,并允許它們被創建和更新開始。
Grid容器座
網格容器的工作就是安置的品牌項目,以顯示在Magento的管理面板各行。 網格容器是類似的包裝,并包括在右上角(例如,“添加”)按鈕。 編輯Block/Adminhtml/Brand.php
與此:
<?php class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand extends Mage_Adminhtml_Block_Widget_Grid_Container { protected function _construct() { parent::_construct(); /** * The $_blockGroup property tells Magento which alias to use to * locate the blocks to be displayed in this grid container. * In our example, this corresponds to BrandDirectory/Block/Adminhtml. */ $this->_blockGroup = 'smashingmagazine_branddirectory_adminhtml'; /** * $_controller is a slightly confusing name for this property. * This value, in fact, refers to the folder containing our * Grid.php and Edit.php - in our example, * BrandDirectory/Block/Adminhtml/Brand. So, we'll use 'brand'. */ $this->_controller = 'brand'; /** * The title of the page in the admin panel. */ $this->_headerText = Mage::helper('smashingmagazine_branddirectory') ->__('Brand Directory'); } public function getCreateUrl() { /** * When the "Add" button is clicked, this is where the user should * be redirected to - in our example, the method editAction of * BrandController.php in BrandDirectory module. */ return $this->getUrl( 'smashingmagazine_branddirectory_admin/brand/edit' ); } }
網格塊
當渲染網格,Magento的會希望找到一個網格塊在_controller
在上述網格容器定義的位置,所以現在我們將創建此。 在這里,我們可以定義哪些字段從數據庫中并顯示在管理面板電網檢索和Magento的會自動允許搜索和過濾這些列。 編輯Block/Adminhtml/Brand/Grid.php
與此:
<?php class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand_Grid extends Mage_Adminhtml_Block_Widget_Grid { protected function _prepareCollection() { /** * Tell Magento which collection to use to display in the grid. */ $collection = Mage::getResourceModel( 'smashingmagazine_branddirectory/brand_collection' ); $this->setCollection($collection); return parent::_prepareCollection(); } public function getRowUrl($row) { /** * When a grid row is clicked, this is where the user should * be redirected to - in our example, the method editAction of * BrandController.php in BrandDirectory module. */ return $this->getUrl( 'smashingmagazine_branddirectory_admin/brand/edit', array( 'id' => $row->getId() ) ); } protected function _prepareColumns() { /** * Here, we'll define which columns to display in the grid. */ $this->addColumn('entity_id', array( 'header' => $this->_getHelper()->__('ID'), 'type' => 'number', 'index' => 'entity_id', )); $this->addColumn('created_at', array( 'header' => $this->_getHelper()->__('Created'), 'type' => 'datetime', 'index' => 'created_at', )); $this->addColumn('updated_at', array( 'header' => $this->_getHelper()->__('Updated'), 'type' => 'datetime', 'index' => 'updated_at', )); $this->addColumn('name', array( 'header' => $this->_getHelper()->__('Name'), 'type' => 'text', 'index' => 'name', )); $this->addColumn('lastname', array( 'header' => $this->_getHelper()->__('Url Key'), 'type' => 'text', 'index' => 'url_key', )); $brandSingleton = Mage::getSingleton( 'smashingmagazine_branddirectory/brand' ); $this->addColumn('visibility', array( 'header' => $this->_getHelper()->__('Visibility'), 'type' => 'options', 'index' => 'visibility', 'options' => $brandSingleton->getAvailableVisibilies() )); /** * Finally, we'll add an action column with an edit link. */ $this->addColumn('action', array( 'header' => $this->_getHelper()->__('Action'), 'width' => '50px', 'type' => 'action', 'actions' => array( array( 'caption' => $this->_getHelper()->__('Edit'), 'url' => array( 'base' => 'smashingmagazine_branddirectory_admin' . '/brand/edit', ), 'field' => 'id' ), ), 'filter' => false, 'sortable' => false, 'index' => 'entity_id', )); return parent::_prepareColumns(); } protected function _getHelper() { return Mage::helper('smashingmagazine_branddirectory'); } }
Form容器座
表格容器塊具有類似于柵格容器的功能,但用于創建或編輯的實體。 編輯Block/Adminhtml/Brand/Edit.php
與此:
<?php class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand_Edit extends Mage_Adminhtml_Block_Widget_Form_Container { protected function _construct() { $this->_blockGroup = 'smashingmagazine_branddirectory_adminhtml'; $this->_controller = 'brand'; /** * The $_mode property tells Magento which folder to use * to locate the related form blocks to be displayed in * this form container. In our example, this corresponds * to BrandDirectory/Block/Adminhtml/Brand/Edit/. */ $this->_mode = 'edit'; $newOrEdit = $this->getRequest()->getParam('id') ? $this->__('Edit') : $this->__('New'); $this->_headerText = $newOrEdit . ' ' . $this->__('Brand'); } }
表座
在窗體模塊中,我們定義哪些字段可以創建或編輯實體時進行管理。 編輯Block/Adminhtml/Brand/Edit/Form.php
與此:
<?php class SmashingMagazine_BrandDirectory_Block_Adminhtml_Brand_Edit_Form extends Mage_Adminhtml_Block_Widget_Form { protected function _prepareForm() { // Instantiate a new form to display our brand for editing. $form = new Varien_Data_Form(array( 'id' => 'edit_form', 'action' => $this->getUrl( 'smashingmagazine_branddirectory_admin/brand/edit', array( '_current' => true, 'continue' => 0, ) ), 'method' => 'post', )); $form->setUseContainer(true); $this->setForm($form); // Define a new fieldset. We need only one for our simple entity. $fieldset = $form->addFieldset( 'general', array( 'legend' => $this->__('Brand Details') ) ); $brandSingleton = Mage::getSingleton( 'smashingmagazine_branddirectory/brand' ); // Add the fields that we want to be editable. $this->_addFieldsToFieldset($fieldset, array( 'name' => array( 'label' => $this->__('Name'), 'input' => 'text', 'required' => true, ), 'url_key' => array( 'label' => $this->__('URL Key'), 'input' => 'text', 'required' => true, ), 'description' => array( 'label' => $this->__('Description'), 'input' => 'textarea', 'required' => true, ), 'visibility' => array( 'label' => $this->__('Visibility'), 'input' => 'select', 'required' => true, 'options' => $brandSingleton->getAvailableVisibilies(), ), /** * Note: we have not included created_at or updated_at. * We will handle those fields ourself in the model * before saving. */ )); return $this; } /** * This method makes life a little easier for us by pre-populating * fields with $_POST data where applicable and wrapping our post data * in 'brandData' so that we can easily separate all relevant information * in the controller. You could of course omit this method entirely * and call the $fieldset->addField() method directly. */ protected function _addFieldsToFieldset( Varien_Data_Form_Element_Fieldset $fieldset, $fields) { $requestData = new Varien_Object($this->getRequest() ->getPost('brandData')); foreach ($fields as $name => $_data) { if ($requestValue = $requestData->getData($name)) { $_data['value'] = $requestValue; } // Wrap all fields with brandData group. $_data['name'] = "brandData[$name]"; // Generally, label and title are always the same. $_data['title'] = $_data['label']; // If no new value exists, use the existing brand data. if (!array_key_exists('value', $_data)) { $_data['value'] = $this->_getBrand()->getData($name); } // Finally, call vanilla functionality to add field. $fieldset->addField($name, $_data['input'], $_data); } return $this; } /** * Retrieve the existing brand for pre-populating the form fields. * For a new brand entry, this will return an empty brand object. */ protected function _getBrand() { if (!$this->hasData('brand')) { // This will have been set in the controller. $brand = Mage::registry('current_brand'); // Just in case the controller does not register the brand. if (!$brand instanceof SmashingMagazine_BrandDirectory_Model_Brand) { $brand = Mage::getModel( 'smashingmagazine_branddirectory/brand' ); } $this->setData('brand', $brand); } return $this->getData('brand'); } }
創建我們的管理員控制器
現在,我們需要一個控制器接受請求,并從上面呈現容器塊。 控制器也將處理POST
請求,根據需要來創建,更新和刪除的品牌。 編輯controllers/Adminhtml/BrandController.php
與此:
<?php class SmashingMagazine_BrandDirectory_Adminhtml_BrandController extends Mage_Adminhtml_Controller_Action { /** * Instantiate our grid container block and add to the page content. * When accessing this admin index page, we will see a grid of all * brands currently available in our Magento instance, along with * a button to add a new one if we wish. */ public function indexAction() { // instantiate the grid container $brandBlock = $this->getLayout() ->createBlock('smashingmagazine_branddirectory_adminhtml/brand'); // Add the grid container as the only item on this page $this->loadLayout() ->_addContent($brandBlock) ->renderLayout(); } /** * This action handles both viewing and editing existing brands. */ public function editAction() { /** * Retrieve existing brand data if an ID was specified. * If not, we will have an empty brand entity ready to be populated. */ $brand = Mage::getModel('smashingmagazine_branddirectory/brand'); if ($brandId = $this->getRequest()->getParam('id', false)) { $brand->load($brandId); if ($brand->getId() < 1) { $this->_getSession()->addError( $this->__('This brand no longer exists.') ); return $this->_redirect( 'smashingmagazine_branddirectory_admin/brand/index' ); } } // process $_POST data if the form was submitted if ($postData = $this->getRequest()->getPost('brandData')) { try { $brand->addData($postData); $brand->save(); $this->_getSession()->addSuccess( $this->__('The brand has been saved.') ); // redirect to remove $_POST data from the request return $this->_redirect( 'smashingmagazine_branddirectory_admin/brand/edit', array('id' => $brand->getId()) ); } catch (Exception $e) { Mage::logException($e); $this->_getSession()->addError($e->getMessage()); } /** * If we get to here, then something went wrong. Continue to * render the page as before, the difference this time being * that the submitted $_POST data is available. */ } // Make the current brand object available to blocks. Mage::register('current_brand', $brand); // Instantiate the form container. $brandEditBlock = $this->getLayout()->createBlock( 'smashingmagazine_branddirectory_adminhtml/brand_edit' ); // Add the form container as the only item on this page. $this->loadLayout() ->_addContent($brandEditBlock) ->renderLayout(); } public function deleteAction() { $brand = Mage::getModel('smashingmagazine_branddirectory/brand'); if ($brandId = $this->getRequest()->getParam('id', false)) { $brand->load($brandId); } if ($brand->getId() < 1) { $this->_getSession()->addError( $this->__('This brand no longer exists.') ); return $this->_redirect( 'smashingmagazine_branddirectory_admin/brand/index' ); } try { $brand->delete(); $this->_getSession()->addSuccess( $this->__('The brand has been deleted.') ); } catch (Exception $e) { Mage::logException($e); $this->_getSession()->addError($e->getMessage()); } return $this->_redirect( 'smashingmagazine_branddirectory_admin/brand/index' ); } }
完成配置
這就是我們所需要的后端代碼。 我們只需要進行一些更改,以config.xml
告訴Magento的在哪里可以找到我們的控制器,模塊,模型和幫手。 我們也有一個菜單項添加到管理面板為方便管理我們的品牌實體。
config.xml中
我們需要的塊,助手和模型定義添加到我們的模塊配置,這樣的Magento知道在哪里可以找到這些文件,以及一個管理路由器,這樣的Magento知道在哪里可以找到我們的控制器,我們將要添加的菜單項下一個步驟。 我們的最終版本etc/config.xml
文件將如下所示:
<?xml version="1.0"?> <config> <modules> <SmashingMagazine_BrandDirectory> <!-- This is the version number that our module is currently at. In order for setup scripts to run, their version number must be less than or equal to this value. As we add upgrade scripts, we increment this value. The next time your Magento instance is accessed, Magento will compare values in the database table 'core_resource' against this value. If the database is lower, it will attempt to run any setup scripts for the module and then update the database table to match this value. --> <version>0.0.1</version> </SmashingMagazine_BrandDirectory> </modules> <global> <!-- add an adminhtml block definition --> <blocks> <smashingmagazine_branddirectory_adminhtml> <class>SmashingMagazine_BrandDirectory_Block_Adminhtml</class> </smashingmagazine_branddirectory_adminhtml> </blocks> <!-- Add a helper definition for use in adminhtml.xml menu translation. --> <helpers> <smashingmagazine_branddirectory> <class>SmashingMagazine_BrandDirectory_Helper</class> </smashingmagazine_branddirectory> </helpers> <models> <!-- This is the model alias referred to in install-0.0.1.php. --> <smashingmagazine_branddirectory> <!-- This tells Magento where to find models for this module. --> <class>SmashingMagazine_BrandDirectory_Model</class> <!-- This tells Magento where to find resource materials for this module. --> <resourceModel>smashingmagazine_branddirectory_resource</resourceModel> </smashingmagazine_branddirectory> <!-- This alias must match the <resourceModel/> value above. --> <smashingmagazine_branddirectory_resource> <!-- This tells Magento where to find resource models for this module. --> <class>SmashingMagazine_BrandDirectory_Model_Resource</class> <entities> <!-- This is the table alias referred to in install-0.0.1.php. --> <brand> <!-- This is the name of the database table itself. --> <table>smashingmagazine_branddirectory_brand</table> </brand> </entities> </smashingmagazine_branddirectory_resource> </models> <resources> <!-- This must match our folder name in the module sql folder. --> <smashingmagazine_branddirectory_setup> <setup> <!-- This defines which module the setup scripts in this location belong to. --> <module>SmashingMagazine_BrandDirectory</module> <!-- In each setup script, this value determines the class of $this. --> <class>Mage_Eav_Model_Entity_Setup</class> </setup> <!-- This is relevant only if you have multiple database connections. --> <connection> <use>core_setup</use> </connection> </smashingmagazine_branddirectory_setup> </resources> </global> <!-- Add a router for access to our admin panel controller. --> <admin> <routers> <!-- This is the alias for this router. --> <smashingmagazine_branddirectory_admin> <!-- This basically informs Magento to use the admin scope for requests to this router. --> <use>admin</use> <args> <!-- This tells Magento where to find adminhtml controllers for this module. --> <module>SmashingMagazine_BrandDirectory_Adminhtml</module> <!-- This is the term used in the actual URL. --> <frontName>brand-directory-admin</frontName> </args> </smashingmagazine_branddirectory_admin> </routers> </admin> </config>
adminhtml.xml
將菜單項添加到Magento的管理面板非常簡單。 我們只需要創建一個adminhtml.xml
文件,確定哪些項目應該出現在哪里,他們應該導致單擊時。 編輯etc/adminhtml.xml
與此:
<?xml version="1.0"?> <config> <!-- We are defining a new menu item for the admin panel. --> <menu> <!-- First, create a top-level menu item, which will appear alongside CMS --> <smashingmagazine_branddirectory translate="title" module="smashingmagazine_branddirectory"> <title>Brand Directory</title> <sort_order>75</sort_order> <depends> <module>SmashingMagazine_BrandDirectory</module> </depends> <!-- Under this top-level menu, create a child menu item. --> <children> <brand translate="title" module="smashingmagazine_branddirectory"> <title>Manage Brands</title> <sort_order>10</sort_order> <!-- When the menu is clicked, take the user here. --> <action>smashingmagazine_branddirectory_admin/brand</action> </brand> </children> </smashingmagazine_branddirectory> </menu> <!-- Define ACL for access to these menu items. --> <acl> <resources> <admin> <children> <smashingmagazine_branddirectory translate="title" module="smashingmagazine_branddirectory"> <title>Brand Directory</title> <sort_order>75</sort_order> <children> <brand translate="title" module="smashingmagazine_branddirectory"> <title>Manage Brands</title> </brand> </children> </smashingmagazine_branddirectory> </children> </admin> </resources> </acl> </config>
顯示品牌在前端
我們已經達到了這個教程對如何創建從管理面板可管理的實體結尾。 現在,你應該能夠創建,更新和刪除的品牌和擁有這些反映在數據庫中修改。 你有一個全功能的品牌實體,但它實際上并沒有做任何事情。 接下來的步驟是在你的Magento代碼的其余部分集成這個新的實體。
而不是繼續絮叨如何做到這一點,我已經包含在附帶的源代碼一個額外的本地模塊,名為“BrandExample”,其中包含了如何實現這樣的例子。
經檢查附件,你會發現我一直本補充前端的例子作為一個單獨的本地模塊,以便它不能與上面覆蓋了管理面板管理部分相混淆。 一旦你比較熟悉,然后通過各種手段,捆綁兩個模塊為一體,如果你的愿望。