Skip to content

Commit

Permalink
The Navbar links should be dynamically configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoyne committed Nov 20, 2014
1 parent 75ec72c commit e50eeb3
Show file tree
Hide file tree
Showing 13 changed files with 163 additions and 104 deletions.
33 changes: 28 additions & 5 deletions app/helpers/blacklight/blacklight_helper_behavior.rb
Expand Up @@ -93,7 +93,17 @@ def render_search_bar
end

##
# Render "docuemnt actions" area for search results view
# Render "document actions" area for navigation header
# (normally renders "Saved Searches", "History", "Bookmarks")
#
# @param [Hash] options
# @return [String]
def render_nav_actions(options={}, &block)
render_filtered_partials(blacklight_config.navbar.partials, options, &block)
end

##
# Render "document actions" area for search results view
# (normally renders next to title in the list view)
#
# @param [SolrDocument] document
Expand All @@ -102,13 +112,20 @@ def render_search_bar
# @return [String]
def render_index_doc_actions(document, options={})
wrapping_class = options.delete(:wrapping_class) || "index-document-functions"
rendered = render_filtered_partials(blacklight_config.index.document_actions, { document: document }.merge(options))
content_tag("div", rendered, class: wrapping_class)
end

def render_filtered_partials(partials, options={}, &block)
content = []
index_tool_partials.select { |_, config| evaluate_if_unless_configuration config, @document }.each do |_, config|
content << render(config.partial, { document: document }.merge(options))
partials.select { |_, config| evaluate_if_unless_configuration config, options }.each do |_, config|
if block_given?
yield render(config.partial, options)
else
content << render(config.partial, options)
end
end

content_tag("div", safe_join(content, "\n"), class: wrapping_class)
safe_join(content, "\n") unless block_given?
end

##
Expand Down Expand Up @@ -575,6 +592,12 @@ def render_bookmarks_control?
has_user_authentication_provider? and current_or_guest_user.present?
end

##
# Determine whether to render the saved searches link
def render_saved_searches?
has_user_authentication_provider? and current_user
end

##
# Returns a document presenter for the given document
def presenter(document)
Expand Down
17 changes: 2 additions & 15 deletions app/views/_user_util_links.html.erb
@@ -1,21 +1,8 @@
<div class="navbar-right">
<ul class="nav navbar-nav">
<% if render_bookmarks_control? %>
<li>
<%= link_to bookmarks_path, id:'bookmarks_nav' do %>
<%= t('blacklight.header_links.bookmarks') %>
(<span data-role='bookmark-counter'><%= current_or_guest_user.bookmarks.count %></span>)
<% end %>
</li>
<% end %>
<% if has_user_authentication_provider? and current_user %>
<li>
<%= link_to t('blacklight.header_links.saved_searches'), saved_searches_path %>
</li>
<%= render_nav_actions do |action|%>
<li><%= action %></li>
<% end %>
<li>
<%= link_to t('blacklight.header_links.search_history'), search_history_path %>
</li>
</ul>

<% if has_user_authentication_provider? %>
Expand Down
4 changes: 4 additions & 0 deletions app/views/blacklight/nav/_bookmark.html.erb
@@ -0,0 +1,4 @@
<%= link_to bookmarks_path, id:'bookmarks_nav' do %>
<%= t('blacklight.header_links.bookmarks') %>
(<span data-role='bookmark-counter'><%= current_or_guest_user.bookmarks.count %></span>)
<% end %>
1 change: 1 addition & 0 deletions app/views/blacklight/nav/_saved_searches.html.erb
@@ -0,0 +1 @@
<%= link_to t('blacklight.header_links.saved_searches'), saved_searches_path %>
1 change: 1 addition & 0 deletions app/views/blacklight/nav/_search_history.html.erb
@@ -0,0 +1 @@
<%= link_to t('blacklight.header_links.search_history'), search_history_path %>
28 changes: 7 additions & 21 deletions lib/blacklight/catalog.rb
@@ -1,15 +1,16 @@
# -*- encoding : utf-8 -*-
module Blacklight::Catalog
extend ActiveSupport::Concern
extend ActiveSupport::Autoload

