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:
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
How to Configure Sourcemaps for Less Using Grunt
Point One Style Class to Another
How to Use CSS Variables in Twitter-Bootstrap 4 $Theme-Colors Array
CSS: Define Media Query Within One Class
Angular2 Get Window Width Onresize
Webpack 4: Mini-CSS-Extract-Plugin + Sass-Loader + Splitchunks
CSS3 Button Background Color Infinite Transition
How to Force Twitter Bootstrap .Dl-Horizontal Dt Content to Wrap Instead of Truncate
How to Convert Whole Folder with Convert-Sass? (Scss to Sass)
Relation Between Dp - Sp and Px
@Import of Less Files into a Limited Scope
Difference Between Box and Grid in Material-Ui
Gooey CSS Effects with Contrast Parent
Difference Between Ng-Class and Ng-Style
Responsive Design: Why Does Height Zero & Padding-Bottom Work for Making a Div Responsively Sized
How to Hide One Column from Grid in Bootstrap Mobile Version