Last active
October 17, 2018 18:24
-
-
Save itay-grudev/bdbdbb8d1b9e92daaf50 to your computer and use it in GitHub Desktop.
Rails Current Page Helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module PathHelper | |
## | |
# Checks whether you are on the specified page | |
# | |
# @param matchers A comma separated list of matchers. | |
# @param returnval Return value if the page matches or nil. Defaults to true. | |
# @return [mixed] returnval (usually truthy) on success or nil on failure. | |
# | |
# @example Check if you are on Article#show | |
# page?( 'article#show' ) | |
# @example Check if on Article#show or News#index | |
# page?( 'article#show, news#index' ) | |
# @example Check if you are in the article controller under the admin scope | |
# page?( 'admin/articles#index' ) | |
# @example Check if you are in the article controller and return `'active'` | |
# page?( 'article', 'active' ) | |
# @example Check aditional parameters and return `'active'` (for use as class) | |
# page?( "article#show?slug=#{@article.slug}", 'active' ) | |
# | |
# ==== Matchers | |
# Matchers are a comma separated list of rules specified with the following | |
# format. Whitespace between matchers is allowed. | |
# controller#action?param1=value¶m2=value | |
# Values should be URL encoded if they contain special characters. | |
# | |
# | |
# ==== LICENSE | |
# Copyright (c) 2015-2017 Itay Grudev <itay[]grudev.com> | |
# Published under the terms of The MIT License (MIT) | |
# | |
def page?( matchers, returnval = true ) | |
matchers.split( ',' ).each do |matcher| | |
# Split the routing part and the parameters part | |
routing, params = matcher.strip.split( '?' ) | |
# Split the controller from the action | |
controller, action = routing.strip.split( '#' ) unless routing.blank? | |
# Split multiple parameters | |
params = params.strip.split( '&' ) unless params.blank? | |
next if ! controller.blank? and request.params[:controller] != controller | |
next if ! action.blank? and request.params[:action] != action | |
# Verify parameters | |
matches = true | |
params.try( :each ) do |param| | |
# Split parameter key from value | |
key, value = param.strip.split( '=' ) | |
if request.params[key] != URI.unescape( value ) | |
matches = false and break | |
end | |
end | |
next unless matches | |
return returnval | |
end | |
nil | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/ Checking if you are on a given page | |
- if page?( 'article#show' ) | |
/ ... | |
- if page?( 'article#show, news#index' ) | |
/ ... | |
/ Marking links as active | |
ul | |
li class=[ page?( 'blog', 'active' ) ] | |
= link_to 'Blog', blog_path | |
/ Usage with namespaces | |
ul | |
li class=[ page?( 'admin/articles#index', 'active' ) ] | |
= link_to 'Pages', admin_pages_path | |
/ Checking additional parameters | |
/ Assuming you have a path like: get '/article/:slug' => 'article#show' | |
ul | |
- @pages.each do |page| | |
li class=[ page?( "article#show?slug=#{@article.slug}", 'active' ) ] | |
= link_to @page.title, page_path( @page.slug ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rails_helper' | |
RSpec.describe PathHelper, type: :helper do | |
describe 'page?' do | |
before { | |
@request = double( 'request' ) | |
allow( helper ).to receive( :request ).and_return( @request ) | |
} | |
# This adds additional test with two matchers where the first is invalid | |
[ '', 'INVALID#INVALID?invalid=invalid&invalid=invalid,' ].each do |prefix| | |
context "with#{'out' if prefix.blank?} prefix" do | |
context 'on matching page' do | |
before { | |
allow( @request ).to receive( :params ).and_return( | |
controller: ( @controller = SecureRandom.hex ), | |
action: ( @action = SecureRandom.hex ) | |
) | |
} | |
it 'matches just a controller' do | |
expect( | |
helper.page?( prefix + "#{@controller}" ) | |
).to eq true | |
end | |
it 'matches just an action' do | |
expect( | |
helper.page?( prefix + "##{@action}" ) | |
).to eq true | |
end | |
it 'matches just a controller and an action' do | |
expect( | |
helper.page?( prefix + "#{@controller}##{@action}" ) | |
).to eq true | |
end | |
end | |
context 'on controller mismatch' do | |
before { | |
allow( @request ).to receive( :params ).and_return( | |
controller: '!' + ( @controller = SecureRandom.hex ), | |
action: ( @action = SecureRandom.hex ) | |
) | |
} | |
it 'matches just a controller' do | |
expect( | |
helper.page?( prefix + "#{@controller}" ) | |
).to be_nil | |
end | |
it 'matches just an action' do | |
expect( | |
helper.page?( prefix + "##{@action}" ) | |
).to eq true | |
end | |
it 'matches just a controller and an action' do | |
expect( | |
helper.page?( prefix + "#{@controller}##{@action}" ) | |
).to be_nil | |
end | |
end | |
context 'on action mismatch' do | |
before { | |
allow( @request ).to receive( :params ).and_return( | |
controller: ( @controller = SecureRandom.hex ), | |
action: '!' + ( @action = SecureRandom.hex ) | |
) | |
} | |
it 'matches just a controller' do | |
expect( | |
helper.page?( prefix + "#{@controller}" ) | |
).to eq true | |
end | |
it 'matches just an action' do | |
expect( | |
helper.page?( prefix + "##{@action}" ) | |
).to be_nil | |
end | |
it 'matches just a controller and an action' do | |
expect( | |
helper.page?( prefix + "#{@controller}##{@action}" ) | |
).to be_nil | |
end | |
end | |
context 'with additional params specified' do | |
it 'should return true on matching page' do | |
allow( @request ).to receive( :params ).and_return( | |
controller: ( @controller = SecureRandom.hex ), | |
action: ( @action = SecureRandom.hex ), | |
( param1 = SecureRandom.hex ) => ( value1 = SecureRandom.hex ), | |
( param2 = SecureRandom.hex ) => ( value2 = SecureRandom.hex ) | |
) | |
expect( | |
helper.page?( | |
"#{@controller}##{@action}?#{param1}=#{value1}&#{param2}=#{value2}" | |
) | |
).to eq true | |
end | |
it 'should return nil if the page doesn\'t match' do | |
allow( @request ).to receive( :params ).and_return( | |
controller: ( @controller = SecureRandom.hex ), | |
action: ( @action = SecureRandom.hex ), | |
( param1 = SecureRandom.hex ) => ( value1 = SecureRandom.hex ), | |
( param2 = SecureRandom.hex ) => ( value2 = SecureRandom.hex ) | |
) | |
expect( | |
helper.page?( | |
"#{@controller}##{@action}?#{param1}=#{value1}&#{param2}=!#{value2}" | |
) | |
).to be_nil | |
end | |
end | |
context 'with return value specified' do | |
it 'should return the specified value on matching page' do | |
allow( @request ).to receive( :params ).and_return( | |
controller: ( @controller = SecureRandom.hex ), | |
action: ( @action = SecureRandom.hex ) | |
) | |
expect( | |
helper.page?( | |
"#{@controller}##{@action}", | |
( val = SecureRandom.hex ) | |
) | |
).to eq val | |
end | |
it 'should return nil if the page doesn\'t match' do | |
allow( @request ).to receive( :params ).and_return( | |
controller: ( '!' + @controller = SecureRandom.hex ), | |
action: ( '!' + @action = SecureRandom.hex ) | |
) | |
expect( | |
helper.page?( | |
"#{@controller}##{@action}", | |
( val = SecureRandom.hex ) | |
) | |
).to be_nil | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment