创建一个读取目录的块来展示块创建过程。块创建跟建立一个模块很类似。
这里报名为Vfeelit,模块名为Catcus,块类名为Vfeelit_Catcus_Block_Menu:
app/etc/modules/Vfeelit_Helloworld.xml app/code/local/Vfeelit/Catcus/etc/config.xml app/code/local/Vfeelit/Catcus/block/Menu.php app/design/frontend/default/default/layout/catcus.xml app/design/frontend/default/default/template/catcus/menu.phtml
app/etc/modules/Vfeelit_Helloworld.xml
<?xml version="1.0"?> <config> <modules> <Vfeelit_Catcus> <active>true</active> <codePool>local</codePool> </Vfeelit_Catcus> </modules> </config>
app/code/local/Vfeelit/Catcus/etc/config.xml
<?xml version="1.0"?> <config> <modules> <Vfeelit_Catcus> <version>1.0.0.0</version> </Vfeelit_Catcus> </modules> <frontend> <layout> <updates> <catcus> <file>catcus.xml</file> </catcus> </updates> </layout> </frontend> <global> <blocks> <catcus> <class>Vfeelit_Catcus_Block</class> </catcus> </blocks> </global> </config>
注意这个配置文件,必须给出布局对应的文件,否则找不到。还有前台必须给出块的类。
app/code/local/Vfeelit/Catcus/block/Menu.php
<?php class Vfeelit_Catcus_Block_Menu extends Mage_Core_Block_Template { /** * Top menu data tree * * @var Varien_Data_Tree_Node */ protected $_menu; /** * Init top menu tree structure */ public function _construct() { $this->_menu = new Varien_Data_Tree_Node(array(), 'root', new Varien_Data_Tree()); } public function addCategoriesToMenu($categories, $parentCategoryNode) { foreach ($categories as $category) { if (!$category->getIsActive()) { continue; } $nodeId = 'category-node-' . $category->getId(); $tree = $parentCategoryNode->getTree(); $categoryData = array( 'name' => $category->getName(), 'id' => $nodeId, 'url' => Mage::helper('catalog/category')->getCategoryUrl($category), 'is_active' => $this->_isActiveMenuCategory($category) ); $categoryNode = new Varien_Data_Tree_Node($categoryData, 'id', $tree, $parentCategoryNode); $parentCategoryNode->addChild($categoryNode); if (Mage::helper('catalog/category_flat')->isEnabled()) { $subcategories = (array)$category->getChildrenNodes(); } else { $subcategories = $category->getChildren(); } $this->addCategoriesToMenu($subcategories, $categoryNode); } } protected function _isActiveMenuCategory($category) { $catalogLayer = Mage::getSingleton('catalog/layer'); if (!$catalogLayer) { return false; } $currentCategory = $catalogLayer->getCurrentCategory(); if (!$currentCategory) { return false; } $categoryPathIds = explode(',', $currentCategory->getPathInStore()); return in_array($category->getId(), $categoryPathIds); } /** * Get top menu html * * @param string $outermostClass * @param string $childrenWrapClass * @return string */ public function getHtml($cid ='', $recursionLevel = 0, $outermostClass = '', $childrenWrapClass = '') { $cid = (int)$cid; $recursionLevel = (int)$recursionLevel; $category = Mage::getModel('catalog/category'); if (!$category->checkId($cid)) { return ''; } $categories = $category->getCategories($cid, $recursionLevel); $this->addCategoriesToMenu($categories,$this->_menu); $this->_menu->setOutermostClass($outermostClass);//level-top $this->_menu->_data['OutermostClass'] = 'level-top' $this->_menu->setChildrenWrapClass($childrenWrapClass); //$this->_menu->_data['ChildrenWrapClass'] = '' $html = $this->_getHtml($this->_menu, $childrenWrapClass); return $html; } /** * Recursively generates top menu html from data that is specified in $menuTree * * @param Varien_Data_Tree_Node $menuTree * @param string $childrenWrapClass * @return string */ public function _getHtml(Varien_Data_Tree_Node $menuTree, $childrenWrapClass) { $html = ''; $children = $menuTree->getChildren(); // $this->_menu Varien_Data_Tree_Node_Collection $parentLevel = $menuTree->getLevel(); //root -> null $this->_menu->_data['level'] = null $childLevel = is_null($parentLevel) ? 0 : $parentLevel + 1; $counter = 1; $childrenCount = $children->count(); //nodes total $parentPositionClass = $menuTree->getPositionClass(); //no set $itemPositionClassPrefix = $parentPositionClass ? $parentPositionClass . '-' : 'nav-'; //can get 'nav-' foreach ($children as $child) { $child->setLevel($childLevel); $child->setIsFirst($counter == 1); $child->setIsLast($counter == $childrenCount); $child->setPositionClass($itemPositionClassPrefix . $counter); $outermostClassCode = ''; $outermostClass = $menuTree->getOutermostClass(); if ($childLevel == 0 && $outermostClass) { $outermostClassCode = ' class="' . $outermostClass . '" '; $child->setClass($outermostClass); } $html .= '<li ' . $this->_getRenderedMenuItemAttributes($child) . '>'; $html .= '<a href="' . $child->getUrl() . '" ' . $outermostClassCode . '><span>' . $this->escapeHtml($child->getName()) . '</span></a>'; if ($child->hasChildren()) { if (!empty($childrenWrapClass)) { $html .= '<div class="' . $childrenWrapClass . '">'; } $html .= '<ul class="level' . $childLevel . '">'; $html .= $this->_getHtml($child, $childrenWrapClass); $html .= '</ul>'; if (!empty($childrenWrapClass)) { $html .= '</div>'; } } $html .= '</li>'; $counter++; } return $html; } /** * Generates string with all attributes that should be present in menu item element * * @param Varien_Data_Tree_Node $item * @return string */ protected function _getRenderedMenuItemAttributes(Varien_Data_Tree_Node $item) { $html = ''; $attributes = $this->_getMenuItemAttributes($item); foreach ($attributes as $attributeName => $attributeValue) { $html .= ' ' . $attributeName . '="' . str_replace('"', '\"', $attributeValue) . '"'; } return $html; } /** * Returns array of menu item's attributes * * @param Varien_Data_Tree_Node $item * @return array */ protected function _getMenuItemAttributes(Varien_Data_Tree_Node $item) { $menuItemClasses = $this->_getMenuItemClasses($item); $attributes = array( 'class' => implode(' ', $menuItemClasses) ); return $attributes; } /** * Returns array of menu item's classes * * @param Varien_Data_Tree_Node $item * @return array */ protected function _getMenuItemClasses(Varien_Data_Tree_Node $item) { $classes = array(); $classes[] = 'level' . $item->getLevel(); $classes[] = $item->getPositionClass(); if ($item->getIsFirst()) { $classes[] = 'first'; } if ($item->getIsActive()) { $classes[] = 'active'; } if ($item->getIsLast()) { $classes[] = 'last'; } if ($item->getClass()) { $classes[] = $item->getClass(); } if ($item->hasChildren()) { $classes[] = 'parent'; } return $classes; } }
用这个块类来输出任意目录的子目录。
app/design/frontend/default/default/layout/catcus.xml
<layout version="0.1.0"> <default> <reference name="top.container"> <block type="catcus/menu" name="catcus.menu" template="catcus/menu.phtml"/> </reference> </default> </layout>
把这个块放在top.container中输出。
app/design/frontend/default/default/template/catcus/menu.phtml
<?php echo $this->getHtml(3);
直接输出内容。
建立一个自定义的块基本就设置这些文件。块的类是应该继承自Mage_Core_Block_Template的。模块的配置文件中必须指定块的类前缀和使用的布局文件。
永久链接:http://blog.ifeeline.com/531.html
原创文章,转载务必保持出处。