# Navigator
[](http://badge.fury.io/rb/navigator)
[](https://codeclimate.com/github/bkuhlmann/navigator/maintainability)
[](https://codeclimate.com/github/bkuhlmann/navigator/test_coverage)
[](https://circleci.com/gh/bkuhlmann/navigator)
Enhances Rails with a DSL for menu navigation.
## Table of Contents
- [Features](#features)
- [Requirements](#requirements)
- [Setup](#setup)
- [Usage](#usage)
- [Unordered List (simple)](#unordered-list-simple)
- [Unordered List (with attributes)](#unordered-list-with-attributes)
- [Unordered List (with multiple data attributes)](#unordered-list-with-multiple-data-attributes)
- [Nav (with links)](#nav-with-links)
- [Foundation Menu](#foundation-menu)
- [Bootstrap Dropdown](#bootstrap-dropdown)
- [Menu Helpers](#menu-helpers)
- [Customization](#customization)
- [Tests](#tests)
- [Versioning](#versioning)
- [Code of Conduct](#code-of-conduct)
- [Contributions](#contributions)
- [License](#license)
- [History](#history)
- [Credits](#credits)
## Features
- Provides a DSL for building navigation menus.
- Supports auto-detection/highlighting of active menu items based on current path (customizable for
non-path usage too).
- Supports sub-menus, nested tags, HTML attributes, etc.
- Supports the following HTML tags:
- div
- section
- header
- h1 - h6
- nav
- ul
- li
- a
- img
- b
- em
- s
- small
- span
- strong
- sub
- sup
- form
- label
- select
- option
- input
- button
- Provides `link`, `image`, and `item` convenience methods for succinct ways to build commonly used
menu elements.
## Requirements
1. [Ruby 2.6.x](https://www.ruby-lang.org).
1. [Ruby on Rails 5.x.x](http://rubyonrails.org).
## Setup
Type the following to install:
gem install navigator
Add the following to your Gemfile:
gem "navigator"
## Usage
The following are examples using the navigation view helper:
### Unordered List (simple)
Code:
navigation do
item "Dashboard", "/dashboard"
item "News", "/posts"
end
Result:
*TIP: Nested data-- attributes can be applied to any menu item in the same manner as Rails view
helpers.*
### Nav (with links)
Code:
navigation "nav" do
a "Dashboard", attributes: {href: "/dashboard"}
a "News", attributes: {href: "/posts"}
end
Result:
### Foundation Menu
Code:
navigation "nav", attributes: {class: "top-bar", "data-topbar" => nil} do
ul attributes: {class: "title-area"} do
li attributes: {class: "name"} do
h1 do
a "Demo", attributes: {href: "/home"}
end
end
end
section attributes: {class: "top-bar-section"} do
ul attributes: {class: "left"} do
item "Home", "/"
item "About", "/about"
end
ul attributes: {class: "right"} do
item "v1.0.0", '#'
end
ul attributes: {class: "right"} do
item "Login", "/login", link_attributes: {class: "button tiny round"}
end
end
end
Result:
### Bootstrap Dropdown
Code:
navigation "nav" do
item "Dashboard", admin_dashboard_path
li attributes: {class: "dropdown"} do
a "Manage", attributes: {href: "#", class: "dropdown-toggle", "data-toggle" => "dropdown"} do
b attributes: {class: "caret"}
end
ul attributes: {class: "dropdown-menu"} do
item "Dashboard", admin_dashboard_path
item "Users", admin_users_path
end
end
end
Result:
### Menu Helpers
There are several convenience methods, in addition to the standard HTML tags, that can make for
shorter lines of code. The following describes each:
When building links, the default is:
navigation "nav", activator: activator do
a "Home", attributes: {href: home_path}
end
...but can be written as:
navigation "nav", activator: activator do
link "Home", home_path
end
When building images, the default is:
navigation "nav", activator: activator do
img attributes: {src: "https://placehold.it/50x50", alt: "Example"}
end
...but can be written as:
navigation "nav", activator: activator do
image "https://placehold.it/50x50", "Example"
end
When building menu items, the default is:
navigation "nav", activator: activator do
li do
a "Home", attributes: {href: home_path}
end
end
...but can be written as:
navigation "nav", activator: activator do
item "Home", "/dashboard"
end
These are just a few, simple, examples of what can be achieved. See the specs for additional usage
and customization.
## Customization
The `navigation` view helper can accept an optional `Navigator::TagActivator` instance. Example:
# Code
activator = Navigator::TagActivator.new search_value: request.env["PATH_INFO"]
navigation "nav", activator: activator do
link "Home", home_path
link "About", about_path
end
This is the default behavior for all navigation menus and is how menu items automaticaly get the
"active" class when the item URL (in this case "/home") matches the `request.env[“PATH_INFO"]` to
indicate current page/active tab.
`Navigator::TagActivator` instances can be configured as follows:
- search_key = Optional. The HTML tag attribute to search for. Default: :href.
- search_value = Required. The value to match against the search_key value in order to update the
value of the target_key. Default: nil.
- target_key = Optional. The HTML tag attribute key value to update when the search_value and
search_key value match. Default: :class.
- target_value = Optional. The value to be applied to the target_key value. If no value exists, then
the value is added. Otherwise, if a value exists then the value is appended to the existing value.
Default: "active".
This customization allows for more sophisticated detection/updating of active HTML tags. For
example, the example code (above) could be rewritten to use `data-*` attributes and customized
styles as follows:
# Code
activator = Navigator::TagActivator.new search_key: "data-id",
search_value: "123",
target_key: "data-style"
target_value: "current"
navigation "nav", activator: activator do
link "Home", home_path, attributes: {data: {id: "123", data-style="info"}}
link "About", about_path attributes: {data: {id: "789"}}
end
Lastly, the search value can be a *regular expression* to make things easier when dealing with
complicated routes, sub- menus, etc. Example:
# Code
profile_activator = Navigator::TagActivator.new search_value: /^profile.+/
navigation do
item "Dashboard", dashboard_path
li activator: profile_activator do
link "Profile", '#'
ul do
item "Addresses", profile_addresses_path
item "Emails", profile_emails_path
end
end
end
Assuming either the `Addresses` or `Emails` menu item was clicked, the `Profile` menu item would be
active due to the regular expression (i.e. `/^profile.+/`) matching one of the the `profile/*`
paths.
## Tests
To test, run:
bundle exec rake
To test the dummy application, run:
cd spec/dummy
bin/rails server
## Versioning
Read [Semantic Versioning](https://semver.org) for details. Briefly, it means:
- Major (X.y.z) - Incremented for any backwards incompatible public API changes.
- Minor (x.Y.z) - Incremented for new, backwards compatible, public API enhancements/fixes.
- Patch (x.y.Z) - Incremented for small, backwards compatible, bug fixes.
## Code of Conduct
Please note that this project is released with a [CODE OF CONDUCT](CODE_OF_CONDUCT.md). By
participating in this project you agree to abide by its terms.
## Contributions
Read [CONTRIBUTING](CONTRIBUTING.md) for details.
## License
Copyright 2012 [Alchemists](https://www.alchemists.io).
Read [LICENSE](LICENSE.md) for details.
## History
Read [CHANGES](CHANGES.md) for details.
Built with [Gemsmith](https://github.com/bkuhlmann/gemsmith).
## Credits
Developed by [Brooke Kuhlmann](https://www.alchemists.io) at
[Alchemists](https://www.alchemists.io).