Magento:如何在主导航菜单的下拉菜单中添加活动产品

Posted

技术标签:

【中文标题】Magento:如何在主导航菜单的下拉菜单中添加活动产品【英文标题】:Magento: HOW-TO add active products in a drop-down in Main Navigation Menu 【发布时间】:2012-02-23 08:30:11 【问题描述】:

我希望产品出现在类似于lowes.com 的下拉导航菜单中,而不是类别。这可能吗?我也没有支付任何费用:)

我尝试更改core/Mage/Catalog/Block/Navigation.php 并尝试将产品“伪造”为类别,但对象要求非常具体。由于创建菜单的功能是递归的,它只适用于实际类别,而没有其他功能。有什么想法吗?

我知道另一种选择是创建 2 级类别并将它们命名为我的产品,然后在 .htaccess 中进行重写,但这不是动态的而且非常混乱。

【问题讨论】:

【参考方案1】:

经过一番试验,我已经成功了!下面是在

中使用的新代码

app/code/core/Mage/Catalog/Block/Navigation.php

function _renderCategoryMenuItemhtml(如果进行本地化,则将“本地”替换为“核心”)

protected function _renderCategoryMenuItemHtml($category, $level = 0, $isLast = false, $isFirst = false, $isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false)

    if (!$category->getIsActive()) 
        return '';
    
    $html = array();

    // get all children
    if (Mage::helper('catalog/category_flat')->isEnabled()) 
        $children = (array)$category->getChildrenNodes();
        $childrenCount = count($children);
     else 
        $children = $category->getChildren();
        $childrenCount = $children->count();
    
    $hasChildren = ($children && $childrenCount);

    // get products listing
    $cur_category = Mage::getModel('catalog/category')->load($category->getId());
    $_productCollection = Mage::getResourceModel('catalog/product_collection')->addCategoryFilter($cur_category)->setOrder('position','ASC');
    $k = 1;
    $hasProduct1 = $_productCollection->count();
    $phtmlChildren = '';
    if ($hasProduct1 >= 1) 
        $l = $level+1;
        foreach ($_productCollection as $_product) 
            $cur_product = Mage::getModel('catalog/product')->load($_product->getId());
            if ($cur_product->getStatus()) 
                $phtmlChildren .= '<li';
                $phtmlChildren .= ' class="level'.$l;
                $phtmlChildren .= ' nav-'.$this->_getItemPosition($l);
                if ($k == $hasProduct1) 
                    $phtmlChildren .= ' last';
                
                $phtmlChildren .= '">'."\n";
                $phtmlChildren .= ' <a href="'.$cur_product->getProductUrl().'">'.$this->htmlEscape($cur_product->getName()).'</a>'."\n";
                $phtmlChildren .= '</li>';
                $k++;
            
        
    

    // select active children
    $activeChildren = array();
    foreach ($children as $child) 
        if ($child->getIsActive()) 
            $activeChildren[] = $child;
        
    
    $activeChildrenCount = count($activeChildren);
    $hasActiveChildren = ($activeChildrenCount > 0);

    // prepare list item html classes
    $classes = array();
    $classes[] = 'level' . $level;
    $classes[] = 'nav-' . $this->_getItemPosition($level);
    if ($this->isCategoryActive($category)) 
        $classes[] = 'active';
    
    $linkClass = '';
    if ($isOutermost && $outermostItemClass) 
        $classes[] = $outermostItemClass;
        $linkClass = ' class="'.$outermostItemClass.'"';
    
    if ($isFirst) 
        $classes[] = 'first';
    
    if ($isLast) 
        $classes[] = 'last';
    
    if ($hasActiveChildren) 
        $classes[] = 'parent';
    

    // prepare list item attributes
    $attributes = array();
    if (count($classes) > 0) 
        $attributes['class'] = implode(' ', $classes);
    
    if ($hasActiveChildren && !$noEventAttributes) 
         $attributes['onmouseover'] = 'toggleMenu(this,1)';
         $attributes['onmouseout'] = 'toggleMenu(this,0)';
    

    // assemble list item with attributes
    $htmlLi = '<li';
    foreach ($attributes as $attrName => $attrValue) 
        $htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
    
    $htmlLi .= '>';
    $html[] = $htmlLi;

    $html[] = '<a href="'.$this->getCategoryUrl($category).'"'.$linkClass.'>';
    $html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
    $html[] = '</a>';

    // render 'product' children
    $htmlChildren = '';
    if ($hasChildren) 
        $j = 0;
        foreach ($children as $child) 
            if ($child->getIsActive()) 
                $htmlChildren .= $this->_renderCategoryMenuItemHtml($child, $level + 1, $j++ >= $k);
            
        
    
    if ((!empty($htmlChildren)) || (!empty($phtmlChildren))) 
        $html[] = '<ul class="level'.$level.'">'."\n".$htmlChildren.$phtmlChildren.'</ul>';
    

    // render children
    $htmlChildren = '';
    $j = 0;
    foreach ($activeChildren as $child) 
        $htmlChildren .= $this->_renderCategoryMenuItemHtml(
            $child,
            ($level + 1),
            ($j == $activeChildrenCount - 1),
            ($j == 0),
            false,
            $outermostItemClass,
            $childrenWrapClass,
            $noEventAttributes
        );
        $j++;
    
    if (!empty($htmlChildren)) 
        if ($childrenWrapClass) 
            $html[] = '<div class="' . $childrenWrapClass . '">';
        
        $html[] = '<ul class="level' . $level . '">';
        $html[] = $htmlChildren;
        $html[] = '</ul>';
        if ($childrenWrapClass) 
            $html[] = '</div>';
        
    

    $html[] = '</li>';

    $html = implode("\n", $html);       
    return $html;

