Magento モジュール (Web および People カスタム メニュー) をインストールして、Web サイトのナビゲーション用のメガ メニュー (メガ ナビゲーション) 機能を提供しました。一部の列の下にこの巨大なスペースがないように、正当化を修正しようとしています。スクリーンショットでわかるように、左側の列には、その下にサブカテゴリを追加する余地があります。
CSS の変更と、印刷された html の構造の変更を試みました。列の div に適用されるロジックを変更する必要があるようですが、理解できないようです。
以下は、「// --- 2.小さな列を次の --- とマージする」の下で何らかの形で変更することになっていると思われる関数です。
private function _explodeByColumns($target, $num)
{
if ((int)Mage::getStoreConfig('custom_menu/columns/divided_horizontally')) {
$target = self::_explodeArrayByColumnsHorisontal($target, $num);
} else {
$target = self::_explodeArrayByColumnsVertical($target, $num);
}
#return $target;
if ((int)Mage::getStoreConfig('custom_menu/columns/integrate') && count($target))
{
// --- combine consistently numerically small column ---
// --- 1. calc length of each column ---
$max = 0; $columnsLength = array();
foreach ($target as $key => $child)
{
$count = 0;
$this->_countChild($child, 1, $count);
if ($max < $count) $max = $count;
$columnsLength[$key] = $count;
}
// --- 2. merge small columns with next ---
$xColumns = array(); $column = array(); $cnt = 0;
$xColumnsLength = array(); $k = 0;
foreach ($columnsLength as $key => $count)
{
$cnt+= $count;
if ($cnt > $max && count($column))
{
$xColumns[$k] = $column;
$xColumnsLength[$k] = $cnt - $count;
$k++; $column = array(); $cnt = $count;
}
$column = array_merge($column, $target[$key]);
}
$xColumns[$k] = $column;
$xColumnsLength[$k] = $cnt - $count;
// --- 3. integrate columns of one element ---
$target = $xColumns; $xColumns = array(); $nextKey = -1;
if ($max > 1 && count($target) > 1)
{
foreach($target as $key => $column)
{
if ($key == $nextKey) continue;
if ($xColumnsLength[$key] == 1)
{
// --- merge with next column ---
$nextKey = $key + 1;
if (isset($target[$nextKey]) && count($target[$nextKey]))
{
$xColumns[] = array_merge($column, $target[$nextKey]);
continue;
}
}
$xColumns[] = $column;
}
$target = $xColumns;
}
}
$_rtl = Mage::getStoreConfigFlag('custom_menu/general/rtl');
if ($_rtl) {
$target = array_reverse($target);
}
return $target;
}
スクリプト全体:
<?php
class WP_CustomMenu_Block_Navigation extends Mage_Catalog_Block_Navigation
{
const CUSTOM_BLOCK_TEMPLATE = "wp_custom_menu_%d";
private $_productsCount = null;
public function showHomeLink()
{
return Mage::getStoreConfig('custom_menu/general/show_home_link');
}
public function drawCustomMenuItem($category, $level = 0, $last = false)
{
if (!$category->getIsActive()) return '';
$html = array();
$id = $category->getId();
// --- Static Block ---
$blockId = sprintf(self::CUSTOM_BLOCK_TEMPLATE, $id); // --- static block key
#Mage::log($blockId);
$collection = Mage::getModel('cms/block')->getCollection()
->addFieldToFilter('identifier', array(array('like' => $blockId . '_w%'), array('eq' => $blockId)))
->addFieldToFilter('is_active', 1);
$blockId = $collection->getFirstItem()->getIdentifier();
#Mage::log($blockId);
$blockHtml = $this->getLayout()->createBlock('cms/block')->setBlockId($blockId)->toHtml();
// --- Sub Categories ---
$activeChildren = $this->_getActiveChildren($category, $level);
// --- class for active category ---
$active = ''; if ($this->isCategoryActive($category)) $active = ' act';
// --- Popup functions for show ---
$drawPopup = ($blockHtml || count($activeChildren));
if ($drawPopup) {
$html[] = '<div id="menu' . $id . '" class="menu' . $active . '" onclick="wpShowMenuPopup(this, event, \'popup' . $id . '\');">';
//$html[] = '<div id="menu' . $id . '" class="menu' . $active . '" onclick="wpShowMenuPopup(this, event, \'popup' . $id . '\');" onmouseout="wpHideMenuPopup(this, event, \'popup' . $id . '\', \'menu' . $id . '\')">';
} else {
$html[] = '<div id="menu' . $id . '" class="menu' . $active . '">';
}
// --- Top Menu Item ---
$html[] = '<div class="parentMenu">';
if ($level == 0 && $drawPopup) {
$html[] = '<a href="javascript:void(0);" rel="'.$this->getCategoryUrl($category).'">';
} else {
$html[] = '<a href="'.$this->getCategoryUrl($category).'">';
}
$name = $this->escapeHtml($category->getName());
if (Mage::getStoreConfig('custom_menu/general/non_breaking_space')) {
$name = str_replace(' ', ' ', $name);
}
$html[] = '<span>' . $name . '</span>';
$html[] = '</a>';
$html[] = '</div>';
$html[] = '</div>';
// --- Add Popup block (hidden) ---
if ($drawPopup) {
// --- Popup function for hide ---
$html[] = '<div id="popup' . $id . '" class="wp-custom-menu-popup" onclick="wpPopupOver(this, event, \'popup' . $id . '\', \'menu' . $id . '\')">';
//$html[] = '<div id="popup' . $id . '" class="wp-custom-menu-popup" onmouseout="wpHideMenuPopup(this, event, \'popup' . $id . '\', \'menu' . $id . '\')" onmouseover="wpPopupOver(this, event, \'popup' . $id . '\', \'menu' . $id . '\')">';
// --- draw Sub Categories ---
//CAITLIN added line below
$html[] = '<div class="displayAllCategories"><p><a href="'.$this->getCategoryUrl($category).'">All ' . $this->escapeHtml($category->getName()) . '</a></p></div>';
if (count($activeChildren)) {
$html[] = '<div class="block1">';
$html[] = $this->drawColumns($activeChildren);
$html[] = '<div class="clearBoth"></div>';
$html[] = '</div>';
}
// --- draw Custom User Block ---
if ($blockHtml) {
$html[] = '<div id="' . $blockId . '" class="block2">';
$html[] = $blockHtml;
$html[] = '</div>';
}
$html[] = '</div>';
}
$html = implode("\n", $html);
return $html;
}
public function drawMenuItem($children, $level = 1)
{
$html = '<div class="itemMenu level' . $level . '">';
$keyCurrent = $this->getCurrentCategory()->getId();
foreach ($children as $child)
{
if (is_object($child) && $child->getIsActive())
{
// --- class for active category ---
$active = '';
if ($this->isCategoryActive($child))
{
$active = ' actParent';
if ($child->getId() == $keyCurrent) $active = ' act';
}
// --- format category name ---
$name = $this->escapeHtml($child->getName());
if (Mage::getStoreConfig('custom_menu/general/non_breaking_space'))
$name = str_replace(' ', ' ', $name);
$html.= '<a class="itemMenuName level' . $level . $active . '" href="' . $this->getCategoryUrl($child) . '"><span>' . $name . '</span></a>';
$activeChildren = $this->_getActiveChildren($child, $level);
if (count($activeChildren) > 0)
{
$html.= '<div class="itemSubMenu level' . $level . '">';
$html.= $this->drawMenuItem($activeChildren, $level + 1);
$html.= '</div>';
}
}
}
$html.= '</div>';
return $html;
}
public function drawColumns($children)
{
$html = '';
// --- explode by columns ---
$columns = (int)Mage::getStoreConfig('custom_menu/columns/count');
if ($columns < 1) $columns = 1;
$chunks = $this->_explodeByColumns($children, $columns);
// --- draw columns ---
$lastColumnNumber = count($chunks);
$i = 1;
foreach ($chunks as $key => $value)
{
if (!count($value)) continue;
$class = '';
if ($i == 1) $class.= ' first';
if ($i == $lastColumnNumber) $class.= ' last';
if ($i % 2) $class.= ' odd'; else $class.= ' even';
//$html.= '<div class="column' . $class . '">';
$html.= $this->drawMenuItem($value, 1);
//$html.= '</div>';
$i++;
}
return $html;
}
protected function _getActiveChildren($parent, $level)
{
$activeChildren = array();
// --- check level ---
$maxLevel = (int)Mage::getStoreConfig('custom_menu/general/max_level');
if ($maxLevel > 0)
{
if ($level >= ($maxLevel - 1)) return $activeChildren;
}
// --- / check level ---
if (Mage::helper('catalog/category_flat')->isEnabled())
{
$children = $parent->getChildrenNodes();
$childrenCount = count($children);
}
else
{
$children = $parent->getChildren();
$childrenCount = $children->count();
}
$hasChildren = $children && $childrenCount;
if ($hasChildren)
{
foreach ($children as $child)
{
if ($this->_isCategoryDisplayed($child))
{
array_push($activeChildren, $child);
}
}
}
return $activeChildren;
}
private function _isCategoryDisplayed(&$child)
{
if (!$child->getIsActive()) return false;
// === check products count ===
// --- get collection info ---
if (!Mage::getStoreConfig('custom_menu/general/display_empty_categories'))
{
$data = $this->_getProductsCountData();
// --- check by id ---
$id = $child->getId();
#Mage::log($id); Mage::log($data);
if (!isset($data[$id]) || !$data[$id]['product_count']) return false;
}
// === / check products count ===
return true;
}
private function _getProductsCountData()
{
if (is_null($this->_productsCount))
{
$collection = Mage::getModel('catalog/category')->getCollection();
$storeId = Mage::app()->getStore()->getId();
/* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */
$collection->addAttributeToSelect('name')
->addAttributeToSelect('is_active')
->setProductStoreId($storeId)
->setLoadProductCount(true)
->setStoreId($storeId);
$productsCount = array();
foreach($collection as $cat)
{
$productsCount[$cat->getId()] = array(
'name' => $cat->getName(),
'product_count' => $cat->getProductCount(),
);
}
#Mage::log($productsCount);
$this->_productsCount = $productsCount;
}
return $this->_productsCount;
}
private function _explodeByColumns($target, $num)
{
if ((int)Mage::getStoreConfig('custom_menu/columns/divided_horizontally')) {
$target = self::_explodeArrayByColumnsHorisontal($target, $num);
} else {
$target = self::_explodeArrayByColumnsVertical($target, $num);
}
#return $target;
if ((int)Mage::getStoreConfig('custom_menu/columns/integrate') && count($target))
{
// --- combine consistently numerically small column ---
// --- 1. calc length of each column ---
$max = 0; $columnsLength = array();
foreach ($target as $key => $child)
{
$count = 0;
$this->_countChild($child, 1, $count);
if ($max < $count) $max = $count;
$columnsLength[$key] = $count;
}
// --- 2. merge small columns with next ---
$xColumns = array(); $column = array(); $cnt = 0;
$xColumnsLength = array(); $k = 0;
foreach ($columnsLength as $key => $count)
{
$cnt+= $count;
if ($cnt > $max && count($column))
{
$xColumns[$k] = $column;
$xColumnsLength[$k] = $cnt - $count;
$k++; $column = array(); $cnt = $count;
}
$column = array_merge($column, $target[$key]);
}
$xColumns[$k] = $column;
$xColumnsLength[$k] = $cnt - $count;
// --- 3. integrate columns of one element ---
$target = $xColumns; $xColumns = array(); $nextKey = -1;
if ($max > 1 && count($target) > 1)
{
foreach($target as $key => $column)
{
if ($key == $nextKey) continue;
if ($xColumnsLength[$key] == 1)
{
// --- merge with next column ---
$nextKey = $key + 1;
if (isset($target[$nextKey]) && count($target[$nextKey]))
{
$xColumns[] = array_merge($column, $target[$nextKey]);
continue;
}
}
$xColumns[] = $column;
}
$target = $xColumns;
}
}
$_rtl = Mage::getStoreConfigFlag('custom_menu/general/rtl');
if ($_rtl) {
$target = array_reverse($target);
}
return $target;
}
private function _countChild($children, $level, &$count)
{
foreach ($children as $child)
{
if ($child->getIsActive())
{
$count++; $activeChildren = $this->_getActiveChildren($child, $level);
if (count($activeChildren) > 0) $this->_countChild($activeChildren, $level + 1, $count);
}
}
}
private static function _explodeArrayByColumnsHorisontal($list, $num)
{
if ($num <= 0) return array($list);
$partition = array();
$partition = array_pad($partition, $num, array());
$i = 0;
foreach ($list as $key => $value) {
$partition[$i][$key] = $value;
if (++$i == $num) $i = 0;
}
return $partition;
}
private static function _explodeArrayByColumnsVertical($list, $num)
{
if ($num <= 0) return array($list);
$listlen = count($list);
$partlen = floor($listlen / $num);
$partrem = $listlen % $num;
$partition = array();
$mark = 0;
for ($column = 0; $column < $num; $column++) {
$incr = ($column < $partrem) ? $partlen + 1 : $partlen;
$partition[$column] = array_slice($list, $mark, $incr);
$mark += $incr;
}
return $partition;
}
}
1 つのメニューの HTML 出力:
<div class="block1">
<div class="column first odd"><div class="itemMenu level1"><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/baseball.html"><span>Baseball</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/baseball/baseball-bases.html"><span>Baseball Bases</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/baseball/baseballs.html"><span>Baseballs</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/baseball/baseball-gloves.html"><span>Baseball Gloves</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/basketball.html"><span>Basketball</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/basketball/basketball-accessories.html"><span>Basketball Accessories</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/basketball/basketballs.html"><span>Basketballs</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/field-ice-hockey.html"><span>Field & Ice Hockey</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/field-ice-hockey/hockey-balls.html"><span>Hockey Balls</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/field-ice-hockey/hockey-goals.html"><span>Hockey Goals</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/field-ice-hockey/hockey-pucks.html"><span>Hockey Pucks</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/field-ice-hockey/hockey-sticks.html"><span>Hockey Sticks</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/first-aid.html"><span>First Aid</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/first-aid/heart-rate-monitors.html"><span>Heart Rate Monitors</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/first-aid/athletic-tape.html"><span>Athletic Tape</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/fitness.html"><span>Fitness</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/fitness/exercise-training-bands.html"><span>Exercise Training Bands</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/football.html"><span>Football</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/football/football-accessories.html"><span>Football Accessories</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/football/footballs.html"><span>Footballs</span></a></div></div></div></div><div class="column even"><div class="itemMenu level1"><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/golf.html"><span>Golf</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/gymnastics.html"><span>Gymnastics</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/lacrosse.html"><span>Lacrosse</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/physical-education.html"><span>Physical Education</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/physical-education/exercise-training-bands.html"><span>Exercise Training Bands</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/physical-education/hurdles.html"><span>Hurdles</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/physical-education/markers.html"><span>Markers</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/playground.html"><span>Playground</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/dodgeballs.html"><span>Dodgeballs</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/foursquare-balls.html"><span>Foursquare Balls</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/handballs.html"><span>Handballs</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/jump-ropes.html"><span>Jump Ropes</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/kickballs.html"><span>Kickballs</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/playground-balls.html"><span>Playground Balls</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/playground/tetherballs.html"><span>Tetherballs</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/rugby.html"><span>Rugby</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/rugby/rugby-balls.html"><span>Rugby Balls</span></a></div></div></div></div><div class="column last odd"><div class="itemMenu level1"><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/soccer.html"><span>Soccer</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/soccer/soccer-balls.html"><span>Soccer Balls</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/softball.html"><span>Softball</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/softball/softballs.html"><span>Softballs</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/multi-sport-accessories.html"><span>Sport Accessories</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/multi-sport-accessories/ball-bags.html"><span>Ball Bags</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/swimming.html"><span>Swimming</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/tennis.html"><span>Tennis</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/timers-pedometers.html"><span>Timers & Pedometers</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/timers-pedometers/stop-watches.html"><span>Stop Watches</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/track-field.html"><span>Track & Field</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/volleyball.html"><span>Volleyball</span></a><div class="itemSubMenu level1"><div class="itemMenu level2"><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/volleyball/miscellaneous-volleyball-accessories.html"><span>Misc Accessories</span></a><a class="itemMenuName level2" href="http://www.directtoschools.com/athletic-supplies/volleyball/volleyballs.html"><span>Volleyballs</span></a></div></div><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/whistles.html"><span>Whistles</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/wrestling.html"><span>Wrestling</span></a><a class="itemMenuName level1" href="http://www.directtoschools.com/athletic-supplies/other-sports.html"><span>Other Sports</span></a></div></div>
これらの列を正当化する方法についてのアイデアやヒントをいただければ幸いです。