File: README.md

package info (click to toggle)
ruby-gretel 5.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 188 kB
  • sloc: ruby: 458; makefile: 4
file content (424 lines) | stat: -rw-r--r-- 15,314 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
[![Gem Version](https://badge.fury.io/rb/gretel.svg)](http://badge.fury.io/rb/gretel)
[![](https://github.com/kzkn/gretel/workflows/CI/badge.svg)](https://github.com/kzkn/gretel/actions/workflows/ci.yml)

<img src="http://i.imgur.com/CAKEaBM.png" alt="Handle breadcrumb trails... like a boss :)" />

([TL;DR](http://i.imgur.com/nH25yiH.png)) Gretel is a [Ruby on Rails](http://rubyonrails.org) plugin that makes it easy yet flexible to create breadcrumbs.
It is based around the idea that breadcrumbs are a concern of the view, so you define a set of breadcrumbs in *config/breadcrumbs.rb* (or multiple files; see below) and specify in the view which breadcrumb to use.
Gretel also supports [semantic breadcrumbs](https://developers.google.com/search/docs/data-types/breadcrumb) (those used in Google results).

Have fun!

## Installation

In your *Gemfile*:

```ruby
gem "gretel"
```

And run:

```bash
$ bundle install
```

## Example

Start by generating breadcrumbs configuration file:

```bash
$ rails generate gretel:install
```

Then, in *config/breadcrumbs.rb*:

```ruby
# Root crumb
crumb :root do
  link "Home", root_path
end

# Issue list
crumb :issues do
  link "All issues", issues_path
end

# Issue
crumb :issue do |issue|
  link issue.title, issue
  parent :issues
end
```

At the top of *app/views/issues/show.html.erb*, set the current breadcrumb (assuming you have loaded `@issue` with an issue):

```erb
<% breadcrumb :issue, @issue %>
```

Then, in *app/views/layouts/application.html.erb*:

```erb
<%= breadcrumbs pretext: "You are here: ",
                separator: " &rsaquo; " %>
```

This will generate the following HTML (indented for readability):

```html
<div class="breadcrumbs">
  <span class="pretext">You are here:</span>
  <a href="/">Home</a> &rsaquo;
  <a href="/issues">All issues</a> &rsaquo;
  <span class="current">My Issue</span>
</div>
```

## Options

You can pass options to `<%= breadcrumbs %>`, e.g. `<%= breadcrumbs pretext: "You are here: " %>`:

Option                   | Description                                                                                                                | Default
------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -------
:style                   | How to render the breadcrumbs. Can be `:inline`, `:ol`, `:ul`, `:bootstrap`, `:bootstrap4`, `:bootstrap5`, `:foundation5`, or `:bulma`. See below for more info.                   | `:inline`
:pretext                 | Text to be rendered before breadcrumb, e.g. `"You are here: "`.                                                            | None
:posttext                | Text to be appended after breadcrumb, e.g. `"Text after breacrumb"`,                                                       | None
:separator               | Separator between links, e.g. `" &rsaquo; "`.                                                                              | `" &rsaquo; "`
:autoroot                | Whether it should automatically link to the `:root` crumb if no parent is given.                                           | True
:display_single_fragment | Whether it should display the breadcrumb if it includes only one link.                                                     | False
:link_current            | Whether the current crumb should be linked to.                                                                             | False
:link_current_to_request_path            | Whether the current crumb should always link to the current request path. *Note:* This option will have no effect unless `:link_current` is set to `true`.                                                                             | True
:semantic                | Whether it should generate [semantic breadcrumbs](https://developers.google.com/search/docs/data-types/breadcrumb). | False
:id                      | ID for the breadcrumbs container.                                                                                          | None
:class                   | CSS class for the breadcrumbs container. Can be set to `nil` for no class.                                                 | `"breadcrumbs"`
:fragment_class          | CSS class for the fragment link or span. Can be set to `nil` for no class.                                                 | None
:current_class           | CSS class for the current link or span. Can be set to `nil` for no class.                                                  | `"current"`
:pretext_class           | CSS class for the pretext, if given. Can be set to `nil` for no class.                                                     | `"pretext"`
:posttext_class          | CSS class for the posttext, if given. Can be set to `nil` for no class.                                                    | `"posttext"`
:link_class              | CSS class for the link, if given. Can be set to `nil` for no class.                                                        | None
:container_tag           | Tag type that contains the breadcrumbs.                                                                                    | `:div`
:fragment_tag            | Tag type to contain each breadcrumb fragment/link.                                                                         | None
:aria_current            | Value of `aria-current` attribute.                                                                                         | None
:link_data               | Adds data attributes to breadcrumb                                                                                         | `nil`

### Styles

These are the styles you can use with `breadcrumbs style: :xx`.

Style          | Description
-------------- | -----------
`:inline`      | Default. Renders each link by itself with `&rsaquo;` as the seperator.
`:ol`          | Renders the links in `<li>` elements contained in an outer `<ol>`.
`:ul`          | Renders the links in `<li>` elements contained in an outer `<ul>`.
`:bootstrap`   | Renders the links for use in [Bootstrap v3](https://getbootstrap.com/docs/3.4/).
`:bootstrap4`  | Renders the links for use in [Bootstrap v4](https://getbootstrap.com/docs/4.6/getting-started/introduction/).
`:bootstrap5`  | Renders the links for use in [Bootstrap v5](https://getbootstrap.com/).
`:foundation5` | Renders the links for use in [Foundation 5](https://get.foundation/).
`:bulma`       | Renders the links for use in [Bulma](https://bulma.io/documentation/components/breadcrumb/).

#### Bulma Style

The `:bulma` style renders breadcrumbs compatible with [Bulma CSS](https://bulma.io/documentation/components/breadcrumb/).

**Basic usage:**

```erb
<nav class="breadcrumb" aria-label="breadcrumbs">
  <%= breadcrumbs style: :bulma %>
</nav>
```

This generates HTML like:

```html
<nav class="breadcrumb" aria-label="breadcrumbs">
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/issues">All issues</a></li>
    <li class="is-active"><a href="/issues/123" aria-current="page">My Issue</a></li>
  </ul>
</nav>
```

**Customize separators:**

```erb
<nav class="breadcrumb has-arrow-separator" aria-label="breadcrumbs">
  <%= breadcrumbs style: :bulma %>
</nav>
```

---

Or you can build the breadcrumbs manually for full customization; see below.

If you add other widely used styles, please submit a [Pull Request](https://github.com/kzkn/gretel/pulls) so others can use them too.


## More examples

In *config/breadcrumbs.rb*:

```ruby
# Root crumb
crumb :root do
  link "Home", root_path
end

# Regular crumb
crumb :projects do
  link "Projects", projects_path
end

# Parent crumbs
crumb :project_issues do |project|
  link "Issues", project_issues_path(project)
  parent project # inferred to :project
end

# Child
crumb :issue do |issue|
  link issue.name, issue_path(issue)
  parent :project_issues, issue.project
end

# Recursive parent categories
crumb :category do |category|
  link category.name, category
  if category.parent
    parent category.parent # inferred to :category
  else
    parent :categories
  end
end

# Product crumb with recursive parent categories (as defined above)
crumb :product do |product|
  link product.name, product
  parent product.category # inferred to :category
end

# Crumb with multiple links
crumb :test do
  link "One", one_path
  link "Two", two_path
  parent :about
end

# Example of using params to alter the parent, e.g. to
# match the user's actual navigation path
# URL: /products/123?q=my+search
crumb :search do |keyword|
  link "Search for #{keyword}", search_path(q: keyword)
end

crumb :product do |product|
  if keyword = params[:q].presence
    parent :search, keyword
  else # default
    parent product.category # inferred to :category
  end
end

# Multiple arguments
crumb :multiple_test do |a, b, c|
  link "Test #{a}, #{b}, #{c}", test_path
  parent :other_test, 3, 4, 5
end

# Breadcrumb without link URL; will not generate a link
crumb :without_link do
  link "Breadcrumb without link"
end

# Breadcrumb using view helper
module UsersHelper
  def user_name_for(user)
    user.name
  end
end

crumb :user do |user|
  link user_name_for(user), user
end

# I18n
crumb :home do
  link t("breadcrumbs.home"), root_path
end
```

## Building the breadcrumbs manually

You can use the `breadcrumbs` method directly as an array. It will return an array with the breadcrumb links so you can build the breadcrumbs HTML manually:

```erb
<% breadcrumbs.tap do |links| %>
  <% if links.any? %>
    You are here:
    <% links.each do |link| %>
      <%= link_to link.text, link.url, class: (link.current? ? "current" : nil) %> (<%= link.key %>)
    <% end %>
  <% end %>
<% end %>
```

If you use this approach, you lose the built-in semantic breadcrumb functionality. One way to
add them back is to use JSON-LD structured data:

```erb
<script type="application/ld+json">
  <%= raw breadcrumbs.structured_data(url_base: "https://example.com").to_json %>
</script>
```

Or, you can infer `url_base` from `request`:

```erb
<script type="application/ld+json">
  <%= raw breadcrumbs.structured_data(url_base: "#{request.protocol}#{request.host_with_port}").to_json %>
</script>
```

## Getting the parent breadcrumb

If you want to add a link to the parent breadcrumb, you can use the `parent_breadcrumb` view helper.
By default it returns a link instance that has the properties `#key`, `#text`, and `#url`.
You can supply options like `autoroot: false` etc.

If you supply a block, it will yield the link if it is present:

```erb
<% parent_breadcrumb do |link| %>
  <%= link_to "Back to #{link.text}", link.url %>
<% end %>
```

## Nice to know

### Access to view methods

When configuring breadcrumbs inside a `crumb :xx do ... end` block, you have access to all methods that are normally accessible in the view where the breadcrumbs are inserted. This includes your view helpers, `params`, `request`, etc.

### Using multiple breadcrumb configuration files

If you have a large site and you want to split your breadcrumbs configuration over multiple files, you can create a folder named `config/breadcrumbs` and put your configuration files (e.g. `products.rb` or `frontend.rb`) in there.
The format is the same as `config/breadcrumbs.rb` which is also loaded.

### Loading breadcrumbs from engines

Breadcrumbs are automatically loaded from any engines' `config/breadcrumbs.rb` and `config/breadcrumbs/**/*.rb`.
Breadcrumbs defined in your main app will override breadcrumbs from engines.

### Inferring breadcrumbs

Breadcrumbs can be automatically inferred if you pass an instance of an object that responds to `model_name` (like an ActiveRecord model instance).

For example:

```erb
<% breadcrumb @product %>
```

is short for

```erb
<% breadcrumb :product, @product %>
```

### Passing options to links

You can pass options to links to be used when you render breadcrumbs manually.

In *config/breadcrumbs.rb*:

```ruby
crumb :something do
  link "My Link", my_path, title: "My Title", other: "My Other Option"
end
```

Example methods you can then use in the view:

```ruby
breadcrumbs do |links|
  links.each do |link|
    link.title?              # => true
    link.title               # => "My Title"
    link.other?              # => true
    link.other               # => "My Other Option"
    link.nonexisting_option? # => false
    link.nonexisting_option  # => nil
  end
end
```

### ARIA support

You can improve the accessibility of your page with the markup that specified in [ARIA](https://www.w3.org/TR/wai-aria-practices/examples/breadcrumb/index.html). Gretel supports generating `aria-current` attribute:

```erb
<% breadcrumb :issue, @issue %>
<%= breadcrumbs aria_current: "page" %>
```

This will generate the following HTML (indented for readability):

```html
<div class="breadcrumbs">
  <a href="/">Home</a> &rsaquo;
  <a href="/issues">All issues</a> &rsaquo;
  <span class="current" aria-current="page">My Issue</span>
</div>
```

## Documentation

* [Full documentation](https://rubydoc.info/gems/gretel)
* [Changelog](https://github.com/kzkn/gretel/blob/main/CHANGELOG.md)
* [Tutorial on using Gretel](https://www.sitepoint.com/breadcrumbs-rails-gretel/) (Sitepoint)

## Versioning

Follows [semantic versioning](https://semver.org/).

## Contributing

You are very welcome to help improve Gretel if you have suggestions for features that other people can use.

To contribute:

1. Fork the project
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Make your changes
4. Add/Fix tests
5. Prepare database for testing: `cd spec/dummy; rake db:migrate; rake db:test:prepare; cd ../..`
6. Run `rake` to make sure all tests pass
7. Be sure to check in the changes to `coverage/coverage.txt`
8. Commit your changes (`git commit -am 'Add new feature'`)
9. Push to the branch (`git push origin my-new-feature`)
10. Create new pull request

Thanks.

## History

This repository had been a fork of [lassebunk/gretel](https://github.com/lassebunk/gretel) for a long time. However, due to some reasons, the maintenance of this repository was stopped and the official repository of gretel was transferred to [WilHall/gretel](https://github.com/WilHall/gretel), which is the fork of lassebunk/gretel. WilHall/gretel was then transferred to kzkn/gretel, where it continues to be maintained. During this time, kzkn/gretel was a fork of lassebunk/gretel, so `lassebunk/gretel:master` was selected by default when a pull request was made. This caused unnecessary confusion for contributors to gretel.

As mentioned earlier, lassebunk/gretel is no longer maintained. I have decided to detach the fork for the future of gretel, with all due respect to [@lassebunk](https://github.com/lassebunk) for creating gretel.

## Contributors

Gretel was created by [@lassebunk](https://github.com/lassebunk) and was maintained by [@WilHall](https://github.com/WilHall).
And it is maintained by [@kzkn](https://github.com/kzkn).

[See the list of contributors](https://github.com/kzkn/gretel/graphs/contributors)

## And then

<img src="http://i.imgur.com/u4Wbt4n.png" alt="After using Gretel, you'll be like this" />

Have fun!

Copyright (c) 2010-2020 [Lasse Bunk](http://lassebunk.dk), released under the MIT license