require 'blacklight/catalog/document_actions'
require 'blacklight/catalog/index_tools'
require 'blacklight/catalog/search_context'
eager_autoload do
autoload :ComponentConfiguration
autoload :DocumentActions
autoload :SearchContext
end

include Blacklight::Base

include Blacklight::Catalog::DocumentActions
include Blacklight::Catalog::IndexTools
include Blacklight::Catalog::ComponentConfiguration

SearchHistoryWindow = 100 # how many searches to save in session history

Expand All @@ -24,21 +25,6 @@ module Blacklight::Catalog
rescue_from Blacklight::Exceptions::InvalidSolrID, :with => :invalid_solr_id_error

record_search_parameters

# provided by Blacklight::Catalog::DocumentActions
add_document_action(:bookmark, partial: 'catalog/bookmark_control', if: :render_bookmarks_control?)
add_document_action(:refworks, if: Proc.new { |_, config, options|
options[:document] && options[:document].respond_to?(:export_formats) && options[:document].export_formats.keys.include?( :refworks_marc_txt )} )

add_document_action(:endnote, if: Proc.new { |_, config, options| options[:document] && options[:document].respond_to?(:export_formats) && options[:document].export_formats.keys.include?( :endnote )} )
add_document_action(:email, callback: :email_action, validator: :validate_email_params)
add_document_action(:sms, callback: :sms_action, validator: :validate_sms_params)
add_document_action(:citation)
add_document_action(:librarian_view, if: Proc.new { |ctx, config, options| ctx.respond_to? :librarian_view_catalog_path and options[:document] && options[:document].respond_to?(:to_marc) })

# provided by Blacklight::Catalog::IndexTools
add_index_tools_partial(:bookmark, partial: 'bookmark_control', if: :render_bookmarks_control?)

end

# get search results from the solr index
Expand Down
51 changes: 51 additions & 0 deletions lib/blacklight/catalog/component_configuration.rb
@@ -0,0 +1,51 @@
module Blacklight
module Catalog::ComponentConfiguration
extend ActiveSupport::Concern
include Blacklight::Catalog::DocumentActions

included do
# provided by Blacklight::Catalog::DocumentActions
add_document_action(:bookmark, partial: 'catalog/bookmark_control', if: :render_bookmarks_control?)
add_document_action(:refworks, if: Proc.new { |_, config, options|
options[:document] && options[:document].respond_to?(:export_formats) && options[:document].export_formats.keys.include?( :refworks_marc_txt )} )
add_document_action(:endnote, if: Proc.new { |_, config, options| options[:document] && options[:document].respond_to?(:export_formats) && options[:document].export_formats.keys.include?( :endnote )} )
add_document_action(:email, callback: :email_action, validator: :validate_email_params)
add_document_action(:sms, callback: :sms_action, validator: :validate_sms_params)
add_document_action(:citation)
add_document_action(:librarian_view, if: Proc.new { |ctx, config, options| ctx.respond_to? :librarian_view_catalog_path and options[:document] && options[:document].respond_to?(:to_marc) })

add_index_tools_partial(:bookmark, partial: 'bookmark_control', if: :render_bookmarks_control?)

add_nav_action(:bookmark, partial: 'blacklight/nav/bookmark', if: :render_bookmarks_control?)
add_nav_action(:saved_searches, partial: 'blacklight/nav/saved_searches', if: :render_saved_searches?)
add_nav_action(:search_history, partial: 'blacklight/nav/search_history')
end

module ClassMethods

##
# Add a partial to the tools for each document in the search results.
# @param partial [String] the name of the document partial
# @param opts [Hash]
# @option opts [Symbol,Proc] :if render this action if the method identified by the symbol or the proc evaluates to true.
# The proc will receive the action configuration and the document or documents for the action.
# @option opts [Symbol,Proc] :unless render this action unless the method identified by the symbol or the proc evaluates to true
# The proc will receive the action configuration and the document or documents for the action.
def add_index_tools_partial name, opts = {}
blacklight_config.add_index_tools_partial(name, opts)
end

##
# Add a partial to the header navbar
# @param partial [String] the name of the document partial
# @param opts [Hash]
# @option opts [Symbol,Proc] :if render this action if the method identified by the symbol or the proc evaluates to true.
# The proc will receive the action configuration and the document or documents for the action.
# @option opts [Symbol,Proc] :unless render this action unless the method identified by the symbol or the proc evaluates to true
# The proc will receive the action configuration and the document or documents for the action.
def add_nav_action name, opts = {}
blacklight_config.add_nav_action(name, opts)
end
end
end
end
39 changes: 0 additions & 39 deletions lib/blacklight/catalog/index_tools.rb

This file was deleted.

39 changes: 39 additions & 0 deletions lib/blacklight/configuration.rb
Expand Up @@ -57,6 +57,7 @@ def default_values
:display_type_field => 'format',
# partials to render for each document(see #render_document_partials)
:partials => [:index_header, :thumbnail, :index],
:document_actions => {},
# what field, if any, to use to render grouped results
:group => false,
# additional response formats for search results
Expand All @@ -72,6 +73,7 @@ def default_values
# partials to render for each document(see #render_document_partials)
partials: [:show_header, :show]
),
:navbar => OpenStructWithHashAccess.new(partials: { }),
# Configurations for specific types of index views
:view => NestedOpenStructWithHashAccess.new(ViewConfig, 'list'),
# Maxiumum number of spelling suggestions to offer
Expand Down Expand Up @@ -248,5 +250,42 @@ def view_config view_type
self.index.merge view.fetch(view_type, {})
end
end

##
# Add a partial to the tools for each document in the search results.
# @param partial [String] the name of the document partial
# @param opts [Hash]
# @option opts [Symbol,Proc] :if render this action if the method identified by the symbol or the proc evaluates to true.
# The proc will receive the action configuration and the document or documents for the action.
# @option opts [Symbol,Proc] :unless render this action unless the method identified by the symbol or the proc evaluates to true
# The proc will receive the action configuration and the document or documents for the action.
def add_index_tools_partial(name, opts = {})
add_action(index.document_actions, name, opts)
end

##
# Add a partial to the header navbar
# @param partial [String] the name of the document partial
# @param opts [Hash]
# @option opts [Symbol,Proc] :if render this action if the method identified by the symbol or the proc evaluates to true.
# The proc will receive the action configuration and the document or documents for the action.
# @option opts [Symbol,Proc] :unless render this action unless the method identified by the symbol or the proc evaluates to true
# The proc will receive the action configuration and the document or documents for the action.
def add_nav_action name, opts = {}
add_action(navbar.partials, name, opts)
end

private

def add_action config_hash, name, opts
config = Blacklight::Configuration::ToolConfig.new opts
config.name = name

if block_given?
yield config
end

config_hash[name] = config
end
end
end
8 changes: 4 additions & 4 deletions spec/controllers/alternate_controller_spec.rb
Expand Up @@ -3,16 +3,16 @@
describe AlternateController do
describe "add_index_tools_partial" do
it "should inherit tools from CatalogController" do
expect(AlternateController.index_tool_partials).to have_key(:bookmark)
expect(AlternateController.blacklight_config.index.document_actions).to have_key(:bookmark)
end

context "when deleting partials from the AlternateController" do
before do
AlternateController.index_tool_partials.delete(:bookmark)
AlternateController.blacklight_config.index.document_actions.delete(:bookmark)
end
it "should not affect the CatalogController" do
expect(AlternateController.index_tool_partials).to be_empty
expect(CatalogController.index_tool_partials).to have_key(:bookmark)
expect(AlternateController.blacklight_config.index.document_actions).to be_empty
expect(CatalogController.blacklight_config.index.document_actions).to have_key(:bookmark)
end
end
end
Expand Down
32 changes: 20 additions & 12 deletions spec/helpers/blacklight_helper_spec.rb
Expand Up @@ -111,40 +111,48 @@ def mock_document_app_helper_url *args
end

