Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
How to make breadcrumbs_on_rails render a Bootstrap compatible breadcrumb navigation
# The BootstrapBreadcrumbsBuilder is a Bootstrap compatible breadcrumb builder.
# It provides basic functionalities to render a breadcrumb navigation according to Bootstrap's conventions.
#
# BootstrapBreadcrumbsBuilder accepts a limited set of options:
# * separator: what should be displayed as a separator between elements
#
# You can use it with the :builder option on render_breadcrumbs:
# <%= render_breadcrumbs :builder => ::BootstrapBreadcrumbsBuilder, :separator => "&raquo;" %>
#
# Note: You may need to adjust the autoload_paths in your config/application.rb file for rails to load this class:
# config.autoload_paths += Dir["#{config.root}/lib/"]
#
class BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
def render
@context.content_tag(:ul, class: 'breadcrumb') do
@elements.collect do |element|
render_element(element)
end.join.html_safe
end
end
def render_element(element)
current = @context.current_page?(compute_path(element))
@context.content_tag(:li, :class => ('active' if current)) do
link_or_text = @context.link_to_unless_current(compute_name(element), compute_path(element), element.options)
divider = @context.content_tag(:span, (@options[:separator] || '/').html_safe, :class => 'divider') unless current
link_or_text + (divider || '')
end
end
end
@idStar

This comment has been minimized.

Show comment Hide comment
@idStar

idStar Nov 26, 2012

Works perfectly. Thank you!

idStar commented Nov 26, 2012

Works perfectly. Thank you!

@ArthurN

This comment has been minimized.

Show comment Hide comment
@ArthurN

ArthurN Dec 2, 2012

+1 thanks!

ArthurN commented Dec 2, 2012

+1 thanks!

@linuxonrails

This comment has been minimized.

Show comment Hide comment
@linuxonrails

linuxonrails Feb 21, 2013

I think the last link/text should be active ever:

class BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
  def render
    @context.content_tag(:ul, :class => 'breadcrumb') do
      elements_count = @elements.size
      i = 0
      @elements.collect do |element|
        i += 1
        render_element(element, last = (i == elements_count))
      end.join.html_safe
    end
  end

  def render_element(element, last = false)
    current = @context.current_page?(compute_path(element))

    @context.content_tag(:li, :class => ('active' if last)) do
      if last
        link_or_text = compute_name(element)
      else
        link_or_text = @context.link_to(compute_name(element), compute_path(element), element.options)
      end
      divider = @context.content_tag(:span, (@options[:separator] || ' &gt; ').html_safe, :class => 'divider') unless current

      link_or_text + (last ? '' : (divider || ''))
    end
  end
end

I think the last link/text should be active ever:

class BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
  def render
    @context.content_tag(:ul, :class => 'breadcrumb') do
      elements_count = @elements.size
      i = 0
      @elements.collect do |element|
        i += 1
        render_element(element, last = (i == elements_count))
      end.join.html_safe
    end
  end

  def render_element(element, last = false)
    current = @context.current_page?(compute_path(element))

    @context.content_tag(:li, :class => ('active' if last)) do
      if last
        link_or_text = compute_name(element)
      else
        link_or_text = @context.link_to(compute_name(element), compute_path(element), element.options)
      end
      divider = @context.content_tag(:span, (@options[:separator] || ' &gt; ').html_safe, :class => 'divider') unless current

      link_or_text + (last ? '' : (divider || ''))
    end
  end
end
@kinjal

This comment has been minimized.

Show comment Hide comment
@kinjal

kinjal May 13, 2013

save the code as bootstrap_breadcrumbs_builder.rb in application dir/lib. restart server.

kinjal commented May 13, 2013

save the code as bootstrap_breadcrumbs_builder.rb in application dir/lib. restart server.

@chitsaou

This comment has been minimized.

Show comment Hide comment
@chitsaou

chitsaou Jul 17, 2013

Hi, how would you like to license this builder? I'd like to use it in a commercial project. Thanks in advance.

Hi, how would you like to license this builder? I'd like to use it in a commercial project. Thanks in advance.

@pazaricha

This comment has been minimized.

Show comment Hide comment
@pazaricha

pazaricha Jul 18, 2013

If the separator doesn't work for you, use this class instead:

class BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
  def render
    @context.content_tag(:ul, :class => 'breadcrumb') do
      elements_count = @elements.size
      i = 0
      @elements.collect do |element|
        i += 1
        render_element(element, last = (i == elements_count))
      end.join.html_safe
    end
  end

  def render_element(element, last = false)
    current = @context.current_page?(compute_path(element))

    @context.content_tag(:li, :class => ('active' if last)) do
      if last
        link_or_text = compute_name(element)
      else
        link_or_text = @context.link_to(compute_name(element), compute_path(element), element.options)
      end

      divider = @context.content_tag(:span, (@options[:separator] || ' / ').html_safe, :class => 'divider') unless last

      link_or_text + (last ? '' : (divider || ''))
    end
  end
end

If the separator doesn't work for you, use this class instead:

class BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
  def render
    @context.content_tag(:ul, :class => 'breadcrumb') do
      elements_count = @elements.size
      i = 0
      @elements.collect do |element|
        i += 1
        render_element(element, last = (i == elements_count))
      end.join.html_safe
    end
  end

  def render_element(element, last = false)
    current = @context.current_page?(compute_path(element))

    @context.content_tag(:li, :class => ('active' if last)) do
      if last
        link_or_text = compute_name(element)
      else
        link_or_text = @context.link_to(compute_name(element), compute_path(element), element.options)
      end

      divider = @context.content_tag(:span, (@options[:separator] || ' / ').html_safe, :class => 'divider') unless last

      link_or_text + (last ? '' : (divider || ''))
    end
  end
end
@toobulkeh

This comment has been minimized.

Show comment Hide comment
@toobulkeh

toobulkeh Aug 2, 2013

this works in development, but not production for me:

ActionView::Template::Error (can't convert Symbol into String):
    11:         = image_tag 'windstream-hosted-solutions-logo.png'
    12:     = render 'navbar'
    13:     .container
    14:       = render_breadcrumbs '/'
    15:     .container
    16:       .row
    17:         .span12
  app/views/layouts/application.html.haml:14:in `_app_views_layouts_application_html_haml___4198396153724011815_32359140'

this works in development, but not production for me:

ActionView::Template::Error (can't convert Symbol into String):
    11:         = image_tag 'windstream-hosted-solutions-logo.png'
    12:     = render 'navbar'
    13:     .container
    14:       = render_breadcrumbs '/'
    15:     .container
    16:       .row
    17:         .span12
  app/views/layouts/application.html.haml:14:in `_app_views_layouts_application_html_haml___4198396153724011815_32359140'
@equivalent

This comment has been minimized.

Show comment Hide comment
@equivalent

equivalent Apr 4, 2014

Bootstrap 3 uses Css to render separators (you don't need to put one manually) so if anyone needs simplified version with working active links you can use my alteration https://gist.github.com/equivalent/9972557

Bootstrap 3 uses Css to render separators (you don't need to put one manually) so if anyone needs simplified version with working active links you can use my alteration https://gist.github.com/equivalent/9972557

@jevin

This comment has been minimized.

Show comment Hide comment
@jevin

jevin May 24, 2014

Nice! You can also achieve something similar using CSS only. Like so:

.breadcrumb li:last-child {
  color: #999999
}

That's the default style for the active class in Bootstrap 3.

jevin commented May 24, 2014

Nice! You can also achieve something similar using CSS only. Like so:

.breadcrumb li:last-child {
  color: #999999
}

That's the default style for the active class in Bootstrap 3.

@nacengineer

This comment has been minimized.

Show comment Hide comment
@nacengineer

nacengineer Dec 2, 2014

Also FWIW, I had to do some debugging to figure it out, if you want to check if any breadcrumbs exist, i.e. only render if they do... the breadcrumbs are in the instance variable @breadcrumbs.

Also FWIW, I had to do some debugging to figure it out, if you want to check if any breadcrumbs exist, i.e. only render if they do... the breadcrumbs are in the instance variable @breadcrumbs.

@SaladFork

This comment has been minimized.

Show comment Hide comment
@SaladFork

SaladFork Jul 20, 2017

Updated for Bootstrap 4 (alpha6): https://gist.github.com/SaladFork/270a4cb3ac20be9715b7117551c31ec7

Of note:

  • No longer has :separator option (Bootstrap 4 accomplishes this with CSS)
  • Now has :container_tag option in addition to :tag option (default to :ol and :li, respectively)
  • Now has :show_empty option which defaults to false to prevent rendering when there are no crumbs (h/t @mrfoto's fork)

Updated for Bootstrap 4 (alpha6): https://gist.github.com/SaladFork/270a4cb3ac20be9715b7117551c31ec7

Of note:

  • No longer has :separator option (Bootstrap 4 accomplishes this with CSS)
  • Now has :container_tag option in addition to :tag option (default to :ol and :li, respectively)
  • Now has :show_empty option which defaults to false to prevent rendering when there are no crumbs (h/t @mrfoto's fork)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment