Skip to content
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

Vocabulary search list Twig-templates #1470

Merged
merged 15 commits into from
Sep 28, 2023
21 changes: 19 additions & 2 deletions resource/css/skosmos.css
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
--feedback-form-text: var(--dark-color);
--feedback-form-input: var(--light-color);
--feedback-form-button-bg: var(--dark-color);
--sidebar-search-bg: var(--dark-color);
--sidebar-search-text: var(--white-color);
--vocab-bg: var(--white-color);
--vocab-table-border: var(--medium-color);
--vocab-link: var(--secondary-dark-color);

/* Font definitions */
--font-size: 14px;
Expand Down Expand Up @@ -84,6 +89,7 @@ body {
color: var(--vocab-text);
font-size: 16px;
width: 20px;
text-align: center;
}

#main-container.searchpage .fa-copy, #main-container.searchpage-multi-vocab .fa-copy {
Expand Down Expand Up @@ -275,7 +281,7 @@ body {
font-weight: bold;
}

/***** Main container frontpage & frontpage one vacab *****/
/***** Main container frontpage & frontpage one vocab *****/
#background.frontpage, #background.frontpage-one-vocab {
background-color: var(--main-bg-1);
background-image: var(--frontpage-stripes-1);
Expand Down Expand Up @@ -553,6 +559,7 @@ body {

.search-result-term a {
font-family: var(--font-family-heading);
font-size: 1.5rem;
text-decoration: none;
}

Expand All @@ -564,7 +571,17 @@ body {
.uri-icon {
display: inline-block;
width: 20px;
font-size: 10px;
font-size: 0.75rem;
text-align: center;
}

.prefLabel.proplabel {
font-weight: bold;
color: var(--secondary-dark-color);
}

.replaced {
font-style: italic;
}

/***** Main container infopage & feedbackpage *****/
Expand Down
5 changes: 4 additions & 1 deletion src/view/base-template.twig
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@
<link href="node_modules/bootstrap/dist/css/bootstrap.min.css" media="screen, print" rel="stylesheet" type="text/css">
<link href="resource/css/fonts.css" media="screen, print" rel="stylesheet" type="text/css">
<link href="resource/css/skosmos.css" media="screen, print" rel="stylesheet" type="text/css">
<link href="resource/fontawesome/css/fontawesome.css" rel="stylesheet">
<link href="resource/fontawesome/css/solid.css" rel="stylesheet">
<link href="resource/fontawesome/css/regular.css" rel="stylesheet">
{% if ServiceCustomCss %}
<link href="{{ ServiceCustomCss }}" media="screen, print" rel="stylesheet" type="text/css">
{% endif %}
{% for plugin, files in request.plugins.pluginsCSS %}{% for file in files %}<link href="{{ file }}" media="screen, print" rel="stylesheet" type="text/css">{% endfor %}{% endfor %}

<title>{{ ServiceName }}{% block title %}{% endblock %}</title>
</head>
<body{% if request.vocabid == '' and request.page != 'feedback' and request.page != 'about' %} class="bg-light frontpage-logo"{% else %} class="bg-medium vocab-{{ request.vocabid }}"{% endif %}>
<body{% if request.vocabid == '' and request.page != 'feedback' and request.page != 'about' and request.page != 'search' %} class="bg-light frontpage-logo"{% else %} class="bg-medium vocab-{{ request.vocabid }}"{% endif %}>
<noscript>
<strong>We're sorry but Skosmos doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
Expand Down
14 changes: 14 additions & 0 deletions src/view/global-search.twig
joelit marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% extends "base-template.twig" %}
{% block title %}: "Search results"{% endblock %}
joelit marked this conversation as resolved.
Show resolved Hide resolved
{% block content %}
<div class="container">
<div class="mx-5 bg-light">
<div class="px-3 pb-3">
<div class="search-count {% if limit_type or limit_parent or limit_group or limit_scheme %}search-limited{% endif %}">
<p class="py-2"><span class="fw-bold">{{ search_count }} results for</span> '{{ term }}'</p>
joelit marked this conversation as resolved.
Show resolved Hide resolved
</div>
{% include "search-results.inc" %}
</div>
</div>
</div>
{% endblock %}
7 changes: 7 additions & 0 deletions src/view/search-results-filter.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% block content %}
<div class="col-md-4 pe-3">
<div class="p-4" id="sidebar">
<h4 class="fw-bold mb-5">{{ "Search options" | trans }}</h4>
</div>
</div>
{% endblock %}
123 changes: 123 additions & 0 deletions src/view/search-results.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
{% block content %}
{%~ if search_results is not null and search_results|length == 0 ~%}
<p class="no-results">{{ "The search provided no results." | trans }}</p>
{%~ endif ~%}