describe "with a config" do
let :index_tool_partials do
{ bookmark: Blacklight::Configuration::ToolConfig.new(partial: 'catalog/bookmark_control', if: :render_bookmarks_control?) }
end

let :document_actions do
{ bookmark: Blacklight::Configuration::ToolConfig.new(partial: 'catalog/bookmark_control', if: :render_bookmarks_control?) }
end

before do
@config = Blacklight::Configuration.new.configure do |config|
let(:config) do
Blacklight::Configuration.new.configure do |config|
config.index.title_field = 'title_display'
config.index.display_type_field = 'format'
end
end

@document = SolrDocument.new('title_display' => "A Fake Document", 'id'=>'8')
allow(helper).to receive(:blacklight_config).and_return(@config)
let(:document) { SolrDocument.new('title_display' => "A Fake Document", 'id'=>'8') }

before do
config.add_index_tools_partial(:bookmark, partial: 'catalog/bookmark_control', if: :render_bookmarks_control?)
config.add_nav_action(:bookmark, partial: 'blacklight/nav/bookmark', if: :render_bookmarks_control?)
allow(helper).to receive(:blacklight_config).and_return(config)
allow(helper).to receive(:has_user_authentication_provider?).and_return(true)
allow(helper).to receive(:current_or_guest_user).and_return(User.new)
allow(helper).to receive_messages(current_bookmarks: [])

allow(helper).to receive(:index_tool_partials).and_return index_tool_partials
allow(helper).to receive(:document_actions).and_return document_actions
end

describe "render_nav_actions" do
it "should render partials" do
buff = ''
helper.render_nav_actions { |item| buff << "<foo>#{item}</foo>" }
expect(buff).to eq("<foo><a href=\"/bookmarks\" id=\"bookmarks_nav\">\n Bookmarks\n(<span data-role='bookmark-counter'>0</span>)\n</a></foo>")
end
end

describe "render_index_doc_actions" do
it "should render partials" do
response = helper.render_index_doc_actions(@document)
response = helper.render_index_doc_actions(document)
expect(response).to have_selector(".bookmark_toggle")
end
end

describe "render_show_doc_actions" do
it "should render partials" do
buff = ''
helper.render_show_doc_actions(@document) do |name, val|
helper.render_show_doc_actions(document) do |name, val|
buff << val
end
expect(buff).to have_selector(".bookmark_toggle")
Expand Down
9 changes: 6 additions & 3 deletions spec/views/_user_util_links.html.erb_spec.rb
Expand Up @@ -3,15 +3,18 @@
describe "_user_util_links" do

let :blacklight_config do
Blacklight::Configuration.new
Blacklight::Configuration.new.configure do |config|
config.navbar.partials = { bookmark: Blacklight::Configuration::ToolConfig.new(partial: 'blacklight/nav/bookmark', if: :render_bookmarks_control?) }
end

end

it "should render the correct bookmark count" do
count = rand(99)
allow(view).to receive(:blacklight_config).and_return(blacklight_config)
allow(view).to receive(:render_bookmarks_control?).and_return true
allow(view).to receive(:has_user_authentication_provider?). and_return false
allow(view).to receive_message_chain(:current_or_guest_user, :bookmarks, :count).and_return(count)
allow(view).to receive(:has_user_authentication_provider?).and_return false
allow(view).to receive_message_chain(:current_or_guest_user, :bookmarks, :count).and_return(count)
render :partial => "user_util_links"
expect(rendered).to have_selector('#bookmarks_nav span[data-role=bookmark-counter]', text: "#{count}")
end
Expand Down

0 comments on commit e50eeb3

Please sign in to comment.