-
Notifications
You must be signed in to change notification settings - Fork 256
Understanding Rails and Blacklight
In order to understand how Blacklight works, you should have some basic knowledge about how Ruby and Ruby on Rails works. In this section, we'll highlight the most important concepts for working with Blacklight.
Blacklight is packaged as a Rails Engine, which means it is distributed as a Ruby gem that provides functionality to the host application; in Blacklight's case, this includes the controllers, helpers, views, and assets to provide a basic search experience.
This means Blacklight can provide its core functionality, but the application is ultimately responsible for all the user interactions presented and will always take precedence over behavior provided by engines. This allows the application to override or change that behavior as appropriate to the application.
As part of the install generator, Blacklight adds a CatalogController
into your application and looks something like this:
class CatalogController < ApplicationController
include Blacklight::Catalog
configure_blacklight do |config|
...
end
end
Blacklight::Catalog
is a controller "concern" that provides some endpoints and useful out-of-the-box behavior for search and discovery, as well as viewing a single item.
Blacklight::Catalog
provides the configure_blacklight
method which allows you to specify and customize many aspects of how the catalog behaviors work using some configuration. You can use this configuration to manage:
- what search views are available
- which fields to show
- how to connect to the Solr index
Note: Information about the Blacklight configuration is provided elsewhere in this wiki.
This Blacklight configuration is done at the class-level, but a separate copy of the configuration is also made available within the controller instance (as CatalogController#blacklight_config
) at request time. This allows you to also modify the Blacklight behaviors (e.g. using Rails' .before_action
hook) based on parameters from the request (say, from parameters or using information about the user)
The Blacklight configuration allows you to make significant changes to what Blacklight displays on the page and how it interacts with parameters sent to and received from your search index. However, your application's controller can further customize behavior by overriding specific parts of what Blacklight provides, including replacing controller actions, helper methods, view partials, etc.
Finally, note that, although Blacklight provides this CatalogController
from its install generator (and seems to be appropriate for many use cases), you are free to rename it, have multiple such controllers, subclass the controller for special use cases, etc.
As with the CatalogController
above, Blacklight generates a SolrDocument
model into your application. The SolrDocument
provides a way to access data as a hash, and it is often useful to add model methods, accessors, and behaviors within the SolrDocument
method to make working with the data easy and pleasant.
This model is also key for translating a document from Solr's representation into something that approximates a Rails model in order to provide some of the same conventional behavior one might expect from any other Rails model.
In order to provide some of this magic, Blacklight expects that the Solr document has a unique id (by default, in the id
field), but this can be changed by setting the unique_key
class attribute:
class SolrDocument
self.unique_key = 'url'
...
Blacklight uses the value of the unique key field to provide appropriate Rails routing behavior, as well as using it to look up additional information from the solr response not contained by the document hash (e.g. Solr highlighting).
Blacklight provides a default implementation of some ActiveModel behavior to make it easy to work with these models within Rails. This includes features like:
Your application can override any view provided by Blacklight by creating a new view within your application with the same name as the Blacklight view you want to override. E.g., if you wanted to override the view provided by the Blacklight app/views/catalog/_per_page_widget.html.erb
partial, you could create the file app/views/catalog/_per_page_widget.html.erb
in your own application. When Rails looks for a view to render, it will first look in the app/views directory of the application. If it cannot find the view there, then it will check in the app/views directories of all engines which have this directory.
Note: View overriding in Rails also respects the controller inheritance; if you added another controller (say,
AnotherController
) that inherited from yourCatalogController
, you could override partials just for the other controller using the pathapp/views/another/_per_page_widget.html.erb
.
Overriding views is a very powerful way to completely change the look and feel of what Blacklight provides. That said, because views lack a strong contract between the the rendering context and your partial, overriding views in this way can be very brittle and liable to change unexpectedly. Although Blacklight maintainers try to limit breaking changes to major releases, you are strongly advised to write good integration tests to ensure your changes continue to function across releases.
Blacklight provides a generic layout to the application. This layout is often overridden by applications to provide institutional branding and styles.
If you're integrating Blacklight into an existing Rails application, note that Blacklight expects the layout to provide a some key content areas:
- flash messages
- modal
content_for(:head)
content_for(:container_header)
yield(:content)
Blacklight provides a small number of application-wide routes that are mounted into the application by the install generator:
mount Blacklight::Engine => '/'
produces:
Routes for Blacklight::Engine:
search_history GET /search_history(.:format) search_history#index
clear_search_history DELETE /search_history/clear(.:format) search_history#clear
The install generator also hooks up Rails routing for the CatalogController
:
# as on Blacklight 7:
# Search behaviors
resource :catalog, only: [:index], as: 'catalog', path: '/catalog', controller: 'catalog' do
concerns :searchable
end
# Single item behavior
resources :solr_documents, only: [:show], path: '/catalog', controller: 'catalog' do
concerns :exportable
end
The searchable
concern adds some routes that the default Blacklight views will use for searching:
search_catalog GET|POST /catalog(.:format) catalog#index
advanced_search_catalog GET /catalog/advanced(.:format) catalog#advanced_search
track_catalog POST /catalog/:id/track(.:format) catalog#track
raw_catalog GET /catalog/:id/raw(.:format) catalog#raw {:format=>"json"}
opensearch_catalog GET /catalog/opensearch(.:format) catalog#opensearch
suggest_index_catalog GET /catalog/suggest(.:format) catalog#suggest {:format=>"json"}
facet_catalog GET /catalog/facet/:id(.:format) catalog#facet
while the exportable
concern adds some actions for working with individual documents:
email_solr_document GET|POST /catalog/:id/email(.:format) catalog#email
sms_solr_document GET|POST /catalog/:id/sms(.:format) catalog#sms
citation_solr_document GET /catalog/:id/citation(.:format) catalog#citation
email_solr_documents GET|POST /catalog/email(.:format) catalog#email
sms_solr_documents GET|POST /catalog/sms(.:format) catalog#sms
citation_solr_documents GET /catalog/citation(.:format) catalog#citation
Note: Blacklight uses Rails' polymorphic URL helpers extensively to map a Blacklight document instance (by default, called
SolrDocument
) to the appropriate route (hence thesolr_document
routes). Given the proper configuration, this makes it possible to express many different search behaviors within an application (multiple search controllers providing access to documents at a consistent URL, multiple search controllers with their own document endpoints, or a single search controller that links to documents at different endpoints depending on the type of document)
More information about Blacklight routing and some common application-specific routing needs is available in the Configuring rails routes section of the wiki.
Blacklight adds javascript and stylesheet assets to your application.
Stylesheets are provided using SCSS, and can be modified by overriding Bootstrap's SCSS variables.
Javascript is implemented using a pluggable approach, which we hope provides an easy way to customize behavior.
Blacklight uses i18n (internationalization) extensively to both:
- translate the Blacklight-provided strings into other languages (with 10+ out-of-the-box translations), and
- allow applications to customize and override those strings with language more appropriate to the application's audience.