Loaf manages and displays breadcrumb trails in your Rails application.
- Use controllers and/or views to specify breadcrumb trails
- Specify urls using Rails conventions
- No markup assumptions for breadcrumbs trails rendering
- Use locales file for breadcrumb names
- Tested with Rails
>= 3.2
and Ruby>= 2.0.0
Add this line to your application's Gemfile:
gem 'loaf'
And then execute:
$ bundle
Or install it yourself as:
gem install loaf
Then run the generator:
rails generate loaf:install
Loaf allows you to add breadcrumbs in controllers and views.
In order to add breadcrumbs in controller use breadcrumb
method (see 2.1).
class Blog::CategoriesController < ApplicationController
breadcrumb 'Article Categories', :blog_categories_path, only: [:show]
def show
breadcrumb @category.title, blog_category_path(@category)
end
end
Then in your view render the breadcrumbs trail using breadcrumb_trail
Creation of breadcrumb in Rails is achieved by the breadcrumb
helper.
The breadcrumb
method takes at minimum two arguments: the first is a name for the crumb that will be displayed and the second is a url that the name points to. The url parameter uses the familiar Rails conventions.
When using path variable blog_categories_path
:
breadcrumb 'Categories', blog_categories_path
When using an instance @category
:
breadcrumb @category.title, blog_category_path(@category)
You can also use set of objects:
breadcrumb @category.title, [:blog, @category]
You can specify segments of the url:
breadcrumb @category.title, {controller: 'categories', action: 'show', id: @category.id}
Breadcrumbs are inherited, so if you set a breadcrumb in ApplicationController
, it will be inserted as a first element inside every breadcrumb trail. It is customary to set root breadcrumb like so:
class ApplicationController < ActionController::Base
breadcrumb 'Home', :root_path
end
Outside of controller actions the breadcrumb
helper behaviour is similar to filters/actions and as such you can limit breadcrumb scope with familiar options :only
, :except
. Any breadcrumb specified inside actions creates another level in breadcrumbs trail.
class ArticlesController < ApplicationController
breadcrumb 'All Articles', :articles_path, only: [:new, :create]
end
Each time you call the breadcrumb
helper, a new element is added to a breadcrumb trial stack:
class ArticlesController < ApplicationController
breadcrumb 'Home', :root_path
breadcrumb 'All Articles', :articles_path
def show
breadcrumb 'Article One', article_path(:one)
breadcrumb 'Article Two', article_path(:two)
end
end
Loaf allows you to call controller instance methods inside the breadcrumb
helper outside of any action. This is useful if your breadcrumb has parameterized behaviour. For example, to dynamically evaluate parameters for breadcrumb title do:
class CommentsController < ApplicationController
breadcrumb ->(c) { c.find_article(c.params[:post_id]).title }, :articles_path
end
Also, to dynamically evalute parameters inside the url argument do:
class CommentsController < ApplicationController
breadcrumb 'All Comments', ->(c) { c.post_comments_path(c.params[:post_id]) }
end
Loaf adds breadcrumb
helper also to the views. Together with controller breadcrumbs, the view breadcrumbs are appended as the last in breadcrumb trail. For instance, to specify view breadcrumb do:
<% breadcrumb @category.title, blog_category_path(@category) %>
Loaf allows you to define matching conditions in order to make a breadcrumb current with the :match
option.
The :match
key accepts the following values:
:inclusive
- the default value, which matches nested paths:exact
- matches only the exact same path:exclusive
- matches only direct path and its query params if present/regex/
- matches based on regular expression{foo: bar}
- match based on query params
For example, to force a breadcrumb to be the current regardless do:
breadcrumb 'New Post', new_post_path, match: :exact
To make a breadcrumb current based on the query params do:
breadcrumb 'Posts', posts_path(order: :desc), match: {order: :desc}
In order to display breadcrumbs use the breadcrumb_trail
view helper which as an argument accepts options and yields all breadcrumbs to a block:
breadcrumb_trail do |crumb|
...
end
The yielded pararmeter is a Loaf::Crumb
object that provides the following methods:
crumb.name # => the name as string
crumb.path # => the path as string
crumb.url # => alias for path
crumb.current? # => true or false
For example, you can add the following semantic markup to show breadcrumbs using the breadcrumb_trail
helper like so:
<nav aria-label="Breadcrumb">
<ol class='breadcrumbs'>
<% breadcrumb_trail do |crumb| %>
<li class="<%= crumb.current? ? 'current' : '' %>">
<%= link_to crumb.name, crumb.url, (crumb.current? ? {'aria-current' => 'page'} : {}) %>
<% unless crumb.current? %><span>::</span><% end %>
</li>
<% end %>
</ol>
</nav>
Usually best practice is to put such snippet inside its own partial.
There is a small set of custom opinionated defaults. The following options are valid parameters:
:capitalize # set breadcrumbs to have initial letter uppercase, default false
:crumb_length # breadcrumb length in integer, default length is 30 characters
You can override them in your views by passing them to the view breadcrumb
helper
<% breadcrumb_trail crumb_length: 20 do |name, url, styles| %>
..
<% end %>
or by configuring an option in config/initializers/loaf.rb
:
Loaf.configure do |config|
config.crumb_length = 20
end
You can use locales files for breadcrumbs' titles. Loaf assumes that all breadcrumb names are scoped inside breadcrumbs
namespace inside loaf
scope. However, this can be easily changed by passing scope: 'new_scope_name'
configuration option.
en:
loaf:
breadcrumbs:
name: 'my-breadcrumb-name'
Therefore, in your controller/view you would do:
class Blog::CategoriesController < ApplicationController
breadcrumb 'blog.categories', :blog_categories_path
end
And corresponding entry in locale would be:
en:
loaf:
breadcrumbs:
blog:
categories: 'Article Categories'
Questions or problems? Please post them on the issue tracker. You can contribute changes by forking the project and submitting a pull request. You can ensure the tests are passing by running bundle
and rake
.
Copyright (c) 2011-2017 Piotr Murach. See LICENSE.txt for further details.