Skip to content

Commit

Permalink
Feature: Show multiple languages (#252)
Browse files Browse the repository at this point in the history
* refactor ontology_viewer_page_name to support multiple languages

* refactor sort_by in collection and schemes to support multiple languges

* update ontology_viewer title

* add all option in language selection

* show prefLabel with the specific language in case of all languages

* remove a forgotten debugger in the JS code of language change selector

* revert concept details prefLabel multiple language display

* show corresponding  lang in the tree view

* Show data in platform language when lang is equal to 'all'

* fix sort_by in collections and schemes

* make sub.publication iterable

* use tooltip to show language in concept tree links

* use display_in_multiple_languges methode to show properties in multiple langs

* add tooltips to show language in tree view

* change 'process_concept' method name to 'language_hash'

* define 'display_in_multiple_languages' method

* use 'langauge_hash' methode in collection instead of 'process_concept'

* cls_id to string

* use 'langauge_hash' methode in schemes instead of 'process_concept'

* update tooltip controller to support position

* use 'langauge_hash' methode in _list_view instead of 'process_concept'

* use 'display_in_multiple_languges' to display properties

* fix missing 'end' in application helper

* display_in_multiple_languges in schemes

* fix language_hash method name typo

* check if prefLabel is nil

* use tooltip to show preLabel lang in schemes

* use tooltip to show preLabel lang in collections

* use tooltip in collection

* fix a typo display_in_multiple_languages function name

* extract link_to_scheme helper for schemes tree view

* extract helpers to display the collections list view

* refactor language related helpers code in application_helper

* add language argument to scheme and collection tree links

* refactor scheme and collection helpers to make it work for mutli-langs

* fix sort in tree_link_to_concept and add return first in array on language_hash methode

* extract multi language helpers into a file

* make display_in_multiple_languages directly do the language_hash inside

* rename the helper get_concept_label to select_language_label

* move the not found prefLabel alert in the prefLabel  row

* catch concept list error when concept label is nil

* add main_language_label helper to show the concept label main language label

* fix loader showed in small state by default

* fix alert component text overflowing

* reset turbo progress bar to blue

* add id to tabs container component

* extract sorted_labels helpers for schemes and collections

* fix mappings new form not finding the ontology  by id bu by acronym

* use main_language_label helper for build_tree

* use main_language_label helper in ontology_viewer_page_name

* restore removed properties section content

---------

Co-authored-by: Syphax Bouazzouni <gs_bouazzouni@esi.dz>
  • Loading branch information
syphax-bouazzouni committed Sep 5, 2023
1 parent 9c2bb25 commit 421f5a0
Show file tree
Hide file tree
Showing 27 changed files with 258 additions and 134 deletions.
5 changes: 5 additions & 0 deletions app/assets/stylesheets/bioportal.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
.turbo-progress-bar {
height: 5px;
background-color: var(--admin-color);
}

a{
text-decoration: none !important;
}
Expand Down
13 changes: 11 additions & 2 deletions app/components/concept_details_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

class ConceptDetailsComponent < ViewComponent::Base
include ApplicationHelper
include MultiLanguagesHelper

renders_one :header
renders_many :sections
Expand Down Expand Up @@ -31,7 +32,11 @@ def render_properties(properties_set, ontology_acronym, &block)
if block_given?
block.call(v)
else
get_link_for_cls_ajax(v, ontology_acronym, '_blank')
if v.is_a?(String)
get_link_for_cls_ajax(v, ontology_acronym, '_blank')
else
display_in_multiple_languages([v].to_h)
end
end
end

Expand Down Expand Up @@ -112,7 +117,11 @@ def concept_properties2hash(properties)
end
begin
# Try to simplify the property values, when they are a struct.
values = properties[key].map { |v| v.string }
if properties[key].is_a?(OpenStruct)
values = language_hash(properties[key])
else
values = properties[key].map { |v| v.string }
end
rescue
# Each value is probably a simple datatype already.
values = properties[key]
Expand Down
1 change: 0 additions & 1 deletion app/components/loader_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,4 @@ def call
end
end
end

end
2 changes: 1 addition & 1 deletion app/controllers/collections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def show_label
collection_label = collection['prefLabel'] if collection
collection_label = params[:id] if collection_label.nil? || collection_label.empty?

render LabelLinkComponent.inline(params[:id], collection_label)
render LabelLinkComponent.inline(params[:id], helpers.main_language_label(collection_label))
end

def show_members
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/concepts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def show_label
return
end

render LabelLinkComponent.inline(cls_id, concept_label(ont_id, cls_id))
render LabelLinkComponent.inline(cls_id, helpers.main_language_label(concept_label(ont_id, cls_id)))
end

def show_definition
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/label_xl_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def show_label
label_xl_label = label_xl ? label_xl['literalForm'] : nil
label_xl_label = params[:id] if label_xl_label.nil? || label_xl_label.empty?

render LabelLinkComponent.inline(params[:id], label_xl_label)
render LabelLinkComponent.inline(params[:id], helpers.main_language_label(label_xl_label))
end

private
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/mappings_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ def mapping_form(mapping: nil)
end
else
mapping = LinkedData::Client::Models::Mapping.new
@ontology_from = LinkedData::Client::Models::Ontology.find(params[:ontology_from])
@ontology_to = LinkedData::Client::Models::Ontology.find(params[:ontology_to])
@ontology_from = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology_from].split('/').last).first
@ontology_to = LinkedData::Client::Models::Ontology.find_by_acronym(params[:ontology_to]&.split('/')&.last).first
@concept_from = @ontology_from.explore.single_class({ full: true }, params[:conceptid_from]) if @ontology_from
if @ontology_to
@concept_to = @ontology_to.explore.single_class({ full: true }, params[:conceptid_to])
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/schemes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ def show_label
scheme_label = scheme ? scheme['prefLabel'] : params[:id]
scheme_label = scheme_label.nil? || scheme_label.empty? ? params[:id] : scheme_label

