Rails Bootstrap Navbar and refineryCMS
Asked Answered
E

7

9

Does anyone have implemented the Rails Bootstrap Navbar in refineryCMS?

I'm having a hard time trying to figure out how to render the dropdown menu.

which should be the right way of accomplish this?

_menu.html.erb

<%    
  if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
    dom_id ||= 'menu'
  css = [(css || 'menu'), 'clearfix'].flatten.join(' ')
    hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<div class="navbar">
  <div class="navbar-inner">
    <div class="container">

      <nav id='<%= dom_id %>' class='<%= css %> nav'>
        <ul class="nav">


          <%= render :partial => '/refinery/menu_branch', :collection => roots,
                     :locals => {
                       :hide_children => hide_children,
                       :sibling_count => (roots.length - 1),
                       :menu_levels => local_assigns[:menu_levels],
                       :apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
                     } -%>

        </ul>
        </nav>
    </div>
    </div>
</div>
<% end -%>

_menu_branch.html.erb

<%
  if !!local_assigns[:apply_css] and (classes = custom_menu_branch_css(local_assigns)).any?
    css = "class='#{classes.join(' ')}'".html_safe
  end

-%>
<li class="dropdown">
<% if menu_branch.children.present? &&  menu_branch.ancestors.length < 1 %>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url), class: "dropdown-togle", data: { toggle: "dropdown" }) -%>
<% else %>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url)) -%>
<% end %>
  <% if ( (children = menu_branch.children unless hide_children).present? &&
          (!local_assigns[:menu_levels] || menu_branch.ancestors.length < local_assigns[:menu_levels]) ) -%>


      <ul class="dropdown-menu">
      <%= render :partial => '/refinery/menu_branch', :collection => children,
                 :locals => {
                   :apply_css => local_assigns[:apply_css],
                   :hide_children => !!hide_children,
                   :menu_levels => local_assigns[:menu_levels]
                  } -%>

    </ul>
</li>
<% end -%>

nav_bar snippet

<%= nav_bar :fixed => :top, :brand => "Fashionable Clicheizr 2.0", :responsive => true do %>
    <%= menu_group do %>
        <%= menu_item "Home", root_path %>
        <%= menu_divider %>
        <%= drop_down "Products" do %>
            <%= menu_item "Things you can't afford", expensive_products_path %>
            <%= menu_item "Things that won't suit you anyway", harem_pants_path %>
            <%= menu_item "Things you're not even cool enough to buy anyway", hipster_products_path %>
            <% if current_user.lives_in_hackney? %>
                <%= menu_item "Bikes", fixed_wheel_bikes_path %>
            <% end %>
        <% end %>
        <%= menu_item "About Us", about_us_path %>
        <%= menu_item "Contact", contact_path %>
    <% end %>
    <%= menu_group :pull => :right do %>
        <% if current_user %>
            <%= menu_item "Log Out", log_out_path %>
        <% else %>
            <%= form_for @user, :url => session_path(:user), html => {:class=> "navbar-form pull-right"} do |f| -%>
              <p><%= f.text_field :email %></p>
              <p><%= f.password_field :password %></p>
              <p><%= f.submit "Sign in" %></p>
            <% end -%>
        <% end %>
    <% end %>
<% end %>
Etoile answered 7/2, 2013 at 19:47 Comment(0)
R
7

Refinery 2.1.0 with Bootstrap 3

None of the solutions above worked for me. So I had to adapt from Valentine Konov's answer. Below you can find all of my files. You can always leave me a comment if you need any help. Here we go!

1) Check your RefineryCMS and Bootstrap versions

Gemfile

gem 'bootstrap-sass', '~> 3.1.1'
gem 'refinerycms', '~> 2.1.0'

2) Save a few lines of code

a. You actually have no need to create an app/decorators/models/refinery/page_decorator.rb file.

b. You can forget the menu_header method as well. This way, you'll have:

app/helpers/application_helper.rb

module ApplicationHelper
end

3) Now let's get to the real work

a. Override your default header with:

$ rake refinery:override view=refinery/_header.html

And change its code to:

app/views/refinery/_header.html.erb

<nav class="navbar navbar-default" role="navigation">
    <div class="container-fluid">

        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#"><%=Refinery::Core::site_name %></a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <%= Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self).to_html %>
        </div>
    </div>
</nav>

b. Now go to terminal and run rake refinery:override presenter=refinery/pages/menu_presenter. It will generate a menu_presenter.rb file. Change it to this:

app/presenters/refinery/pages/menu_presenter.rb

