后台菜单显示点击后404,如果adminhtml.xml配置正确,那是config.xml的问题
Magento Grid关联了多表后,表与表之间有相同字段出现。在后台点查询时出现报错解决用filter_index
$this->addColumn('name', array(
'header' => '返利商家',
'align' => 'right',
'width' => '50px',
'index' => 'vname',
'filter_index' =>'v.name',
));
$this->addColumn('type', array(
'header' => '返利规则名',
'align' => 'right',
'width' => '50px',
'index' => 'name',
'filter_index' =>'main_table.name',
));
1.在后台管理界面加入菜单
1.1添加新菜单
<?xml version="1.0"?>
<config>
<menu>
<!--子菜单标识符-->
<dcatalog translate="title">
<title>推荐位管理</title>
<sort_order>110</sort_order>
<children>
<recommend_product translate="title">
<title>商品推荐</title>
<action>adminhtml/recommend_product</action>
</recommend_product>
<recommend_jifen translate="title">
<title>积分商户推荐</title>
<action>adminhtml/recommend_jifen</action>
</recommend_jifen>
<recommend_image translate="title">
<title>图片推荐</title>
<action>adminhtml/recommend_image</action>
</recommend_image>
</children>
</dcatalog>
</menu>
<acl>
<resources>
<admin>
<children>
<dcatalog translate="title">
<title>推荐位管理</title>
<children>
<recommend_product translate="title">
<title>商品推荐</title>
<sort_order>0</sort_order>
</recommend_product>
<recommend_jifen translate="title">
<title>商品推荐</title>
<sort_order>0</sort_order>
</recommend_jifen>
<recommend_image translate="title">
<title>图片推荐</title>
<sort_order>0</sort_order>
</recommend_image>
</children>
</dcatalog>
</children>
</admin>
</resources>
</acl>
</config>
1.2在已有菜单下添加:在模块的Glamour/CustomerMessage/etc目录下增加adminhtml.xml配置文件,用于加入自定义的菜单项。文件内容如下:
<?xml version="1.0"?>
<config>
<menu>
<!-- 父菜单项标识,此处是在标题为Customers的菜单下加入子菜单-->
<!-- Magento一级管理菜单标识和显示标题-->
<!--
dashboard =>Dashboard
catalog=>Catalog
sales=>Sales
customer=>Customers
newsletter=>Newsletter
cms=>CMS
report=>Reports
-->
<customer>
<children>
<!--子菜单标识符-->
<customermessage translate="title">
<title>Customer Message</title>
<!--点击菜单时执行的动作,此处将执行controller/adminhtml目录下的messageController默认的action-->
<action>adminhtml/message</action>
<sort_order>120</sort_order>
</customermessage >
</children>
</customer>
</menu>
<!--加入权限列表-->
<acl>
<resources>
<admin>
<children>
<customer>
<children>
<customermessage translate="title">
<title>Customer Message</title>
</customermessage>
</children>
</customer>
</children>
</admin>
</resources>
</acl>
</config>
可以在后台,系统-》权限-》角色-》角色资源-》自定义 查看
2开发后台Controller
在模块的controllers目录下创建Adminhtml目录,新建一个Controller类。
<?php
class Glamour_CustomerMessage_Adminhtml_MessageController extends Mage_Adminhtml_Controller_Action {
public function indexAction() {
$this->loadLayout()
->_setActiveMenu('customer')
->_addBreadcrumb('Customer Message', 'Customer Message')
->renderLayout();
}
protected function _initData() {
$id = $this->getRequest()->getParam('id', 0);
$model = Mage::getModel('news/news');
if ($id > 0) {
$model = $model->load($id);
}
Mage::register('form_data', $model);
return $formdata;
}
public function editAction() { //页面回显
if (!$formdata = $this->_initData()) {
return;
}
try{
$this->loadLayout();
$this->_setActiveMenu('customer/message');
$this->_addContent($this->getLayout()->createBlock('news/adminhtml_news_edit'))
->_addLeft($this->getLayout()->createBlock('news/adminhtml_news_edit_tabs'));
$this->renderLayout();
} catch(Exception $e) {
Mage::getSingleton('adminhtml/session')->addError('记录不存在');
$this->_redirect('*/*/');
}
}
public function newAction() {
$this->_forward('edit');
}
public function deleteAction() {
$id = $this->getRequest()->getParam('id');
if ($id > 0) {
try {
$this->doDelete($id);
Mage::getSingleton('adminhtml/session')->addSuccess('删除成功');
$this->_redirect('*/*/');
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError('删除失败');
$this->_redirect('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
}
}
$this->_redirect('*/*/');
}
public function saveAction() {
if ($data = $this->getRequest()->getPost()) {
try {
$model = Mage::getModel('news/news');
$model->setData($data);
$model->save();
Mage::getSingleton('adminhtml/session')->addSuccess('保存成功');
// check if 'Save and Continue'
if ($this->getRequest()->getParam('back')=='edit') {
$this->_redirect('*/*/edit', array('id' => $model->getId()));
return;
}
$this->_redirect('*/*/');
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
$this->_redirect('*/*/edit', array('id' => $model->getId()));
return;
}
}
$this->_redirect('*/*/');
}
public function massDeleteAction() {
$ids = $this->getRequest()->getParam('news');
if (!empty($ids)) {
try {
$this->doDelete($ids);
Mage::getSingleton('adminhtml/session')->addSuccess(sprintf('删除 %d条成功', count($ids)));
} catch (Exception $e) {
Mage::getSingleton('adminhtml/session')->addError('删除失败');
}
}
$this->_redirect('*/*/');
}
private function doDelete($id) {
if (is_array($id)) {
foreach ($id as $id) {
$this->doDelete($id);
}
} else {
Mage::getModel('news/news')->load($id)->delete();
}
}
public function exportCsvAction() {
$fileName = 'fanli.csv';
$grid = $this->getLayout()->createBlock('rebates/adminhtml_order_grid');
$this->_prepareDownloadResponse($fileName, strip_tags($grid->getCsv())); //string 方式
// $this->_prepareDownloadResponse($fileName, $grid->getCsvFile($fileName)); //读export/xml方式导出,先写文件再读文件,性能不好
}
}
后台的Controller类继承自Mage_Adminhtml_Controller_Action,在etc/config.xml加入:
</frontend>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<customermessage before="Mage_Adminhtml">Glamour_CustomerMessage_Adminhtml</customermessage>
</modules>
</args>
</adminhtml>
</routers>
</admin>
这样就可以使用和Magento自带的后台模块类似的url .../index.php/admin/message/来访问自定义模块的后台controller,也可以实现rewrite后台controller。
3开发后台Block
在app\code\local\Voodoo\News\Block\Adminhtml下,建立News.php文件:列表显示
class Voodoo_News_Block_Adminhtml_News extends Mage_Adminhtml_Block_Widget_Grid_Container
{
public function __construct()
{
$this->_controller = 'adminhtml_news'; //block路径
$this->_blockGroup = 'news';//module name
$this->_headerText = '管理';
$this->_addButtonLabel = '添加';
parent::__construct();
//$this->_removeButton('back');//reset save add
}
}
同样目录下继续建立Grid.php文件:
<?php
class Voodoo_News_Block_Adminhtml_News_Grid extends Mage_Adminhtml_Block_Widget_Grid {
public function __construct() {
parent::__construct();
$this->setId('newsGrid');
$this->setDefaultSort('news_id');
$this->setDefaultDir('ASC');
$this->setSaveParametersInSession(true);
}
protected function _prepareCollection() {
$collection = Mage::getModel('news/news')->getCollection();
$this->setCollection($collection);
return parent::_prepareCollection();
}
protected function _prepareColumns() {
$this->addColumn('news_id', array(
'header' => 'ID',
'align' => 'right',
'width' => '50px',
'index' => 'news_id',
));
$this->addColumn('action', array(
'header' => '操作',
'width' => '100',
'type' => 'action',
'getter' => 'getId',
'actions' => array(
array(
'caption' => '修改',
'url' => array('base' => '*/*/edit'),
'field' => 'id'
)
),
'filter' => false,
'sortable' => false,
'index' => 'stores',
'is_system' => true,
));
$this->addExportType('*/*/exportCsv', 'CSV');
return parent::_prepareColumns();
}
protected function _prepareMassaction() {
$this->setMassactionIdField('news_id'); //checkbox value 需要_prepareMassactionColumn
$this->getMassactionBlock()->setFormFieldName('news'); //checkbox name
$this->getMassactionBlock()->addItem('delete', array(
'label' => '删除',
'url' => $this->getUrl('*/*/massDelete'),
'confirm' => '确认删除?'
));
return $this;
}
protected function _prepareMassactionColumn() {
$columnId = 'massaction';
$massactionColumn = $this->getLayout()->createBlock('adminhtml/widget_grid_column')
->setData(array(
'index' => $this->getMassactionIdField(),
'type' => 'massaction',
'name' => $this->getMassactionBlock()->getFormFieldName(),
'align' => 'center',
'disabled_values' => array(1, 3), // checkbox disabled values
'is_system' => true, //系统自带导出csv/excel中不显示
'use_index' =>true // 关联setMassactionIdField
));
if ($this->getNoFilterMassactionColumn()) {
$massactionColumn->setData('filter', false);
}
$massactionColumn->setSelected($this->getMassactionBlock()->getSelected())
->setGrid($this)
->setId($columnId);
$oldColumns = $this->_columns;
$this->_columns = array();
$this->_columns[$columnId] = $massactionColumn;
$this->_columns = array_merge($this->_columns, $oldColumns);
return $this;
}
public function getRowUrl($row) //点击tr进入edit,去掉后显示#
{
return $this->getUrl('*/*/edit', array('id' => $row->getId()));
}
}
app\code\local\Voodoo\News\Block\Adminhtml\News中建立Edit.php文件:
<?php
class Voodoo_News_Block_Adminhtml_News_Edit extends Mage_Adminhtml_Block_Widget_Form_Container {
//protected $_mode = 'edit';//form.php目录名
public function __construct() {
parent::__construct();
$this->_objectId = 'id';
$this->_blockGroup = 'news';
$this->_controller = 'adminhtml_news';
$this->_updateButton('save', 'label', '保存');
$this->_updateButton('delete', 'label', '删除');
$this->_addButton('saveandcontinue', array(
'label' => Mage::helper('adminhtml')->__('Save and Continue Edit'),
'onclick' => 'saveAndContinueEdit()',
'class' => 'save',
), -100);
$this->_formScripts[] =<<<JS
function toggleEditor() {
if (tinyMCE.getInstanceById('block_content') == null) {
tinyMCE.execCommand('mceAddControl', false, 'block_content');
} else {
tinyMCE.execCommand('mceRemoveControl', false, 'block_content');
}
}
function saveAndContinueEdit(){
editForm.submit(\$('edit_form').action+'back/edit/');
}
JS;
}
public function getHeaderText() {
if (Mage::registry('form_data') && Mage::registry('form_data')->getId()) {
return ("Edit Item '%s'", $this->htmlEscape(Mage::registry('news_data')->getTitle());
} else {
return 'Add Item';
}
}
public function _prepareLayout() { //add js css 需要添加此方法,其他可以删除
$this->getLayout()->getBlock('head')
->addJs('extjs/ext-tree.js')
->addJs('extjs/ext-tree-checkbox.js')
->addItem('js_css', 'extjs/resources/css/ext-all.css');
return parent::_prepareLayout();
}
}
app\code\local\Voodoo\News\Block\Adminhtml\News\Edit下创建Form.php和Tabs.php:
<?php
class Voodoo_News_Block_Adminhtml_News_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
{
protected function _prepareForm()
{
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => $this->getUrl('*/*/save', array('id' =>$this->getRequest()->getParam('id'))),
'method' => 'post',
'enctype' => 'multipart/form-data'
));
$form->setUseContainer(true);
$this->setForm($form);
return parent::_prepareForm();
}
}
下面的是tab选项卡带form,可以不要。将$fieldset的内容放到上面去
<?php
class Voodoo_News_Block_Adminhtml_News_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
{
public function __construct()
{
parent::__construct();
$this->setId('news_tabs');
$this->setDestElementId('edit_form');
$this->setTitle('News Information');
}
protected function _beforeToHtml()
{
$this->addTab('form_section', array(
'label' => 'News Information',
'title' => 'News Information',
'content' => $this->getLayout()->createBlock('news/adminhtml_news_edit_tab_form')->toHtml(),
));
return parent::_beforeToHtml();
}
}
最后在app\code\local\Voodoo\News\Block\Adminhtml\News\Edit\Tab下建立Form.php
<?php
class Voodoo_News_Block_Adminhtml_News_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form {
/*public function __construct() {
parent::__construct();
$this->setTemplate('news/news/tab/form.phtml'); //用setTemplate时不需要用_prepareForm
}*/
protected function _prepareForm() {
$form = new Varien_Data_Form();
$fieldset = $form->addFieldset('news_form', array('legend' => 'Item information'));
$fieldset->addField('title', 'text', array('label' => 'Title', 'class' => 'required-entry', 'required' => true, 'name' => 'title'));
$model = Mage::registry('form_data');
$form->setValues($model->getData());
$this->setForm($form);
return parent::_prepareForm();
}
}
这样就完成了模块的创建。block是Magento的重要部分,这里我们创建了7个新闻模块功能,我们写了一些方法,并且将数据传递到布局。
这样我们便完成了新闻模块的开发,这是后台截图:
相信留心的人已经在看Mage_Widget模块了,对的就是从这里学到的。像这种例子还可以参考Mage_Centinel。目前我只能向大家讲些框架的理论,具体里面的业务逻辑,还要靠自己多看、多理解。学习Magento绝对是个体力活,希望大家能够少走些弯路。