Skip to content

Commit

Permalink
MIR-1241 Response mir facets should be dynamic (#901)
Browse files Browse the repository at this point in the history
* MIR-1241: split the response-mir.xsl file, dynamic facets were split into a separate facets.xsl file; improved usability and customized the code in the mir_results.scss file; added some facets to the solr-config.json file and corresponding messages to messages_*.properties files.

* MIR-1241: remove new fields from solr-config.json for SOLR request handler /select, remove some new messages from messages_*.properties

* MIR-1241: add facets for classifications

* MIR-1241: split the response-mir.xsl file, dynamic facets were split into a separate facets.xsl file; improved usability and customized the code in the mir_results.scss file; added some facets to the solr-config.json file and corresponding messages to messages_*.properties files.

* MIR-1241

* MIR-1241: remove unused file facets.xsl

* MIR-1241: refactoring: reducing the number of calls to URI-Resolver

* MIR-1241: fix redundant condition

* MIR-1241: remove variables $MIR.Response.Facet.Prefix.Classification, $classId

* MIR-1241 Moved facet related template to response-facets.xsl. Use include via resource: uri

* MIR-1241 Simplified code for arbtrary facets

* MIR-1241 Parse classification only once

* MIR-1241 Support dynamic facet titles, allow to read values from category.top solr field

* MIR-1241 Fix $ClassId to 'category.top'

* MIR-1241 Renamed variable

* MIR-1241 Removed extra handling for mods.genre and worldReadableComplete facets

* MIR-1241 Reduce diff in mir_results.scss (removed changes caused by code format)

---------

Co-authored-by: Silvio Hermann <[email protected]>
Co-authored-by: Oleksiy 'Alex' Levshyn <[email protected]>
  • Loading branch information
3 people authored Dec 5, 2023
1 parent 178c827 commit eb13e20
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $filter_border: #ccc !default;
$filter_headline: #999 !default;
$filter_hits: #999 !default;
$filter: #666 !default;
$hover_darken: 20%;

@-webkit-keyframes bouncedelay {
0%, 80%, 100% { -webkit-transform: scale(0.0) }
Expand Down Expand Up @@ -89,54 +90,75 @@ $filter: #666 !default;
float: left;
width: 100%;
.card-header {
cursor: pointer;
.card-title {
font-size: 1rem;
color: $filter_headline;
margin-bottom: 0px;
&:hover {
color: darken($filter_headline, $hover_darken);
}
}
}
.filter {
li {
.checkbox {
cursor: pointer;
&:hover * {
background-color: transparent;
}
&:hover {
.custom-checkbox {
label {
.title {
color: darken($filter, $hover_darken);
}
.hits {
color: darken($filter_hits, $hover_darken);
}
}
}
}
.custom-checkbox {
margin-top: 0px;
margin-bottom: 0px;
label {
cursor: pointer;
vertical-align: middle;
.hits {
color: $filter_hits;
}
}
.hits {
color: $filter_hits;
}
}
}
&.worldReadableComplete {
li[data-fq^='worldReadableComplete']{
.title:before{
display: inline-block;
font: normal normal 900 14px/1 'Font Awesome 5 Free';
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin-right: 5px;
}
}
li[data-fq='worldReadableComplete:true'] {
.title {
@extend .text-success;
&:before{
content: "\f13e"; //fa-unlock-alt
}
}
}
li[data-fq='worldReadableComplete:false'] {
.title {
@extend .text-warning;
&:before{
content: "\f023"; //fa-lock
}
}
}
}
&.oa {
li[data-fq^='worldReadableComplete']{
.title:before{
display: inline-block;
font: normal normal 900 14px/1 'Font Awesome 5 Free';
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
margin-right: 5px;
}
}
li[data-fq='worldReadableComplete:true'] {
.title {
@extend .text-success;
&:before{
content: "\f13e"; //fa-unlock-alt
}
}
}
li[data-fq='worldReadableComplete:false'] {
.title {
@extend .text-warning;
&:before{
content: "\f023"; //fa-lock
}
}
}
}

}
}
Expand Down
10 changes: 7 additions & 3 deletions mir-module/src/main/resources/config/mir/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -627,12 +627,16 @@ mir.relatedItem.reviewOf = Rezension von
mir.relatedItem.search = Verkn\u00FCpfte Publikationen als separate Trefferliste anzeigen
mir.relatedItem.series = In Serie
mir.response.button.filter = Filter
mir.response.openAccess.facet.false = keine oder gesch\u00FCtze Dateien
mir.response.openAccess.facet.title = Verf\u00FCgbarkeit
mir.response.openAccess.facet.true = Dateien frei zug\u00E4nglich
mir.response.facet.worldReadableComplete.title = Verf\u00FCgbarkeit
mir.response.facet.worldReadableComplete.value.true = Dateien frei zug\u00E4nglich
mir.response.facet.worldReadableComplete.value.false = keine oder gesch\u00FCtze Dateien
mir.response.openAccess.false = Keine frei verf\u00FCgbare Datei angehangen.
mir.response.openAccess.true = Frei verf\u00FCgbare Datei angehangen.
mir.response.relevance = Relevanz des Treffers in Bezug auf alle Treffer dieser Suche
mir.response.facet.mods.genre.title = Typ
mir.response.facet.createdby.title = Erstellt von
mir.response.facet.modifiedby.title = Angepasst von
mir.response.facet.mods.author.title = Autor*in
mir.results.hitDoesNotExist = Dieser Treffer kann nicht angezeigt werden oder wurde gerade gel\u00F6scht.
mir.rights = Lizenz
mir.rightsHolder = Rechteinhaber:
Expand Down
10 changes: 7 additions & 3 deletions mir-module/src/main/resources/config/mir/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -600,12 +600,16 @@ mir.relatedItem.references = References
mir.relatedItem.reviewOf = Review of
mir.relatedItem.search = Show related publications as separate result list
mir.relatedItem.series = In Series
mir.response.openAccess.facet.false = no or protected files
mir.response.openAccess.facet.title = Availability
mir.response.openAccess.facet.true = Files freely accessible
mir.response.facet.worldReadableComplete.title = Availability
mir.response.facet.worldReadableComplete.value.false = no or protected files
mir.response.facet.worldReadableComplete.value.true = Files freely accessible
mir.response.openAccess.false = No free available file attached.
mir.response.openAccess.true = Free available file attached.
mir.response.relevance = Relevance of this hit in relation to all hits of current search
mir.response.facet.mods.genre.title = Type
mir.response.facet.createdby.title = Created by
mir.response.facet.modifiedby.title = Modified by
mir.response.facet.mods.author.title = Author
mir.results.hitDoesNotExist = This result can not be displayed or was recently deleted.
mir.rights = License
mir.rightsHolder = License Holder:
Expand Down
10 changes: 7 additions & 3 deletions mir-module/src/main/resources/config/mir/messages_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ mir.metaData.panel.heading.mir_admindata_panel = Informazioni di sistema
mir.placeholder.characteristics.factor = Impact Factor
mir.placeholder.characteristics.year = YYYY
mir.response.button.filter = Filtri
mir.response.openAccess.facet.false = file no o protetti
mir.response.openAccess.facet.title = Disponibilit\u00E0
mir.response.openAccess.facet.true = File liberamente accessibili
mir.response.facet.worldReadableComplete.title = Disponibilit\u00E0
mir.response.facet.worldReadableComplete.value.true = File liberamente accessibili
mir.response.facet.worldReadableComplete.value.false = file no o protetti
mir.response.facet.mods.genre.title = Tipo
mir.response.facet.createdby.title = Creato da
mir.response.facet.modifiedby.title = Modificato da
mir.response.facet.mods.author.title = Autore

user.profile.id.orcid = Your ORCID iD
1 change: 0 additions & 1 deletion mir-module/src/main/resources/config/mir/mycore.properties
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,6 @@ MCR.Solr.HTTPResponseHeader.Content-Security-Policy=
# MIR still works with dynamic generated solr fields
MCR.Solr.DynamicFields=true


##############################################################################
# URIResolver & ContentTransformer #
##############################################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,9 @@
},
"appends": {
"facet": "true",
"facet.field": "mods.genre",
"facet.field": [
"mods.genre"
],
"facet.mincount": "1"
}
}
Expand Down
177 changes: 177 additions & 0 deletions mir-module/src/main/resources/xsl/response-facets.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:encoder="xalan://java.net.URLEncoder"
xmlns:i18n="xalan://org.mycore.services.i18n.MCRTranslation"
xmlns:mcrxsl="xalan://org.mycore.common.xml.MCRXMLFunctions"
xmlns:xalan="http://xml.apache.org/xalan"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="i18n mcrxsl encoder xalan fn">