render LabelLinkComponent.inline(params[:id], scheme_label)
render LabelLinkComponent.inline(params[:id], helpers.main_language_label(scheme_label))
end

private
Expand Down
50 changes: 39 additions & 11 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@

module ApplicationHelper

include ModalHelper, MultiLanguagesHelper

RESOLVE_NAMESPACE = {:omv => "http://omv.ontoware.org/2005/05/ontology#", :skos => "http://www.w3.org/2004/02/skos/core#", :owl => "http://www.w3.org/2002/07/owl#",
:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#", :rdfs => "http://www.w3.org/2000/01/rdf-schema#", :metadata => "http://data.bioontology.org/metadata/",
:metadata_def => "http://data.bioontology.org/metadata/def/", :dc => "http://purl.org/dc/elements/1.1/", :xsd => "http://www.w3.org/2001/XMLSchema#",
:oboinowl_gen => "http://www.geneontology.org/formats/oboInOwl#", :obo_purl => "http://purl.obolibrary.org/obo/",
:umls => "http://bioportal.bioontology.org/ontologies/umls/", :door => "http://kannel.open.ac.uk/ontology#", :dct => "http://purl.org/dc/terms/",
:void => "http://rdfs.org/ns/void#", :foaf => "http://xmlns.com/foaf/0.1/", :vann => "http://purl.org/vocab/vann/", :adms => "http://www.w3.org/ns/adms#",
:voaf => "http://purl.org/vocommons/voaf#", :dcat => "http://www.w3.org/ns/dcat#", :mod => "http://www.isibang.ac.in/ns/mod#", :prov => "http://www.w3.org/ns/prov#",
:cc => "http://creativecommons.org/ns#", :schema => "http://schema.org/", :doap => "http://usefulinc.com/ns/doap#", :bibo => "http://purl.org/ontology/bibo/",
:wdrs => "http://www.w3.org/2007/05/powder-s#", :cito => "http://purl.org/spar/cito/", :pav => "http://purl.org/pav/", :nkos => "http://w3id.org/nkos/nkostype#",
:oboInOwl => "http://www.geneontology.org/formats/oboInOwl#", :idot => "http://identifiers.org/idot/", :sd => "http://www.w3.org/ns/sparql-service-description#",
:cclicense => "http://creativecommons.org/licenses/"}


