RefineryCMS 2.1.0 and Zurb 4 Top menu with dropdown navigation

我的梦境 提交于 2019-12-03 17:30:27

instead of in_menu if you use fast_menu, then you will be able to reorder pages. menu_pages works, but you it will not render pages in the same order as they are in admin. hope this helps someone.

menu_items = Refinery::Menu.new(Refinery::Page.menu_pages)

menu_items = Refinery::Menu.new(Refinery::Page.fast_menu)

This is my version... Tested; and it works for me at least.

I used the code for Bootstrap I found on another question (link in the comments above). But instead of replacing the entire menu presenter I override only the methods we need for this.

Create a Zurb menu presenter file:

app/presenters/refinery/pages/zurb_menu_presenter.rb

module Refinery
  module Pages
    class ZurbMenuPresenter < MenuPresenter

    config_accessor :list_dropdown_css, :list_item_dropdown_css, :list_first_css

    MenuPresenter.menu_tag = :section
    MenuPresenter.css = "top-bar-section"
    self.list_dropdown_css = "dropdown"
    self.list_item_dropdown_css = "has-dropdown"
    self.list_first_css = nil

      def render_menu_items(menu_items)
        if menu_items.present?
          content_tag(list_tag, :class => menu_items_css(menu_items)) do
            menu_items.each_with_index.inject(ActiveSupport::SafeBuffer.new) do |buffer, (item, index)|
              buffer << render_menu_item(item, index)
            end
          end
        end
      end


      def check_for_dropdown_item(menu_item)
        ( menu_item != roots.first ) && ( menu_item_children( menu_item ).count > 0 )
      end

      def menu_items_css(menu_items)
        css = []

        css << list_first_css if (roots == menu_items)
        css << list_dropdown_css if (roots != menu_items)

        css.reject(&:blank?).presence

      end


      def menu_item_css(menu_item, index)
        css = []

        css << list_item_dropdown_css if (check_for_dropdown_item(menu_item))
        css << selected_css if selected_item_or_descendant_item_selected?(menu_item)
        css << first_css if index == 0
        css << last_css if index == menu_item.shown_siblings.length

        css.reject(&:blank?).presence
      end

      def render_menu_item(menu_item, index)

          if check_for_dropdown_item(menu_item)
              menu_item_class = list_item_dropdown_css
          else
              menu_item_class =  menu_item_css(menu_item, index)
          end

          content_tag(list_item_tag, :class => menu_item_class) do
              @cont = context.refinery.url_for(menu_item.url)
              buffer = ActiveSupport::SafeBuffer.new
              buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
              buffer << render_menu_items(menu_item_children(menu_item))
              buffer
          end
      end


    end
  end
end

I have a helper in app/helpers/application_helpers.rb:

module ApplicationHelper
    def zurb_menu
        menu_items = Refinery::Menu.new(Refinery::Page.menu_pages)
        presenter = Refinery::Pages::ZurbMenuPresenter.new(menu_items, self)
        presenter
    end
...

Then just call zurb_menu from the _header. I'm doing the Navbar stuff explicitly in my header function, which may or may not be right; you could roll that into the ZurbMenuPresenter class, and I may well do so:

app/views/refinery/_header.html.erb

<nav class="top-bar hide-for-small">
<ul class="title-area">

    <li class="name">
    <h1><a href="/">Home</a></h1>
    </li>
    <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
</ul>
<script src="http://foundation.zurb.com/public/assets/marketing_docs.js"></script>
<%=
    zurb_menu.to_html
%>

</nav>

You'll need to override the MenuPresenter. Specifically, you'll need to add the appropriate classes to the children of the top-level menu with the render_menu_item function. I'm not too familiar with Zerb Foundation, but this should get you started.

Note: untested code, I just switched in some class names from my own Bootstrap menu solution to get you started, you might have to do a bit more work. I'm also adding your helper code to the overridden presenter, so you can just call it in a view like this: <%= Refinery::ZerbMenuPresenter.new(refinery_menu_pages, self).to_html %>

app/presenters/refinery/zerb_menu_presenter.rb

module Refinery
  class ZerbMenuPresenter < ::Refinery::MenuPresenter
    self.css = "top-bar-section"
    self.dom_id = nil
    self.menu_tag = :section
    self.list_tag = "ul class='left'"
    def render_menu_item(menu_item, index)
      content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
        buffer = ActiveSupport::SafeBuffer.new
        if menu_item_children(menu_item).present?
          buffer << link_to("#{menu_item.title}", context.refinery.url_for(menu_item.url), :class => 'has-dropdown')
          buffer << render_menu_items(menu_item_children(menu_item), 'dropdown')
        else
          buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
        end
        buffer
      end
    end
  end
end
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!