New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
allow language to be specified in the http accept_language header #223
Conversation
ddbecbf
to
e34f01e
Compare
Adds a few other language improvements… * do not include parameters that do not have a value when building URLs * clean template built URL to remove any occurances of ?&, &&, or ending with & * allow * as a wildcard for language processing which will prevent filtering of literals by language (TBD)
e87ad68
to
5cd213d
Compare
@@ -29,7 +29,7 @@ jobs: | |||
project: qa | |||
|
|||
- samvera/engine_cart_generate: | |||
cache_key: v1-internal-test-app-{{ checksum "qa.gemspec" }}-{{ checksum "spec/test_app_templates/lib/generators/test_app_generator.rb" }}-{{ checksum "lib/generators/qa/install/install_generator.rb" }}-<< parameters.rails_version >>-<< parameters.ruby_version >> | |||
cache_key: v2-internal-test-app-{{ checksum "qa.gemspec" }}-{{ checksum "spec/test_app_templates/lib/generators/test_app_generator.rb" }}-{{ checksum "lib/generators/qa/install/install_generator.rb" }}-<< parameters.rails_version >>-<< parameters.ruby_version >> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Required to force Circle CI cache to rebuild and pick up the new linked_data fixtures.
params[:lang] | ||
request_language = request.env['HTTP_ACCEPT_LANGUAGE'] | ||
request_language = request_language.scan(/^[a-z]{2}/).first if request_language.present? | ||
params[:lang] || request_language |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extends language specification to honor HTTP_ACCEPT_LANGUAGE if specified.
end | ||
|
||
def subauthority | ||
params[:subauthority] | ||
end | ||
|
||
def replacement_params | ||
params.reject { |k, _v| ['q', 'vocab', 'controller', 'action', 'subauthority', 'language', 'id'].include?(k) } | ||
params.reject { |k, _v| ['q', 'vocab', 'controller', 'action', 'subauthority', 'lang', 'id'].include?(k) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should have always been lang
instead of language
.
url = url.gsub("{#{key}}", m.simple_value(substitutions[key])) | ||
url = url.gsub("{?#{key}}", m.parameter_value(substitutions[key])) | ||
class << self | ||
# Construct an url from an IriTemplate making identified substitutions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is mostly an indentation change by adding class << self. This allows the private methods to be specified under the private section.
# In the process of substitution, if a value is missing, you can end up with '?&', '&&', or ending with '&'. These are all removed this method. | ||
def clean(url) | ||
url.gsub(/&&*/, '&').chomp('&').gsub('?&', '?') | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clean method is the only change to this service.
substitutions[action_request_variable(action_config, action)] = action_request | ||
substitutions[action_subauth_variable(action_config)] = action_subauth_variable_value(action_config, subauthority) if subauthority.present? | ||
substitutions[action_subauth_variable(action_config)] = action_subauth_variable_value(action_config, subauthority) if supports_subauthorities?(action_config) && subauthority.present? | ||
substitutions[action_language_variable(action_config)] = language_value(language) if supports_language_parameter?(action_config) && language.present? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lang
used to be passed in as part of the substitutions
. This was an artifact of lang
failing to be removed in the controller. Now that it is properly removed, it has to be passed in by name. This is cleaner as it makes the language processing more visible.
@@ -22,6 +24,7 @@ def literal_has_language_marker?(literal) | |||
def normalize_language(language) | |||
return language if language.blank? | |||
language = [language] unless language.is_a? Array | |||
return nil if language.include?(WILDCARD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By setting the language to nil, there will be no filtering. When an authority configuration sets the language to *
, it overrides the site wide default and prevents filtering for that authority.
@@ -37,7 +37,7 @@ def initialize(term_config) | |||
def find(id, language: nil, replacements: {}, subauth: nil, jsonld: false) | |||
raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data term sub-authority #{subauth}" unless subauth.nil? || term_subauthority?(subauth) | |||
@language = Qa::LinkedData::LanguageService.preferred_language(user_language: language, authority_language: term_config.term_language) | |||
url = Qa::LinkedData::AuthorityUrlService.build_url(action_config: term_config, action: :term, action_request: id, substitutions: replacements, subauthority: subauth) | |||
url = Qa::LinkedData::AuthorityUrlService.build_url(action_config: term_config, action: :term, action_request: id, substitutions: replacements, subauthority: subauth, language: @language) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After determining the preferred_language, it was then being ignored by passing language
to the AuthorityUrlService. Changing this to @language
causes the preferred language to be correctly passed instead.
@@ -35,7 +35,7 @@ def search(query, language: nil, replacements: {}, subauth: nil, context: false) | |||
raise Qa::InvalidLinkedDataAuthority, "Unable to initialize linked data search sub-authority #{subauth}" unless subauth.nil? || subauthority?(subauth) | |||
@context = context | |||
@language = language_service.preferred_language(user_language: language, authority_language: search_config.language) | |||
url = authority_service.build_url(action_config: search_config, action: :search, action_request: query, substitutions: replacements, subauthority: subauth) | |||
url = authority_service.build_url(action_config: search_config, action: :search, action_request: query, substitutions: replacements, subauthority: subauth, language: @language) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here. Needs to pass @language
which is the preferred langauge, instead of always the user/http language which may be nil if not set.
@@ -12,7 +13,7 @@ | |||
url: { | |||
:@context => 'http://www.w3.org/ns/hydra/context.jsonld', | |||
:@type => 'IriTemplate', | |||
template: 'http://localhost/test_default/search?{?subauth}&{?query}&{?param1}&{?param2}', | |||
template: 'http://localhost/test_default/search?{?subauth}&{?query}&{?param1}&{?param2}&{?lang}', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The updates to the expected full_config
here corresponds to the changes to the lod_full_config.json
fixture.
@@ -12,7 +13,7 @@ | |||
url: { | |||
:@context => 'http://www.w3.org/ns/hydra/context.jsonld', | |||
:@type => 'IriTemplate', | |||
template: 'http://localhost/test_default/term/{subauth}/{term_id}?{?param1}&{?param2}', | |||
template: 'http://localhost/test_default/term/{subauth}/{term_id}?{?param1}&{?param2}&{?lang}', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The updates to the expected full_config here corresponds to the changes to the lod_full_config.json fixture.
@@ -156,7 +172,7 @@ | |||
expect(min_config.term_language).to eq nil | |||
end | |||
it 'returns the preferred language for selecting literal values if configured for term' do | |||
expect(full_config.term_language).to eq [:en] | |||
expect(full_config.term_language).to eq [:es] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This value was changed in lod_full_config.json
fixture to make each language different so we can be sure the language we are checking came for the right place in the config.
it 'returns default language from Qa configuration' do | ||
expect(subject).to match_array [:en] | ||
context 'and site wide default language is set' do | ||
before do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These test changes are covering the various scenarios for setting language, including the new WILDCARD.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just had one question about the logic. Otherwise look solid.
end | ||
|
||
def language_value(language) | ||
return nil if language.blank? || !language.is_a?(Array) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@elrayle Just checking the logic here. If the language is 'EN' you will return nil, but if the language is ['EN'] you will return 'EN' . Is this correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will return nil when language is... nil, :en, 'en'
Will return :en when language is... ['en']
The reason this is ok is because the parameter is expected to be an array of symbols (line 12)
# @param language [Array<Symbol>] languages for filtering returned literals (optional)
The language is normalized to be an Array<Symbol>
by the language_service.
I could raise an exception if language is not nil
or an Array<Symbol>
to make this clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went with removing || !language.is_a?(Array)
since the param doc says it should be an array.
5cd213d
to
d403b70
Compare
Adds a few other improvements…