{%~ for concept in search_results ~%} {# loop through the hits #}

<div class="search-result mt-5 pt-1">
<div class="search-result-term">
{%- if vocab == '' and concept.vocab.id is defined %}<span class="fw-bold" data-title="{{ concept.vocabTitle }}">{{ concept.shortName }}: </span>{% endif -%}
{%- if concept.foundBy %} {# hit has been found through an alt/hidden/another language label #}
{%~ if concept.foundByType != 'lang' and concept.foundByType != 'hidden' ~%}
<span class="fst-italic">{{ concept.foundBy }}{%~ if explicit_langcodes or request.queryparam('anylang') and concept.contentLang != '' ~%} ({{ concept.contentLang }}){%~ endif ~%}</span>
&nbsp;<i class="fa-solid fa-arrow-right"></i>&nbsp;
{%~ if concept.notation ~%}<span>{{ concept.notation }}&nbsp;</span>{%~ endif ~%}
<a class="fw-bold" href="{%~ if 'isothes:ConceptGroup' in concept.type ~%}{{ concept.uri | link_url(concept.vocab,request.lang,'page',concept.contentLang) }}{%~ else ~%}{{ concept.uri | link_url(concept.vocab,request.lang,'page',concept.contentLang) }}{%~ endif ~%}">{{ concept.label(request.contentLang) }}</a>
{%~ if explicit_langcodes or request.queryparam('anylang') ~%}<span> ({{ concept.label.lang }})</span>{%~ endif ~%}
{%~ else ~%}
{%~ if concept.notation ~%}<span>{{ concept.notation }}&nbsp;</span>{%~ endif ~%}
<a href="{%~ if "isothes:ConceptGroup" in concept.type ~%}{{ concept.uri | link_url(concept.vocab,request.lang,'page',concept.contentLang) }}{%~ else ~%}{{ concept.uri | link_url(concept.vocab,request.lang,'page',concept.contentLang) }}{%~ endif ~%}">{{ concept.label(request.contentLang) }}</a>
{%~ if explicit_langcodes or request.queryparam('anylang') ~%}<span> ({{ concept.contentLang }})</span>{%~ endif ~%}
{%~ endif ~%}
{%~ else ~%}
{%~ if concept.notation %}<span class="notation">{{ concept.notation }}&nbsp;</span>{% endif ~%}
<a class="prefLabel conceptlabel" href="{%~ if "isothes:ConceptGroup" in concept.type ~%}{{ concept.uri | link_url(concept.vocab, request.lang, 'page') }}{%~ elseif concept.exvocab is defined%}{{ concept.uri | link_url(concept.exvocab,concept.contentLang) }}{%~ else ~%}{{ concept.uri | link_url(concept.vocab,request.lang,'page',concept.contentLang) }}{%~ endif ~%}">{{ concept.label(request.contentLang) }}</a>{%~ if explicit_langcodes or request.queryparam('anylang') ~%} ({{ concept.contentLang }}){%~ endif ~%}
{% endif -%}
{%- if concept.type == 'skosext:DeprecatedConcept' %}<span class="deprecated-alert">"deprecated"</span>{% endif -%}
joelit marked this conversation as resolved.
Show resolved Hide resolved
</div>
<ul class="list-group">
{% set conceptProperties = concept.properties %}
{%~ for property in conceptProperties ~%} {# loop through ConceptProperty objects #}
{%~ if property.type in PreferredProperties or property.type in concept.vocab.config.additionalSearchProperties or property.type in concept.vocab.config.hierarchyProperty ~%}
<li class="list-group-item px-0 py-1">
<span class="skosmos-tooltip" data-title="{{ property.description }}">
{%- if property.type == 'skos:broader' -%}<i class="property-hover fa-solid fa-arrow-turn-up fa-rotate-270"></i>
{%- elseif property.type == 'skos:narrower' -%}<i class="property-hover fa-solid fa-arrow-turn-up fa-rotate-90"></i>
{%- elseif property.type == 'skos:altLabel' -%}<i class="property-hover fa-solid fa-arrow-right"></i>
{%- elseif property.type == 'skos:related' -%}<i class="property-hover fa-solid fa-cloud"></i>
{%- elseif property.type == 'skosmos:memberOf' -%}<i class="property-hover fa-solid fa-layer-group"></i>
{%- elseif property.type == 'skos:note' -%}<i class="property-hover fa-solid fa-note-sticky"></i>
{%- else -%}<i class="property-hover fa-solid fa-globe"></i>
{%- endif -%}
</span>
{%~ set previous = false ~%}
{%- for propval in property.values -%} {# loop through ConceptPropertyValue objects #}
{%~ set outerLast = loop.last ~%}
{%- if propval.SubMembers ~%} {# if property is a group concept that has sub properties #}
joelit marked this conversation as resolved.
Show resolved Hide resolved
{%- for sub_member in propval.SubMembers ~%}
{%~ if previous != sub_member.label ~%}{{ sub_member.label }}{%- if sub_member.lang or explicit_langcodes ~%} ({{ sub_member.lang }}){%~ endif -%}{%- if not outerLast %}, {% endif %}
{%~ endif ~%}
{%~ set previous = sub_member.label ~%}
{%~ endfor -%}
{%- else ~%}
{%- if propval.uri ~%} {# resources with URI #}
{%- if propval.label ~%}
{%- if propval.exvocab and propval.exvocab != propval.vocab ~%}{# if the property is located in a another vocabulary #}{{ propval.label }}
{% else %}
{{ propval.label(request.contentLang) }}
{%- endif -%}
{%- if propval.lang and (propval.lang != request.lang) or explicit_langcodes %} ({{ propval.lang }}){%~ endif -%}{%- if not loop.last ~%}, {%~ endif ~%}
{%~ endif -%}
{%~ else ~%} {# Literals (no URI), eg. alternative labels as properties #}
<span class="{%~ if propval.type == 'skos:altLabel' %}replaced {% endif ~%}">{{ propval.label }}{%- if not loop.last -%}, {% endif %}</span>
joelit marked this conversation as resolved.
Show resolved Hide resolved
{%~ endif %}
{%~ endif %}
{%- endfor %}
</li>
{%~ endif ~%}
{%~ endfor ~%}
{%~ set foreignLabels = concept.foreignLabels ~%}
{%~ if foreignLabels ~%}
<li class="list-group-item px-0 py-1">
<span class="skosmos-tooltip" data-title="foreign prefLabel help"><i class="property-hover fa-solid fa-globe"></i></span>
{%- for langstring, labels in foreignLabels ~%}
{%~ for label in labels.prefLabel|default([])|merge(labels.altLabel|default([])) ~%}
<span class="{% if label.type == 'skos:prefLabel' %}prefLabel{% elseif label.type == 'skos:altLabel' %}replaced{% endif %} proplabel">{{ label }}</span>{%~ if label.lang %} ({{ label.lang }}){% endif ~%}{%- if loop.last == false %}, {% endif -%}
joelit marked this conversation as resolved.
Show resolved Hide resolved
{%~ endfor ~%}
{%- if loop.last == false -%}, {%- endif -%}
{%~ endfor ~%}
</li>
{% endif ~%}

{%~ if concept.vocab.config.additionalSearchProperties ~%}
{%~ set mappingProperties = concept.mappingProperties(concept.vocab.config.additionalSearchProperties) ~%}
{%~ if mappingProperties ~%}
{%~ for property in mappingProperties ~%} {# loop through ConceptProperty objects #}
{%~ if property.type in concept.vocab.config.additionalSearchProperties ~%}
<li class="list-group-item px-0 py-1">
<span class="skosmos-tooltip" data-title="{{ property.type }}">
<i class="property-hover fa-solid fa-globe"></i>
</span>
{%- for propval in property.values -%} {# loop through ConceptMappingPropertyValue objects #}
{%- if propval.exVocab -%}<span class="redirected-vocab-id prefLabel">{{ propval.exVocab.shortName }}: </span>{%- endif -%}{{ propval.label(request.contentLang) }}
{%- if propval.label(request.contentLang).lang != request.contentLang -%} ({{ propval.label(request.contentLang).lang }}){%- endif -%}{%- if loop.last == false -%}, {% endif %}
{% endfor %}
</li>
{%~ endif ~%}
{%~ endfor ~%}
{%~ endif ~%}
{%~ endif -%}
{%- for property in conceptProperties ~%} {# loop through ConceptProperty objects #}
{%- if property.type == 'rdf:type' ~%}
<li class="list-group-item px-0 py-1">
<span class="skosmos-tooltip" data-title="concept_types">
<i class="property-hover fa-solid fa-arrows-to-circle"></i>
</span>
{% for propval in property.values %}{{ propval.label }}{% if loop.last == false %}, {% endif %}{% endfor %}

</li>
{%~ endif -%}
{%~ endfor -%}
{%~ if concept.uri ~%}
<li class="list-group-item px-0 py-1">
<span class="uri-icon">URI</span>
<span class="search-result-uri">{{ concept.uri }}</span>
<i class="fa-regular fa-copy"></i> <!-- no copy to clipboard functionality yet -->
</li>
{%~ endif ~%}
</ul>

</div>
{%~ endfor ~%}
{% endblock %}
20 changes: 20 additions & 0 deletions src/view/vocab-search.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends "base-template.twig" %}
{% block title %}: {{ vocab.shortName(request.contentLang) }} '{{ term }}'{% endblock %}
{% block content %}
<main class="searchpage py-5" id="main-container" >
<div class="container">
<div class="row">
{% include "search-results-filter.inc" %}

<div class="col-md-8 ps-3" id="main-content">
<div class="p-5 pt-4">
<div class="search-count {% if limit_type or limit_parent or limit_group or limit_scheme %}search-limited{% endif %}">
<p class="py-2"><span class="fw-bold">{{ "%search_count% results for '%term%'" | trans({'%search_count%': search_count, '%term%' : term}) }}</span></p>
</div>
{% include "search-results.inc" %}
</div>
</div>
</div>
</div>
</main>
{% endblock %}
15 changes: 14 additions & 1 deletion tests/cypress/template/vocab-search.cy.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a pretty minimal test for what is a fairly advanced page type. Could we come up with more tests?

Examples:

  • the "X results for Y" text is there, with the correct values for X and Y
  • the search returns the correct number of search-result DIV elements
  • for one of the search results, verify the basic information, e.g.
    • heading information (also check that the link points where it should)
    • prefLabels in all languages
    • altLabels
    • broader / narrower / related
    • group
    • URI
  • same as above for non-Concept types e.g. ThesaurusArray ("vaatteet vuodenajan mukaan")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added more texts for the search result properties. We should maye wait for test-yso before writing tests for the non-concept types.

Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
describe('Vocabulary search page', () => {
it('no-op test', () => {})
it('contains search result info', () => {
cy.visit('/test/en/search?clang=en&q=bass')

//Check that there are at least some search results
cy.get('.search-count > p > span').invoke('text')

.then(text => {
const searchCount = text.charAt(0);
cy.wrap(searchCount).then(parseFloat).should('be.gt', 0)
});

//Check that there is a search result that contains a type icon
cy.get('div.search-result > ul > li > span > i.property-hover.fa-solid.fa-arrows-to-circle')
})
})