:toc: macro :toclevels: 5 :figure-caption!: = Navigator [link=http://badge.fury.io/rb/navigator] image::https://badge.fury.io/rb/navigator.svg[Gem Version] [link=https://circleci.com/gh/bkuhlmann/navigator] image::https://circleci.com/gh/bkuhlmann/navigator.svg?style=svg[Circle CI Status] Enhances Rails with a DSL for menu navigation. toc::[] == 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 . link:https://www.ruby-lang.org[Ruby] . link:https://rubyonrails.org[Ruby on Rails] == Setup === Production To install, run: .... gem install navigator .... Add the following to your Gemfile: .... gem "navigator" .... === Development To contribute, run: .... git clone https://github.com/bkuhlmann/navigator.git cd navigator bin/setup .... You can also use the IRB console for direct access to all objects: .... bin/console .... == Usage The following are examples using the navigation view helper: === Unordered List (simple) Code: [source,ruby] ---- navigation do item "Dashboard", "/dashboard" item "News", "/posts" end ---- Result: [source,html] ---- ---- === Unordered List (with attributes) Code: [source,ruby] ---- navigation "ul", attributes: {class: "nav"} do item "Dashboard", "/dashboard", item_attributes: {class: "active"} item "News", "/posts" end ---- Result: [source,html] ---- ---- === Unordered List (with multiple data attributes) Code: [source,ruby] ---- navigation do item "Home", "/home", item_attributes: {data: {id: 1, type: "public"}} end ---- Result: [source,html] ---- ---- _TIP: Nested data– attributes can be applied to any menu item in the same manner as Rails view helpers._ === Nav (with links) Code: [source,ruby] ---- navigation "nav" do a "Dashboard", attributes: {href: "/dashboard"} a "News", attributes: {href: "/posts"} end ---- Result: [source,html] ---- ---- === Foundation Menu Code: [source,ruby] ---- 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: [source,html] ---- ---- === Bootstrap Dropdown Code: [source,ruby] ---- 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: [source,html] ---- ---- === 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: [source,ruby] ---- navigation "nav", activator: activator do a "Home", attributes: {href: home_path} end ---- ...but can be written as: [source,ruby] ---- navigation "nav", activator: activator do link "Home", home_path end ---- When building images, the default is: [source,ruby] ---- navigation "nav", activator: activator do img attributes: {src: "https://placehold.it/50x50", alt: "Example"} end ---- ..but can be written as: [source,ruby] ---- navigation "nav", activator: activator do image "https://placehold.it/50x50", "Example" end ---- When building menu items, the default is: [source,ruby] ---- navigation "nav", activator: activator do li do a "Home", attributes: {href: home_path} end end ---- ...but can be written as: [source,ruby] ---- 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. Code: [source,ruby] ---- activator = Navigator::TagActivator.new search_value: request.env["PATH_INFO"] navigation "nav", activator: activator do link "Home", home_path link "About", about_path end ---- Result: [source,html] ---- ---- 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. Code: [source,ruby] ---- 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 ---- Result: [source,html] ---- ---- Lastly, the search value can be a _regular expression_ to make things easier when dealing with complicated routes, sub- menus, etc. Code: [source,ruby] ---- 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 ---- Result: [source,html] ---- ---- 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: [source,bash] ---- bundle exec rake ---- To test the dummy application, run: [source,bash] ---- cd spec/dummy bin/rails server ---- == Versioning Read link:https://semver.org[Semantic Versioning] 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 link:CODE_OF_CONDUCT.adoc[CODE OF CONDUCT]. By participating in this project you agree to abide by its terms. == Contributions Read link:CONTRIBUTING.adoc[CONTRIBUTING] for details. == License Read link:LICENSE.adoc[LICENSE] for details. == History Read link:CHANGES.adoc[CHANGES] for details. == Credits Engineered by link:https://www.alchemists.io/team/brooke_kuhlmann[Brooke Kuhlmann].