Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bkuhlmann/navigator
A Rails domain specific language for menu navigation.
https://github.com/bkuhlmann/navigator
dsl menu-navigation
Last synced: about 2 months ago
JSON representation
A Rails domain specific language for menu navigation.
- Host: GitHub
- URL: https://github.com/bkuhlmann/navigator
- Owner: bkuhlmann
- License: other
- Created: 2012-02-04T22:54:56.000Z (over 12 years ago)
- Default Branch: main
- Last Pushed: 2024-07-23T00:05:23.000Z (about 2 months ago)
- Last Synced: 2024-07-23T03:19:35.438Z (about 2 months ago)
- Topics: dsl, menu-navigation
- Language: Ruby
- Homepage: https://alchemists.io/projects/navigator
- Size: 742 KB
- Stars: 15
- Watchers: 4
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.adoc
- Funding: .github/FUNDING.yml
- License: LICENSE.adoc
- Citation: CITATION.cff
Awesome Lists containing this project
README
:toc: macro
:toclevels: 5
:figure-caption!:= Navigator
Navigator is a Rails Engine that provides a domain specific language for menu navigation. Great for
situations in which you need dynamic, server-side, rendering of site navigation menus complete with
active page highlighting. You can also style your navigation menus with plain CSS or any CSS
framework of your choice.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
To install, run:
....
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:
[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 automatically 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.
== Development
To contribute, run:
[source,bash]
----
git clone https://github.com/bkuhlmann/navigator
cd navigator
bin/setup
----
You can also use the IRB console for direct access to all objects:
[source,bash]
----
bin/console
----
== Tests
To test, run:
[source,bash]
----
bin/rake
----
To test the dummy application, run:
[source,bash]
----
cd spec/dummy
bin/rails server
----
== link:https://alchemists.io/policies/license[License]
== link:https://alchemists.io/policies/security[Security]
== link:https://alchemists.io/policies/code_of_conduct[Code of Conduct]
== link:https://alchemists.io/policies/contributions[Contributions]
== link:https://alchemists.io/projects/navigator/versions[Versions]
== link:https://alchemists.io/community[Community]
== Credits
* Built with link:https://alchemists.io/projects/gemsmith[Gemsmith].
* Engineered by link:https://alchemists.io/team/brooke_kuhlmann[Brooke Kuhlmann].