基本上有两个新添加的部分。第一部分构建产品集合以获取相关信息(名称、url 等)。第二部分将新的 无序列表 附加到现有的根类别 list items 中。希望这可以帮助某人。现在您无需为现有的扩展支付 99 美元 :)

在 v.1.6.1 上测试

【讨论】:

非常有帮助,谢谢。不利的一面是,如果文件被修改,它将中断更新,因为它是核心的一部分。 不,它不会,只需将它放在本地文件夹中。为了清楚起见,我只是列出了该特定代码。 请稍微扩展一下? 大多数人对他们的 Magento 自定义所做的就是为他们的所有工作创建本地文件夹。例如,如果你想保持这个特定的核心文件完整无缺,而是在 app/local/core/Mage/Catalog/Block/Navigation.php 中创建一个新的 Navigation.php。 Magento 首先查找本地文件夹,然后向下移动以查找核心等。 非常感谢。我不知道它是为代码做的。以为仅限于设计、皮肤等。【参考方案2】:

Jared Eitnier 的方法在登录、购物车和结帐页面除外 - 例如 /customer/account/login 产品的 URL 中断它变成 /customer/account/login/product-seo-url

奇怪的是,产品的 URL 可以在 CMS 页面上运行...

我正在使用 Magento 1.6.2

我已经改变了这一行 -

$phtmlChildren .= ' <a href="'.$cur_product->getUrlPath().'">'.$this->htmlEscape($cur_product->getName()).'</a>'."\n";

有了这个——

$phtmlChildren .= ' <a href="'.$cur_product->getProductUrl().'">'.$this->htmlEscape($cur_product->getName()).'</a>'."\n";

现在它适用于每一页!希望这可以帮助某人。

【讨论】:

很好,谢谢。我将使用此修复程序更新我的代码。【参考方案3】:

也许一个通用类别称为“所有产品”,并将所有产品链接到它?

然后只显示该类别。

至少这是一种解决方案,无需制动系统。

【讨论】:

以上是关于Magento:如何在主导航菜单的下拉菜单中添加活动产品的主要内容,如果未能解决你的问题,请参考以下文章

Magento 标头 childhtml 下拉菜单

如何自定义 magento 单页结帐表单

如何在导航栏中制作 Bootstrap 4 全宽下拉菜单?

如何向我创建的这个自定义 flexbox 导航栏添加下拉菜单?

悬停在下拉菜单上时保持主导航项悬停 CSS

引导导航下拉菜单切换问题