def get_apikey
unless session[:user].nil?
return session[:user].apikey
Expand Down Expand Up @@ -153,8 +168,8 @@ def draw_tree(root, id = nil, concept_schemes = [])
def build_tree(node, string, id, concept_schemes: [])

return string if node.children.nil? || node.children.empty?

node.children.sort! { |a, b| (a.prefLabel || a.id).downcase <=> (b.prefLabel || b.id).downcase }
node.children.sort! { |a, b| (main_language_label(a.prefLabel) || a.id).downcase <=> (main_language_label(a.prefLabel) || b.id).downcase }
node.children.each do |child|
active_style = child.id.eql?(id) ? "active" : ''

Expand Down Expand Up @@ -186,14 +201,27 @@ def tree_link_to_concept(child:, ontology_acronym:, active_style:, node: nil)
icons = child.relation_icon(node)
muted_style = child.isInActiveScheme&.empty? ? 'text-muted' : ''
href = ontology_acronym.blank? ? '#' : "/ontologies/#{child.explore.ontology.acronym}/concepts/?id=#{CGI.escape(child.id)}&language=#{language}"

if child.prefLabel.nil?
prefLabelHTML = child.id.split('/').last
else
prefLabelLang, prefLabelHTML = select_language_label(child.prefLabel)
prefLabelLang = prefLabelLang.to_s.upcase
tooltip = prefLabelLang.eql?("@NONE") ? "" : "data-controller='tooltip' data-tooltip-position-value='right' title='#{prefLabelLang}'";
end

link = <<-EOS
<a id='#{child.id}' data-conceptid='#{child.id}'
data-turbo=true data-turbo-frame='concept_show' href='#{href}'
data-collections-value='#{child.memberOf || []}'
data-active-collections-value='#{child.isInActiveCollection || []}'
data-skos-collection-colors-target='collection'
class='#{muted_style} #{active_style}'>
#{child.prefLabel ? child.prefLabel({ use_html: true }) : child.id.split('/').last}
<a id='#{child.id}'
data-conceptid='#{child.id}'
data-turbo=true data-turbo-frame='concept_show' href='#{href}'
data-collections-value='#{child.memberOf || []}'
data-active-collections-value='#{child.isInActiveCollection || []}'
data-skos-collection-colors-target='collection'
class='#{muted_style} #{active_style}'
#{tooltip}
>
#{ prefLabelHTML }
</a>
EOS

Expand Down Expand Up @@ -554,8 +582,8 @@ def get_link_for_label_xl_ajax(label_xl, ont_acronym, cls_id, modal: true)
end

###END ruby equivalent of JS code in bp_ajax_controller.
def ontology_viewer_page_name(ontology_name, concept_name_title , page)
ontology_name + " | " +concept_name_title + " - #{page.capitalize}"
def ontology_viewer_page_name(ontology_name, concept_label, page)
ontology_name + " | " + main_language_label(concept_label) + " - #{page.capitalize}"
end

def link_to_modal(name, options = nil, html_options = nil, &block)
Expand Down
26 changes: 22 additions & 4 deletions app/helpers/collections_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@ def get_collections_labels(collections, main_uri = '')
collections_labels = []
collections.each do |x|
id = x['@id']
label = get_collection_label(x)
label = select_language_label(get_collection_label(x))
if id.eql? main_uri
selected_label = { 'prefLabel' => label, '@id' => id }
else
collections_labels.append( { 'prefLabel' => label, '@id' => id , 'color' => x['color'] })
end
end
collections_labels.sort_by! { |s| s['prefLabel']}

collections_labels = sorted_labels(collections_labels)
collections_labels.unshift selected_label if selected_label
[collections_labels, selected_label]
end
Expand All @@ -47,14 +48,31 @@ def no_collections_alert
end
end

