weppos / breadcrumbs_on_rails

A simple Ruby on Rails plugin for creating and managing a breadcrumb navigation.
https://simonecarletti.com/code/breadcrumbs-on-rails
MIT License
944 stars 188 forks source link

Ability to fully support Bootstrap's markup? #138

Closed richardonrails closed 3 years ago

richardonrails commented 3 years ago

Bootstrap 3, 4, and 5 all require an active class to be added to the last list item.

Is this supported without writing a custom Builder ruby class?

An example for fully supporting Bootstrap in the README would be really helpful as I'm sure lots of people are trying to do that.

weppos commented 3 years ago

Is this supported without writing a custom Builder ruby class?

No, it will require a custom Builder.

I am reluctant to ship any specialized builder as part of the library, because it will tie the maintainership to this or that project. The lib is designed to allow extendability via custom Builders, that's fairly trivial to create one so I won't likely add bootstrap-oriented code.

richardonrails commented 3 years ago

Might want to remove the Bootstrap example from the README since it's not correct Bootstrap then.

Do you have any example of a how to use a custom Builder? I didn't see any documentation about it.

richardonrails commented 3 years ago

In case it helps others, here's what I pieced together for myself:

# lib/bootstrap_breadcrumbs.rb
class BootstrapBreadcrumbs < BreadcrumbsOnRails::Breadcrumbs::SimpleBuilder

  def render
    return '' if @elements.size == 0
    @context.content_tag(@options[:outer_tag], class: 'breadcrumb') do
      @elements.collect do |element|
        render_element(element)
      end.join(@options[:separator] || " &raquo; ").html_safe
    end
  end

  def render_element(element)
    if element.path == nil
      content = compute_name(element)
    else
      content = @context.link_to_unless_current(compute_name(element), compute_path(element), element.options)
    end
    @context.content_tag(@options[:tag], content, class: ('active' if @elements.last == element))
  end

end
# ERB:
<% require 'bootstrap_breadcrumbs' %>
<%= render_breadcrumbs outer_tag: :ol, tag: :li, separator: "", builder: ::BootstrapBreadcrumbs %>

Note that you may need to restart your web server after adding/editing the file in lib/

I also found this gist: https://gist.github.com/ricardodovalle/7174833

steveclarke commented 3 years ago

For anyone using Bootstrap 5, here's what works for me:

# app/lib/bootstrap_five_breadcrumbs.rb
class BootstrapFiveBreadcrumbs < BreadcrumbsOnRails::Breadcrumbs::SimpleBuilder
  def render
    return '' if @elements.size == 0

    @options[:outer_tag] ||= :ol
    @options[:tag] ||= :li
    @options[:separator] ||= ""

    @context.content_tag(@options[:outer_tag], class: 'breadcrumb') do
      @elements.collect do |element|
        render_element(element)
      end.join(@options[:separator]).html_safe
    end
  end

  def render_element(element)
    if element.path == nil
      content = compute_name(element)
    else
      content = @context.link_to_unless_current(compute_name(element), compute_path(element), element.options)
    end

    if @elements.last == element
      @context.content_tag(@options[:tag], content, class: "breadcrumb-item active", "aria-current": "page")
    else
      @context.content_tag(@options[:tag], content, class: "breadcrumb-item")
    end
  end
end
# _breadcrumbs.html.erb
<nav aria-label="breadcrumb">
  <%= render_breadcrumbs builder: ::BootstrapFiveBreadcrumbs %>
</nav>