From 55cca59318c2f3ece5dbfc405119ee1aa20190ff Mon Sep 17 00:00:00 2001 From: John-Paul Teti Date: Tue, 8 Feb 2022 20:14:11 -0500 Subject: [PATCH] Configure Gem via a `.configure` block https://github.com/comfy/active_link_to/issues/65 If you wanted to use a standard class name for active status (for example in a CSS framework), this was previously not possible. * Implement a standard `.configure` block * Add tests --- README.md | 22 +++++++ lib/active_link_to.rb | 1 + lib/active_link_to/active_link_to.rb | 13 ++-- lib/active_link_to/configuration.rb | 25 ++++++++ test/active_link_to_test.rb | 94 ++++++++++++++++++++++++++++ 5 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 lib/active_link_to/configuration.rb diff --git a/README.md b/README.md index 7c1a7c9..4ce8854 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,28 @@ Here's a list of available options that can be used as the `:active` value * Hash -> { param_a: 1, param_b: 2 } ``` +## Configuration +Several of the options that can be set in a calling of the helper can also be set in an +initializer. For example, if you want to use `is-active` as the active class all the time, +create `config/initializers/active_link_to.rb` with: + +```ruby +ActiveLinkTo.configure do |config| + config.class_active = 'is-active' +end +``` + +The full list of configurable values is: + +- `class_active` +- `class_inactive` +- `active_disable` +- `wrap_tag` +- `wrap_class` + +Setting these values in configuration just changes the default -- setting them in a +use of the helper should always override the default, as you'd expect. + ## More Examples Most of the functionality of `active_link_to` depends on the current url. Specifically, `request.original_fullpath` value. We covered the basic example diff --git a/lib/active_link_to.rb b/lib/active_link_to.rb index 8fc1f6b..814444c 100644 --- a/lib/active_link_to.rb +++ b/lib/active_link_to.rb @@ -1,3 +1,4 @@ require 'addressable/uri' require 'active_link_to/active_link_to' +require 'active_link_to/configuration' require 'active_link_to/version' diff --git a/lib/active_link_to/active_link_to.rb b/lib/active_link_to/active_link_to.rb index a2790dc..8770ffa 100644 --- a/lib/active_link_to/active_link_to.rb +++ b/lib/active_link_to/active_link_to.rb @@ -1,5 +1,4 @@ module ActiveLinkTo - # Wrapper around link_to. Accepts following params: # :active => Boolean | Symbol | Regex | Controller/Action Pair # :class_active => String @@ -28,8 +27,8 @@ def active_link_to(*args, &block) css_class = link_options.delete(:class).to_s + ' ' - wrap_tag = active_options[:wrap_tag].present? ? active_options[:wrap_tag] : nil - wrap_class = active_options[:wrap_class].present? ? active_options[:wrap_class] + ' ' : '' + wrap_tag = active_options[:wrap_tag].present? ? active_options[:wrap_tag] : ActiveLinkTo.configuration.wrap_tag + wrap_class = active_options[:wrap_class].present? ? active_options[:wrap_class] + ' ' : ActiveLinkTo.configuration.wrap_class.dup if wrap_tag.present? wrap_class << active_link_to_class(url, active_options) @@ -42,7 +41,9 @@ def active_link_to(*args, &block) link_options[:class] = css_class if css_class.present? link_options['aria-current'] = 'page' if is_active_link?(url, active_options[:active]) - link = if active_options[:active_disable] === true && is_active_link?(url, active_options[:active]) + active_disable = active_options.member?(:active_disable) ? active_options[:active_disable] : ActiveLinkTo.configuration.active_disable + + link = if active_disable && is_active_link?(url, active_options[:active]) content_tag(:span, name, link_options) else link_to(name, url, link_options) @@ -57,9 +58,9 @@ def active_link_to(*args, &block) # def active_link_to_class(url, options = {}) if is_active_link?(url, options[:active]) - options[:class_active] || 'active' + options[:class_active] || ActiveLinkTo.configuration.class_active else - options[:class_inactive] || '' + options[:class_inactive] || ActiveLinkTo.configuration.class_inactive end end diff --git a/lib/active_link_to/configuration.rb b/lib/active_link_to/configuration.rb new file mode 100644 index 0000000..0562085 --- /dev/null +++ b/lib/active_link_to/configuration.rb @@ -0,0 +1,25 @@ +module ActiveLinkTo + class Configuration + attr_accessor :class_active, :class_inactive, :active_disable, :wrap_tag, :wrap_class + + def initialize + @class_active = 'active'.freeze + @class_inactive = ''.freeze + @active_disable = false + @wrap_tag = nil + @wrap_class = ''.freeze + end + end + + def self.configuration + @configuration ||= Configuration.new + end + + def self.configuration=(config) + @configuration = config + end + + def self.configure + yield configuration + end +end diff --git a/test/active_link_to_test.rb b/test/active_link_to_test.rb index c9a2632..0cf717a 100644 --- a/test/active_link_to_test.rb +++ b/test/active_link_to_test.rb @@ -1,6 +1,33 @@ require_relative 'test_helper' class ActiveLinkToTest < MiniTest::Test + def setup + reset_configuration + end + + def reset_configuration + ActiveLinkTo.configuration = ActiveLinkTo::Configuration.new + end + + def test_default_active_class + assert_equal 'active', ActiveLinkTo.configuration.class_active + end + + def test_default_inactive_class + assert_equal '', ActiveLinkTo.configuration.class_inactive + end + + def test_default_active_disable + refute ActiveLinkTo.configuration.active_disable + end + + def test_default_wrap_tag + assert_nil ActiveLinkTo.configuration.wrap_tag + end + + def test_default_wrap_class + assert_equal '', ActiveLinkTo.configuration.wrap_class + end def test_is_active_link_booleans_test assert is_active_link?('/', true) @@ -166,6 +193,17 @@ def test_active_link_to assert_html link, 'a[href="/other"]', 'label' end + def test_active_link_to_with_configured_alternative_class_active_value + ActiveLinkTo.configuration.class_active = 'is-active' + + set_path('/root') + link = active_link_to('label', '/root') + assert_html link, 'a.is-active[href="/root"]', 'label' + + link = active_link_to('label', '/other') + assert_html link, 'a[href="/other"]', 'label' + end + def test_active_link_to_with_existing_class set_path('/root') link = active_link_to('label', '/root', class: 'current') @@ -184,6 +222,29 @@ def test_active_link_to_with_custom_classes assert_html link, 'a.off[href="/other"]', 'label' end + def test_active_link_to_inactive_class_configuration + ActiveLinkTo.configuration.class_inactive = 'inactive' + + set_path('/root') + link = active_link_to('label', '/root') + assert_html link, 'a.active[href="/root"]', 'label' + + link = active_link_to('label', '/other') + assert_html link, 'a.inactive[href="/other"]', 'label' + end + + def test_active_link_to_with_custom_classes_overrides_configured_values + ActiveLinkTo.configuration.class_active = 'is-active' + ActiveLinkTo.configuration.class_inactive = 'is-inactive' + + set_path('/root') + link = active_link_to('label', '/root', class_active: 'on') + assert_html link, 'a.on[href="/root"]', 'label' + + link = active_link_to('label', '/other', class_inactive: 'off') + assert_html link, 'a.off[href="/other"]', 'label' + end + def test_active_link_to_with_wrap_tag set_path('/root') link = active_link_to('label', '/root', wrap_tag: :li) @@ -196,12 +257,45 @@ def test_active_link_to_with_wrap_tag assert_html link, 'li.active a.testing[href="/root"]', 'label' end + def test_active_link_to_with_wrap_tag_configuration_set + ActiveLinkTo.configuration.wrap_tag = :li + + set_path('/root') + link = active_link_to('label', '/root') + assert_html link, 'li.active a[href="/root"]', 'label' + + link = active_link_to('label', '/root', active_disable: true) + assert_html link, 'li.active span', 'label' + + link = active_link_to('label', '/root', class: 'testing') + assert_html link, 'li.active a.testing[href="/root"]', 'label' + end + def test_active_link_to_with_active_disable set_path('/root') link = active_link_to('label', '/root', active_disable: true) assert_html link, 'span.active', 'label' end + def test_active_link_to_with_active_disable_configuration + ActiveLinkTo.configuration.active_disable = true + + set_path('/root') + link = active_link_to('label', '/root') + assert_html link, 'span.active', 'label' + end + + def test_active_link_to_with_active_disable_configuration_override + ActiveLinkTo.configuration.active_disable = true + + set_path('/root') + link = active_link_to('label', '/root') + assert_html link, 'span.active', 'label' + + link = active_link_to('label', '/root', active_disable: false) + assert_html link, 'a.active', 'label' + end + def test_should_not_modify_passed_params set_path('/root') params = {class: 'testing', active: :inclusive}