如何为品牌网站创建一个可管理的Magento实体店

在本教程中,我们将创建在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的页面可能需要几分钟的时间更长的时间来加载,而我们的安装脚本的内容是运行(即在新的数据库表被创建),然后页面会不断加载正常。 您现在有两个任务要执行,检查,一切都已经如预期:

  1. 保证Magento的知道你的模块,而模块是通过去激活System → Configuration → Advanced → Advanced
  2. 通过任一终端或类似PHPMyAdmin的东西进入你的数据库,看看是否Magento的创造了一个新的表, smashingmagazine_branddirectory_brand

如果所有的不顺利…

如果一切不顺利,那么它也可能看起来像什么都没有发生,只是这一次没有什么事情发生了! 这样做的原因可能是错别字在config.xml ,严重命名文件夹或文件(注意大小写敏感)或别的东西。 经过前面的步骤,仔细检查,一切都是理所应当的。

在另一方面,你可能会看到一个错误消息 – 也许是“PHP的致命错误”或报告页面,根据错误的严重程度。 用你的调试技巧,以找出问题并纠正它,再仔细检查在本教程前面的所有步骤。

“出错。 我如何再试一次吗?“

从头再试一次,你可以执行以下操作 – 不是所有的可能需要,根据Magento的多远,得到了什么事情之前。 您将需要直接访问你的数据库,因为这无法通过Magento的执行:

  1. core_resource表,删除单列smashingmagazine_branddirectory_setup
  2. 删除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”,其中包含了如何实现这样的例子。

经检查附件,你会发现我一直本补充前端的例子作为一个单独的本地模块,以便它不能与上面覆盖了管理面板管理部分相混淆。 一旦你比较熟悉,然后通过各种手段,捆绑两个模块为一体,如果你的愿望。

Comments are closed.