def collection_path(collection_id = '')
"/ontologies/#{@ontology.acronym}/collections/show?id=#{escape(collection_id)}"
def collection_path(collection_id = '', language = '')
"/ontologies/#{@ontology.acronym}/collections/show?id=#{escape(collection_id)}&language=#{language}"
end

def request_collection_id
params[:id] || params[:collection_id] || params[:concept_collection]
end

def sort_collections_label(collections_labels)
sorted_labels(collections_labels)
end

def link_to_collection(collection, selected_collection_id)
pref_label_lang, pref_label_html = get_collection_label(collection)
tooltip = pref_label_lang.to_s.eql?('@none') ? '' : "data-controller='tooltip' data-tooltip-position-value='right' title='#{pref_label_lang.upcase}'"
<<-EOS
<a id="#{collection['@id']}" href="#{collection_path(collection['@id'], request_lang)}"
data-turbo="true" data-turbo-frame="collection" data-collectionid="#{collection['@id']}"
#{tooltip}
class="#{selected_collection_id.eql?(collection['@id']) ? 'active' : nil}">
#{pref_label_html}
</a>
EOS
end

private

def generate_collections_colors(collections)
Expand Down
63 changes: 63 additions & 0 deletions app/helpers/multi_languages_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
module MultiLanguagesHelper

def language_hash(concept_label)

return concept_label.first if concept_label.is_a?(Array)
return concept_label.to_h.reject { |key, _| %i[links context].include?(key) } if concept_label.is_a?(OpenStruct)

concept_label
end

def sorted_labels(labels)
Array(labels).sort_by { |label| label['prefLabel'].is_a?(String) ? label['prefLabel'] : label['prefLabel'].last }
end

def select_language_label(concept_label, platform_languages = %i[en fr])
concept_value = nil

concept = language_hash(concept_label)

return ['@none', concept] if concept.is_a?(String)

concept = concept.to_h

platform_languages.each do |lang|
if concept[lang]
concept_value = [lang, concept[lang]]
break
end
end

concept_value || concept.to_a.first
end

def main_language_label(label)
select_language_label(label)&.last
end

def display_in_multiple_languages(label)
label = language_hash(label)

if label.nil?
return render Display::AlertComponent.new(message: t('ontology_details.concept.no_preferred_name_for_selected_language'),
type: "warning",
closable: true)
end

return content_tag(:p, label) if label.is_a?(String)

raw(label.map do |key, value|
content_tag(:div, class: 'd-flex align-items-center') do
concat content_tag(:p, Array(value).join(', '), class: 'm-0')

unless key.to_s.upcase.eql?('NONE') || key.to_s.upcase.eql?('@NONE')
concat content_tag(:span, key.upcase, class: 'badge badge-secondary ml-1')
end
end
end.join)
end

def selected_language_label(label)
language_hash(label).values.first
end
end
19 changes: 18 additions & 1 deletion app/helpers/ontologies_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,16 +467,33 @@ def language_selector_hidden_tag(section)
end

def languages_options(submission = @submission || @submission_latest)
current_lang = request_lang
current_lang = request_lang.downcase
submission_lang = submission_languages(submission)
# Transform each language into a select option
submission_lang = submission_lang.map do |lang|
lang = lang.split('/').last.upcase
[lang, lang, { selected: lang.eql?(current_lang) }]
end

# Add the option to select all language
submission_lang.push(['All', 'all', { selected: current_lang.eql?('all') }])

options_for_select(submission_lang)
end

def display_complex_text(definitions)
html = ""
definitions.each do |definition|
if definition.is_a?(String)
html += '<p class="prefLabel">' + definition + '</p>'
elsif definition.respond_to?(:uri) && definition.uri
html += render LinkFieldComponent.new(value: definition.uri)
else
html += display_in_multiple_languages(definition)
end
end
return html.html_safe
end
private

def submission_languages(submission = @submission)
Expand Down
Loading

0 comments on commit 421f5a0

Please sign in to comment.