Refinerycms: Apply Bootstrap Styles to Navigation Menu

RefineryCMS: apply bootstrap styles to navigation menu

It can be done, but the solution is not pretty because the Menu Presenter in Refinery 2.1 doesn't support all the right CSS options out of the box. But with a bit of perseverance, this is roughly what to do:

Firstly, create a new blank file here: config/initializers/refinery/monkey_patch_menu_presenter.rb

In this patch file, paste in the contents of this updated version of the menu presenter (published October 2013): menu_presenter.rb

Next, based on the instructions in section 5 of the menu presenter guide, in your app/helpers/application_helper.rb file, add a new method called navigation_menu:

def navigation_menu
presenter = Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self)
presenter.css = "navbar-inner"
presenter.menu_tag = :div
presenter.list_tag_css = "nav"
presenter.selected_css = "active"
presenter.first_css = ""
presenter.last_css = ""
presenter.max_depth = 0 # prevents dropdown menus, which don't render correctly
presenter
end

Finally, in your app/views/refinery/_header.html.erb file (use $ bundle exec rake refinery:override view=refinery/_header if it doesn't exist), replace the call for:

<%= Refinery::Pages::MenuPresenter.new(refinery_menu_pages, self).to_html %>

with:

<div class="navbar">
<%= navigation_menu.to_html %>
</div>

Ensure that you have the loaded the Bootstrap CSS/JS files and have wrapped the whole page in a <div class="container"> element. Then restart your application for the patch to take affect and hopefully you'll see a familiar bootstrap navigation bar.

Good luck!

Martyn.

Rails Bootstrap Navbar and refineryCMS

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:

Sample Image

Adding an image in the menu bar with RefineryCMS

Put the image in app/assets/images and use the following:

<%= link_to(image_tag("logo3.png" , id:"logosT"), refinery.root_path, class: 'navbar-brand' ) %>

iPhone - setNeedsDisplay doesn't call drawRect

It is -(void)drawRect:(CGRect)rect right? Make sure the method signature is correct, and you don't omit the rect argument even if you don't use it.

-setNeedsDisplay should be called the the subview, not self.

Also, -setNeedsDisplay won't call -drawRect: immediately. It only flushes the graphics cache so that -drawRect: is forced to be called in the next update of the frame.

How to create a menu from sub pages of a menu item AND use attributes/class on ul?

All in formation is in documentation - https://www.impresspages.org/docs/navigation ("ADD CUSTOM MENU ITEMS").

items variable supports menu objects, too.

In your case the final solution should look like this:

$pages = \Ip\Menu\Helper::getChildItems($pageId = 5);   

$options = array(
'items' => $pages,
'attributes' => array('class' => 'nav nav-stacked')
);
echo ipSlot('menu', $options);

System.Timers.Timer leaking due to direct delegate roots

have you tried using the DispatchTimer instead of System.Timers.Timer?

If a Timer is used in a WPF application, it is worth noting that the Timer runs on a different thread then the user interface (UI) thread. In order to access objects on the user interface (UI) thread, it is necessary to post the operation onto the Dispatcher of the user interface (UI) thread using Invoke or BeginInvoke. Reasons for using a DispatcherTimer opposed to a Timer are that the DispatcherTimer runs on the same thread as the Dispatcher and a DispatcherPriority can be set. ( from this blog )



Related Topics



Leave a reply



Submit