<xsl:param name="CurrentLang"/>
<xsl:param name="RequestURL"/>

<xsl:variable name="facetProperties" select="document(concat('property:','MIR.Response.Facet.*'))"/>

<xsl:template name="facets">
<xsl:for-each select="/response/lst[@name='facet_counts']/lst[@name='facet_fields']/*">
<xsl:variable name="facet_name" select="self::node()/@name"/>

<xsl:if test="self::node()[@name=$facet_name]/int">
<!-- name of facet -->
<div class="card {$facet_name}">
<div class="card-header" data-toggle="collapse-next">
<h3 class="card-title">
<xsl:variable name="classification"
select="document(concat('notnull:classification:metadata:all:children:', $facet_name))"/>
<xsl:choose>
<xsl:when test="i18n:exists(concat('mir.response.facet.', $facet_name, '.title'))">
<xsl:value-of select="i18n:translate(concat('mir.response.facet.', $facet_name, '.title'))"/>
</xsl:when>
<xsl:when test="not($classification/null)">
<xsl:variable name="label" select="$classification/mycoreclass/label[@xml:lang=$CurrentLang]/@text"/>
<xsl:choose>
<xsl:when test="string-length($label) &gt; 0">
<xsl:value-of select="$label"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$facet_name"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>

<xsl:otherwise>
<xsl:value-of select="$facet_name"/>
</xsl:otherwise>

</xsl:choose>
</h3>
</div>