require 'active_support/core_ext/string'
require 'active_support/configurable'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/url_helper'

module Refinery
    module Pages
        class MenuPresenter
            include ActionView::Helpers::TagHelper
            include ActionView::Helpers::UrlHelper
            include ActiveSupport::Configurable

            config_accessor :roots, :menu_tag, :list_tag, :list_item_tag, :css, :dom_id,
                                            :max_depth, :selected_css, :first_css, :last_css, :list_first_css,
                                            :list_dropdown_css, :list_item_dropdown_css,
                                            :list_item__css, :link_dropdown_options, :carret

            # self.dom_id = nil
            # self.css = "pull-left"
            self.menu_tag = :section
            self.list_tag = :ul
            self.list_first_css = ["nav", "navbar-nav", "navbar-right"]
            self.carret = '<b class="caret"></b>'
            self.list_dropdown_css = "dropdown-menu"
            self.link_dropdown_options = {class: "dropdown-toggle", data: {:toggle=>"dropdown"}}
            self.list_item_tag = :li
            self.list_item_dropdown_css = :dropdown
            self.list_item__css = nil
            self.selected_css = :active
            self.first_css = :first
            self.last_css = :last

            def roots
                config.roots.presence || collection.roots
            end

            attr_accessor :context, :collection
            delegate :output_buffer, :output_buffer=, :to => :context

            def initialize(collection, context)
                @collection = collection
                @context = context
            end

            def to_html
                render_menu(roots) if roots.present?
            end

            private
            def render_menu(items)
                content_tag(menu_tag, :id => dom_id, :class => css) do
                    render_menu_items(items)
                end
            end

            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 render_menu_item(menu_item, index)
                content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
                    @cont = context.refinery.url_for(menu_item.url)
                    buffer = ActiveSupport::SafeBuffer.new
                        if check_for_dropdown_item(menu_item)
                            buffer << link_to((menu_item.title+carret).html_safe, "#", link_dropdown_options)
                        else
                            buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
                        end
                    buffer << render_menu_items(menu_item_children(menu_item))
                    buffer
                end
            end

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

            # Determines whether any item underneath the supplied item is the current item according to rails.
            # Just calls selected_item? for each descendant of the supplied item
            # unless it first quickly determines that there are no descendants.
            def descendant_item_selected?(item)
                item.has_children? && item.descendants.any?(&method(:selected_item?))
            end

            def selected_item_or_descendant_item_selected?(item)
                selected_item?(item) || descendant_item_selected?(item)
            end

            # Determine whether the supplied item is the currently open item according to Refinery.
            def selected_item?(item)
                path = context.request.path
                path = path.force_encoding('utf-8') if path.respond_to?(:force_encoding)

                # Ensure we match the path without the locale, if present.
                if %r{^/#{::I18n.locale}/} === path
                    path = path.split(%r{^/#{::I18n.locale}}).last.presence || "/"
                end

                # First try to match against a "menu match" value, if available.
                return true if item.try(:menu_match).present? && path =~ Regexp.new(item.menu_match)

                # Find the first url that is a string.
                url = [item.url]
                url << ['', item.url[:path]].compact.flatten.join('/') if item.url.respond_to?(:keys)
                url = url.last.match(%r{^/#{::I18n.locale.to_s}(/.*)}) ? $1 : url.detect{|u| u.is_a?(String)}

                # Now use all possible vectors to try to find a valid match
                [path, URI.decode(path)].include?(url) || path == "/#{item.original_id}"
            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 menu_item_children(menu_item)
                within_max_depth?(menu_item) ? menu_item.children : []
            end

            def within_max_depth?(menu_item)
                !max_depth || menu_item.depth < max_depth
            end

        end
    end
end

c. Restart your server and see the results. If you already have some pages created, your navbar should look similar to the one below:

enter image description here

Randyranee answered 14/4, 2014 at 20:56 Comment(2)
You mean $ rake refinery:override view=refinery/_header.htmlScibert
Wow, you saved my life! To get this working with my web designer's code, I just had to change the stuff near the beginning: # self.menu_tag = :section self.menu_tag = :div self.css = "navbar-collapse collapse navbar-right" self.list_tag = :ul self.list_first_css = ["nav", "navbar-nav"]` (With the code you suggested, there's a double navbar-right class, and an extra section in the middle of the menu)Dorthea
D
8

Faced for some hours with same issue. Have solution with bit more pretty code (or just more close to refinery standarts), I believe, its better to override base Refinery menu_presenter first of all take a look a bit simmilar quest http://refinerycms.com/guides/menu-presenter and this one too: http://refinerycms.com/guides/extending-controllers-with-decorators

So. Based on that article lets do this

app/decorators/models/refinery/page_decorator.rb:

Refinery::Page.class_eval do
  def self.menu_pages
    where :show_in_menu => true
  end
end

app/helpers/application_helper.rb

module ApplicationHelper
  def menu_header
    menu_items = Refinery::Menu.new(Refinery::Page.menu_pages)

    presenter = Refinery::Pages::MenuPresenter.new(menu_items, self)
    presenter.first_css = nil
    presenter.last_css = nil

    presenter
  end
end

in terminal run:

cd /path/to/app/
rake refinery:override presenter=refinery/pages/menu_presenter

It will generate app/presenters/refinery/pages/menu_presenter.rb change it to this:

require 'active_support/core_ext/string'
require 'active_support/configurable'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/url_helper'

module Refinery
  module Pages
    class MenuPresenter
      include ActionView::Helpers::TagHelper
      include ActionView::Helpers::UrlHelper
      include ActiveSupport::Configurable

      config_accessor :roots, :menu_tag, :list_tag, :list_item_tag, :css, :dom_id,
                      :max_depth, :selected_css, :first_css, :last_css, :list_first_css,
                      :list_dropdown_css, :list_item_dropdown_css,
                      :list_item__css, :link_dropdown_options, :carret

      self.dom_id = :div
      self.css = ["nav-collapse", "collapse", "navbar-responsive-collapse"]
      self.menu_tag = :nav
      self.list_tag = :ul
      self.list_first_css = :nav
      self.carret = '<b class="caret"></b>'
      self.list_dropdown_css = "dropdown-menu"
      self.link_dropdown_options = {class: "toggle-dropdown", data: {:toggle=>"dropdown"}}
      self.list_item_tag = :li
      self.list_item_dropdown_css = :dropdown
      self.list_item__css = nil
      self.selected_css = :active
      self.first_css = :first
      self.last_css = :last
      def roots
        config.roots.presence || collection.roots
      end

      attr_accessor :context, :collection
      delegate :output_buffer, :output_buffer=, :to => :context

      def initialize(collection, context)
        @collection = collection
        @context = context
      end

      def to_html
        render_menu(roots) if roots.present?
      end

      private
      def render_menu(items)
        content_tag(menu_tag, :id => dom_id, :class => css) do
          render_menu_items(items)
        end
      end

      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 render_menu_item(menu_item, index)
        content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
          @cont = context.refinery.url_for(menu_item.url)
          buffer = ActiveSupport::SafeBuffer.new
            if check_for_dropdown_item(menu_item)
              buffer << link_to((menu_item.title+carret).html_safe, "#", link_dropdown_options)
            else
              buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
            end
          buffer << render_menu_items(menu_item_children(menu_item))
          buffer
        end
      end

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

      # Determines whether any item underneath the supplied item is the current item according to rails.
      # Just calls selected_item? for each descendant of the supplied item
      # unless it first quickly determines that there are no descendants.
      def descendant_item_selected?(item)
        item.has_children? && item.descendants.any?(&method(:selected_item?))
      end

      def selected_item_or_descendant_item_selected?(item)
        selected_item?(item) || descendant_item_selected?(item)
      end

      # Determine whether the supplied item is the currently open item according to Refinery.
      def selected_item?(item)
        path = context.request.path
        path = path.force_encoding('utf-8') if path.respond_to?(:force_encoding)

        # Ensure we match the path without the locale, if present.
        if %r{^/#{::I18n.locale}/} === path
          path = path.split(%r{^/#{::I18n.locale}}).last.presence || "/"
        end

        # First try to match against a "menu match" value, if available.
        return true if item.try(:menu_match).present? && path =~ Regexp.new(item.menu_match)

        # Find the first url that is a string.
        url = [item.url]
        url << ['', item.url[:path]].compact.flatten.join('/') if item.url.respond_to?(:keys)
        url = url.last.match(%r{^/#{::I18n.locale.to_s}(/.*)}) ? $1 : url.detect{|u| u.is_a?(String)}

        # Now use all possible vectors to try to find a valid match
        [path, URI.decode(path)].include?(url) || path == "/#{item.original_id}"
      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 menu_item_children(menu_item)
        within_max_depth?(menu_item) ? menu_item.children : []
      end

      def within_max_depth?(menu_item)
        !max_depth || menu_item.depth < max_depth
      end

    end
  end
end

almost done. add menu_header.to_html to your menu inside container of your menu like this:

    <div class="navbar navbar-fixed-top">
      <div class="navbar-inner">
        <div class="container">
          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </a>
          <a class="brand" href="#"><%=Refinery::Core::site_name %></a>
          <%= menu_header.to_html %>
        </div>
      </div>
    </div>

PS: RefineryCMS 2.1.0

Demagogic answered 23/8, 2013 at 6:11 Comment(4)
I have tried this -- it is almost there, bar a few small changes, and I haven't tested it thoroughly (although dropdowns don't seem to be working for me). In order for the Bootstrap menu to show correctly, I needed to change list_first_css line in the Presenter code above to: self.list_first_css = "nav navbar-nav". But +1 for a comprehensive answer, this looks like it'll give me a great starting point.Gastritis
... menu_items_css method is not defined... :-)Gastritis
Valentine Konov approach looks nice but in my case dropdown are not working.Etoile
You don't need to override the entire MenuPresenter; just subclass it, override the methods you want to change and use your new presenter in its place in your templates.Boutis
R
7

Refinery 2.1.0 with Bootstrap 3

None of the solutions above worked for me. So I had to adapt from Valentine Konov's answer. Below you can find all of my files. You can always leave me a comment if you need any help. Here we go!

1) Check your RefineryCMS and Bootstrap versions

Gemfile

gem 'bootstrap-sass', '~> 3.1.1'
gem 'refinerycms', '~> 2.1.0'

2) Save a few lines of code

a. You actually have no need to create an app/decorators/models/refinery/page_decorator.rb file.

b. You can forget the menu_header method as well. This way, you'll have:

app/helpers/application_helper.rb

module ApplicationHelper
end

3) Now let's get to the real work

a. Override your default header with:

$ rake refinery:override view=refinery/_header.html

And change its code to:

app/views/refinery/_header.html.erb

<nav class="navbar navbar-default" role="navigation">
    <div class="container-fluid">

        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand" href="#"><%=Refinery::Core::site_name %></a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
            <%= Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self).to_html %>
        </div>
    </div>
</nav>

b. Now go to terminal and run rake refinery:override presenter=refinery/pages/menu_presenter. It will generate a menu_presenter.rb file. Change it to this:

app/presenters/refinery/pages/menu_presenter.rb

require 'active_support/core_ext/string'
require 'active_support/configurable'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/url_helper'

module Refinery
    module Pages
        class MenuPresenter
            include ActionView::Helpers::TagHelper
            include ActionView::Helpers::UrlHelper
            include ActiveSupport::Configurable

            config_accessor :roots, :menu_tag, :list_tag, :list_item_tag, :css, :dom_id,
                                            :max_depth, :selected_css, :first_css, :last_css, :list_first_css,
                                            :list_dropdown_css, :list_item_dropdown_css,
                                            :list_item__css, :link_dropdown_options, :carret

            # self.dom_id = nil
            # self.css = "pull-left"
            self.menu_tag = :section
            self.list_tag = :ul
            self.list_first_css = ["nav", "navbar-nav", "navbar-right"]
            self.carret = '<b class="caret"></b>'
            self.list_dropdown_css = "dropdown-menu"
            self.link_dropdown_options = {class: "dropdown-toggle", data: {:toggle=>"dropdown"}}
            self.list_item_tag = :li
            self.list_item_dropdown_css = :dropdown
            self.list_item__css = nil
            self.selected_css = :active
            self.first_css = :first
            self.last_css = :last

            def roots
                config.roots.presence || collection.roots
            end

            attr_accessor :context, :collection
            delegate :output_buffer, :output_buffer=, :to => :context

            def initialize(collection, context)
                @collection = collection
                @context = context
            end

            def to_html
                render_menu(roots) if roots.present?
            end

            private
            def render_menu(items)
                content_tag(menu_tag, :id => dom_id, :class => css) do
                    render_menu_items(items)
                end
            end

            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 render_menu_item(menu_item, index)
                content_tag(list_item_tag, :class => menu_item_css(menu_item, index)) do
                    @cont = context.refinery.url_for(menu_item.url)
                    buffer = ActiveSupport::SafeBuffer.new
                        if check_for_dropdown_item(menu_item)
                            buffer << link_to((menu_item.title+carret).html_safe, "#", link_dropdown_options)
                        else
                            buffer << link_to(menu_item.title, context.refinery.url_for(menu_item.url))
                        end
                    buffer << render_menu_items(menu_item_children(menu_item))
                    buffer
                end
            end

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

            # Determines whether any item underneath the supplied item is the current item according to rails.
            # Just calls selected_item? for each descendant of the supplied item
            # unless it first quickly determines that there are no descendants.
            def descendant_item_selected?(item)
                item.has_children? && item.descendants.any?(&method(:selected_item?))
            end

            def selected_item_or_descendant_item_selected?(item)
                selected_item?(item) || descendant_item_selected?(item)
            end

            # Determine whether the supplied item is the currently open item according to Refinery.
            def selected_item?(item)
                path = context.request.path
                path = path.force_encoding('utf-8') if path.respond_to?(:force_encoding)

                # Ensure we match the path without the locale, if present.
                if %r{^/#{::I18n.locale}/} === path
                    path = path.split(%r{^/#{::I18n.locale}}).last.presence || "/"
                end

                # First try to match against a "menu match" value, if available.
                return true if item.try(:menu_match).present? && path =~ Regexp.new(item.menu_match)

                # Find the first url that is a string.
                url = [item.url]
                url << ['', item.url[:path]].compact.flatten.join('/') if item.url.respond_to?(:keys)
                url = url.last.match(%r{^/#{::I18n.locale.to_s}(/.*)}) ? $1 : url.detect{|u| u.is_a?(String)}

                # Now use all possible vectors to try to find a valid match
                [path, URI.decode(path)].include?(url) || path == "/#{item.original_id}"
            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 menu_item_children(menu_item)
                within_max_depth?(menu_item) ? menu_item.children : []
            end

            def within_max_depth?(menu_item)
                !max_depth || menu_item.depth < max_depth
            end

        end
    end
end

c. Restart your server and see the results. If you already have some pages created, your navbar should look similar to the one below:

enter image description here

Randyranee answered 14/4, 2014 at 20:56 Comment(2)
You mean $ rake refinery:override view=refinery/_header.htmlScibert
Wow, you saved my life! To get this working with my web designer's code, I just had to change the stuff near the beginning: # self.menu_tag = :section self.menu_tag = :div self.css = "navbar-collapse collapse navbar-right" self.list_tag = :ul self.list_first_css = ["nav", "navbar-nav"]` (With the code you suggested, there's a double navbar-right class, and an extra section in the middle of the menu)Dorthea
R
4

Try this _menu_branch.html.erb

<% if ( (children = menu_branch.children unless hide_children).present? &&
        (!local_assigns[:menu_levels] || menu_branch.ancestors.length < local_assigns[:menu_levels]) ) -%>

<%
  if !!local_assigns[:apply_css] and (classes = menu_branch_css(local_assigns)).any?
    css = "class='#{classes.join(' ')} dropdown'".html_safe
  end

-%>
<li<%= ['', css].compact.join(' ').gsub(/\ *$/, '').html_safe %>>
<%= link_to("#{menu_branch.title} <b class='caret'></b>".html_safe, refinery.url_for(menu_branch.url), :class=>"dropdown-toggle", 'data-toggle'=>'dropdown') -%>
    <ul class='dropdown-menu'>
      <%= render :partial => '/refinery/menu_branch', :collection => children,
                 :locals => {
                   :apply_css => local_assigns[:apply_css],
                   :hide_children => !!hide_children,
                   :menu_levels => local_assigns[:menu_levels]
                 } -%>
    </ul>

</li>
<% else -%>
<%
  if !!local_assigns[:apply_css] and (classes = menu_branch_css(local_assigns)).any?
    css = "class='#{classes.join(' ')}'".html_safe
  end

-%>
<li<%= ['', css].compact.join(' ').gsub(/\ *$/, '').html_safe %>>
<%= link_to(menu_branch.title, refinery.url_for(menu_branch.url)) -%>
</li>
<% end -%>

_menu.html.erb

<%
  # Collect the root items.
  # ::Refinery::Menu is smart enough to remember all of the items in the original collection.
  if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
    dom_id ||= 'menu'
    css = [(css || 'menu clearfix')].flatten.join(' ')
    hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<div id="main-menu" class="nav-collapse">
  <nav id='<%= dom_id %>' class='<%= css %>'>
    <ul id="main-menu-left" class="nav">
      <%= render :partial => '/refinery/menu_branch', :collection => roots,
                 :locals => {
                   :hide_children => hide_children,
                   :sibling_count => (roots.length - 1),
                   :menu_levels => local_assigns[:menu_levels],
                   :apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
                 } -%>
    </ul>
  </nav>
</div>
<% end -%>

and _header.html.erb

<div class="container">
    <div class="navbar">
      <div class="navbar-inner">
        <div class="container">
          <a data-target=".nav-collapse" data-toggle="collapse" class="btn btn-navbar">
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>
                 <span class="icon-bar"></span>
                </a>
    <%= link_to Refinery::Core.site_name, refinery.root_path, :class => "brand" %>

    <%= render(:partial => "/refinery/menu", :locals => {
                 :dom_id => 'menu',
                 :css => 'menu'
               }) %>
        </div>
      </div>
    </div>  
</div>
Rectify answered 18/2, 2013 at 10:59 Comment(1)
RefineryCMS has just updated to 2.1 and unfortunately, for this post anyway, they have altered and swapped out the menu system listed above. Of course it's not going to be gone over night, but I just thought I would mention this in case you are thinking of updating to RefineryCMS 2.1 in the near future. They have started using Menu Presenter to accomplish the rendering of the CMS' menus. I realize my pose won't be much help here, but here is the new menu systems guide. refinerycms.com/guides/menu-presenterPatagium
A
3

The approach outlined by user1852788 worked for me. If you are using a menu with drop downs don't forget to load the bootstrap js in your application.js manifest file:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .

And then call the dropdown function (I have a file called layout.js.coffee):

$('.dropdown-toggle').dropdown()
Authors answered 4/3, 2013 at 18:18 Comment(0)
C
1

This Gist worked great for me for the latest of Refinery and Bootstrap https://gist.github.com/npflood/2d3f5fc44518ef231195

Callan answered 3/5, 2015 at 18:4 Comment(0)
R
0

There is a gem that tries to solve this problem.

https://github.com/ghoppe/refinerycms-bootstrap

But I've been having problems with it personally.

Require answered 30/4, 2013 at 3:59 Comment(0)
G
0

I found much easier way to do this for refinerycms 2-0-stable

my solution is the following:

first _menu.html.erb update css variable with bootstrap classes and add necessary html for example I added div to wrap ul

<%
  # Collect the root items.
  # ::Refinery::Menu is smart enough to remember all of the items in the original collection.
  if (roots = local_assigns[:roots] || (collection ||= refinery_menu_pages).roots).present?
    dom_id ||= 'menu'
    css = [(css || 'pull-right')].flatten.join(' ')
    hide_children = Refinery::Core.menu_hide_children if hide_children.nil?
-%>
<nav id='<%= dom_id %>' class='<%= css %>'>
  <div class="collapse navbar-collapse">
    <ul class="nav nav-pills navbar-nav">
      <%= render :partial => '/refinery/menu_branch', :collection => roots,
                 :locals => {
                   :hide_children => hide_children,
                   :sibling_count => (roots.length - 1),
                   :menu_levels => local_assigns[:menu_levels],
                   :apply_css => true #if you don't care about class='first' class='last' or class='selected' set apply_css to false for speed.
                 } -%>
    </ul>
  </div>
</nav>
<% end -%>

second _menu_branch.html.erb update class with bootstrap classes

    <%
  if !!local_assigns[:apply_css] and (classes = menu_branch_css(local_assigns)).any?
    css = "class='#{classes.join(' ')}'".html_safe
  end
-%>
<% if ( (children = menu_branch.children unless hide_children).present? &&
        (!local_assigns[:menu_levels] || menu_branch.ancestors.length < local_assigns[:menu_levels]) ) -%>
  <li class="dropdown">
    <a href="<%= refinery.url_for(menu_branch.url) %>" class="dropdown-toggle" data-toggle="dropdown"><%= menu_branch.title %><b class="caret"></b></a>
    <ul class='dropdown-menu'>
      <%= render :partial => '/refinery/menu_branch', :collection => children,
                 :locals => {
                   :apply_css => local_assigns[:apply_css],
                   :hide_children => !!hide_children,
                   :menu_levels => local_assigns[:menu_levels]
                 } -%>
    </ul>
<% else -%>
  <li<%= ['', css].compact.join(' ').gsub(/\ *$/, '').html_safe %>>
  <%= link_to(menu_branch.title, refinery.url_for(menu_branch.url)) -%>
<% end -%>
  </li>

now your menu should display fine. To enable Active you just need to update /config/initializers/refinery/core.rb file by changing the following code:

change selected, to active

    # CSS class selectors for menu helper
  config.menu_css = {:selected=>"active", :first=>"first", :last=>"last"}
Gerbold answered 1/12, 2013 at 23:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.