<!-- facet values -->
<div class="card-body collapse show">
<ul class="filter">
<xsl:variable name="CategoryClassValues"
select="concat('MIR.Response.Facet.', $facet_name, '.CategoryClassValues')"/>
<xsl:apply-templates select="/response/lst[@name='facet_counts']/lst[@name='facet_fields']">
<xsl:with-param name="facet_name" select="$facet_name"/>
<xsl:with-param name="CategoryClassValues"
select="boolean($facetProperties/properties/entry[@key = $CategoryClassValues])"/>
</xsl:apply-templates>
</ul>
</div>
</div>
</xsl:if>
</xsl:for-each>
</xsl:template>

<xsl:template match="/response/lst[@name='facet_counts']/lst[@name='facet_fields']">
<xsl:param name="CategoryClassValues" select="false()"/>
<xsl:param name="facet_name"/>
<xsl:param name="i18nPrefix"/>

<xsl:for-each select="lst[@name=$facet_name]/int">
<xsl:variable name="fqValue">
<xsl:choose>
<xsl:when test="$CategoryClassValues = true()">
<xsl:value-of
select="concat('category.top',':',substring-before(@name,':'),'%5C:',substring-after(@name,':'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($facet_name,':',@name)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<xsl:variable name="fqResponseValue">
<xsl:choose>
<xsl:when test="$CategoryClassValues = true()">
<xsl:value-of
select="concat('category.top',':',substring-before(@name,':'),'\:',substring-after(@name,':'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($facet_name,':',@name)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="fqFragment" select="concat('fq=',$fqValue)"/>
<xsl:variable name="fqFragmentEncoded" select="concat('fq=',encoder:encode($fqResponseValue, 'UTF-8'))"/>
<xsl:variable name="queryWithoutStart" select="mcrxsl:regexp($RequestURL, '(&amp;|%26)(start=)[0-9]*', '')"/>

<xsl:variable name="queryURL">
<xsl:choose>
<xsl:when test="contains($queryWithoutStart, $fqFragment)">
<xsl:choose>
<xsl:when test="not(substring-after($queryWithoutStart, $fqFragment))">
<!-- last parameter -->
<xsl:value-of
select="substring($queryWithoutStart, 1, string-length($queryWithoutStart) - string-length($fqFragment) - 1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="concat(substring-before($queryWithoutStart, $fqFragment), substring-after($queryWithoutStart, concat($fqFragment,'&amp;')))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="contains($queryWithoutStart, $fqFragmentEncoded)">
<xsl:choose>
<xsl:when test="not(substring-after($queryWithoutStart, $fqFragmentEncoded))">
<!-- last parameter -->
<xsl:value-of
select="substring($queryWithoutStart, 1, string-length($queryWithoutStart) - string-length($fqFragmentEncoded) - 1)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="concat(substring-before($queryWithoutStart, $fqFragmentEncoded), substring-after($queryWithoutStart, concat($fqFragmentEncoded,'&amp;')))"/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:when test="not(contains($queryWithoutStart, '?'))">
<xsl:value-of select="concat($queryWithoutStart, '?', $fqFragment)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat($queryWithoutStart, '&amp;', $fqFragment)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>

<li data-fq="{$fqResponseValue}">
<div class="custom-control custom-checkbox" onclick="location.href='{$queryURL}';">
<input type="checkbox" class="custom-control-input">
<xsl:if test="
/response/lst[@name='responseHeader']/lst[@name='params']/str[@name='fq' and text() = $fqResponseValue] |
/response/lst[@name='responseHeader']/lst[@name='params']/arr[@name='fq']/str[text() = $fqResponseValue]">
<xsl:attribute name="checked">true</xsl:attribute>
</xsl:if>
</input>

<label class="custom-control-label">
<span class="title">
<xsl:choose>
<xsl:when
test="$CategoryClassValues = true() and mcrxsl:isCategoryID(substring-before(@name, ':'), substring-after(@name, ':'))">
<xsl:value-of
select="mcrxsl:getDisplayName(substring-before(@name, ':'), substring-after(@name, ':'))"/>
</xsl:when>
<xsl:when test="mcrxsl:isCategoryID($facet_name, @name)">
<xsl:value-of select="mcrxsl:getDisplayName($facet_name, @name)"/>
</xsl:when>
<xsl:when test="i18n:exists(concat('mir.response.facet.' ,$facet_name, '.value.', @name))">
<xsl:value-of select="i18n:translate(concat('mir.response.facet.' ,$facet_name, '.value.', @name))"
disable-output-escaping="yes"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@name"/>
</xsl:otherwise>
</xsl:choose>
</span>

<span class="hits">
<xsl:value-of select="."/>
</span>
</label>
</div>
</li>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>
2 changes: 1 addition & 1 deletion mir-module/src/main/resources/xsl/response-mir-utils.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -393,4 +393,4 @@
<xsl:value-of select="concat($href, '&amp;start=',(($page -1) * $numPerPage), '&amp;rows=', $numPerPage)" />
</xsl:template>

</xsl:stylesheet>
</xsl:stylesheet>
Loading

0 comments on commit eb13e20

Please sign in to comment.