Modifications pour le document Solr Search Macros
Modifié par Florent Charton le 2026/03/13 11:04
Depuis la version 5.1
modifié par Florent Charton
sur 2026/03/13 11:04
sur 2026/03/13 11:04
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/17.10.4]
À la version 3.1
modifié par Florent Charton
sur 2026/01/08 10:59
sur 2026/01/08 10:59
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/17.4.8]
Résumé
-
Propriétés de la Page (1 modifications, 0 ajouts, 0 suppressions)
Détails
- Propriétés de la Page
-
- Contenu
-
... ... @@ -4,11 +4,13 @@ 4 4 #set ($rangePattern = $regextool.compile('^[\[{](.+) TO (.+)[\]}]$')) 5 5 #set ($wildcardPattern = $regextool.compile('^\(.*\*.*\)$')) 6 6 7 -#macro ( _displaySearchFormBegin)7 +#macro (displaySearchForm) 8 8 #set($void = $services.progress.startStep('#displaySearchForm')) 9 9 {{html clean="false"}} 10 - <form class="search-form" action="$doc.getURL()" role="search"> 10 + <form class="search-form row" action="$doc.getURL()" role="search"> 11 11 <div class="hidden"> 12 + <input type="hidden" name="sort" value="$!escapetool.xml($sort)"/> 13 + <input type="hidden" name="sortOrder" value="$!escapetool.xml($sortOrder)"/> 12 12 <input type="hidden" name="highlight" value="$highlightEnabled"/> 13 13 <input type="hidden" name="facet" value="$facetEnabled"/> 14 14 ## The parameter used to determine if the request has been redirected with default search filters. ... ... @@ -25,36 +25,27 @@ 25 25 #end 26 26 #end 27 27 </div> 28 - <div class="s earch-bar">30 + <div class="col-xs-12 col-sm-6"> 29 29 <div class="input-group"> 30 - <input id="search-page-bar-input" type="search" name="text" class="form-control" 31 - title="$escapetool.xml($services.localization.render('search.page.bar.query.title'))" 32 - placeholder="$escapetool.xml($services.localization.render('search.page.bar.query.title'))" 33 - value="$escapetool.xml($text)"/> 34 34 <label class='sr-only' for='search-page-bar-input'> 35 - $escapetool.xml($services.localization.render('search.page.bar.query.title'))33 + $services.localization.render('search.page.bar.query.title') 36 36 </label> 35 + <input id='search-page-bar-input' type='search' name='text' class='form-control' 36 + placeholder="$services.localization.render('search.page.bar.query.title')" 37 + title="$services.localization.render('search.page.bar.query.title')" value="$escapetool.xml($text)"/> 37 37 <span class="input-group-btn"> 38 38 <button type="submit" class="btn btn-primary"> 39 39 $services.icon.renderHTML('search') 40 - <span >$escapetool.xml($services.localization.render('search.page.bar.submit'))</span>41 + <span class="sr-only">$services.localization.render('search.page.bar.submit')</span> 41 41 </button> 42 42 </span> 43 43 </div> 44 44 </div> 46 + </form> 45 45 {{/html}} 46 46 #set($void = $services.progress.endStep()) 47 47 #end 48 48 49 -## We make sure the html block in this macro is not considered as inline to avoid generating extra `p` tags. 50 -#macro (_displaySearchFormEnd) 51 - 52 - {{html clean="false"}} 53 - </form> 54 - {{/html}} 55 - 56 -#end 57 - 58 58 #macro (displaySearchDebugInfo) 59 59 (% class="search-debug" %)((( 60 60 === Debug Information === ... ... @@ -119,12 +119,12 @@ 119 119 #end 120 120 #extendQueryString($url $resetParameters) 121 121 [[{{translation key="solr.facets.resetAll"}}>>path:$url 122 - ||class="search-facets-action-reset force-no-underline"]]## Continue in the same paragraph.115 + ||class="search-facets-action-reset"]]## Continue in the same paragraph. 123 123 {{html clean="false"}} 124 - <a href="#" class="search-facets-action-collapseAll hidden force-no-underline">117 + <a href="#" class="search-facets-action-collapseAll hidden"> 125 125 $escapetool.xml($services.localization.render('solr.facets.collapseAll')) 126 126 </a> 127 - <a href="#" class="search-facets-action-expandAll hidden force-no-underline">120 + <a href="#" class="search-facets-action-expandAll hidden"> 128 128 $escapetool.xml($services.localization.render('solr.facets.expandAll')) 129 129 </a> 130 130 <span class="clearfloats"></span> ... ... @@ -156,10 +156,9 @@ 156 156 ## Show active facets (that have selected values or that have an explicit limit on the number of values, i.e. 157 157 ## pagination) as expanded. Collapse the rest, otherwise you have to scroll to see all the available facets. 158 158 #set ($facetValuesLimit = $request.getParameter("l_$facetField.name")) 159 - <div class="search-facet" data-name="$facetField.name"> 160 - #set ($expanded = ($facetRequestValues || $facetValuesLimit)) 161 - #displaySearchFacetHeader($facetField $expanded) 162 - #displaySearchFacetBody($facetField $expanded) 152 + <div class="search-facet#if ($facetRequestValues || $facetValuesLimit) expanded#end" data-name="$facetField.name"> 153 + #displaySearchFacetHeader($facetField) 154 + #displaySearchFacetBody($facetField) 163 163 </div> 164 164 #end 165 165 #end ... ... @@ -176,7 +176,7 @@ 176 176 #setVariable("$property" $classDocument.xWikiClass.get($classPropertyReference.name)) 177 177 #end 178 178 179 -#macro (displaySearchFacetHeader $facetField $expanded)171 +#macro (displaySearchFacetHeader $facetField) 180 180 #set ($facetPrettyNameKey = "solr.field.$facetField.name") 181 181 #if ($services.localization.get($facetPrettyNameKey)) 182 182 #set ($facetPrettyName = $services.localization.render($facetPrettyNameKey)) ... ... @@ -191,21 +191,17 @@ 191 191 #set ($facetPrettyName = $facetField.name) 192 192 #end 193 193 <div class="search-facet-header"> 194 - <label>$escapetool.xml($facetPrettyName) 195 - <button class="btn btn-xs facet-toggle#if(!$expanded) collapsed#end" 196 - type="button" 197 - data-toggle="collapse" 198 - data-target="#$escapetool.xml($facetField.name)-dropdown" 199 - aria-expanded="$expanded" 200 - aria-controls="$escapetool.xml($facetField.name)-dropdown"> 186 + <span id="$escapetool.xml($facetField.name)-toggler-hint">$escapetool.xml($facetPrettyName)</span> 187 + <button class="btn btn-xs facet-toggler" 188 + aria-controls="$escapetool.xml($facetField.name)-dropdown" 189 + aria-labelledby="$escapetool.xml($facetField.name)-toggler-hint"> 201 201 $services.icon.renderHTML('caret-down') 202 202 </button> 203 - </label> 204 204 </div> 205 205 #end 206 206 207 -#macro (displaySearchFacetBody $facetField $expanded)208 - <div id="$escapetool.xml($facetField.name)-dropdown" class="search-facet-body collapse#if($expanded) in#end">195 +#macro (displaySearchFacetBody $facetField) 196 + <div id="$escapetool.xml($facetField.name)-dropdown" class="search-facet-body"> 209 209 #set ($facetDisplayer = $solrConfig.facetDisplayers.get($facetField.name)) 210 210 #if (!$facetDisplayer && $facetField.name.startsWith('property.')) 211 211 ## Choose a facet displayer based on the property type. ... ... @@ -258,7 +258,7 @@ 258 258 #displaySearchFacetValue($facetValue $customQueryStringParameters $customValueDisplayer false) 259 259 #end 260 260 261 -#macro (displaySearchFacetValue $facetValue $customQueryStringParameters $customValueDisplayer $displayToggle) 249 +#macro (displaySearchFacetValue $facetValue $customQueryStringParameters $customValueDisplayer $displayToggler) 262 262 #set ($selectedValues = []) 263 263 #if ($facetRequestValues) 264 264 #set ($discard = $selectedValues.addAll($facetRequestValues.subList(0, $facetRequestValues.size()))) ... ... @@ -273,8 +273,7 @@ 273 273 #set ($discard = $queryStringParameters.putAll($customQueryStringParameters)) 274 274 #end 275 275 #extendQueryString($url $queryStringParameters) 276 - <a href="$url" class="itemName#if ($selected) selected#end#if ($facetValue.name == '') empty#end" 277 - #if ($facetValue.name != '')data-facetvalue="$escapetool.xml($facetValue.name)"#end> 264 + <a href="$url" class="itemName#if ($selected) selected#end#if ($facetValue.name == '') empty#end"> 278 278 #if ($facetValue.name == '') 279 279 #set ($facetPrettyValueKey = "solr.field.${facetField.name}.emptyValue") 280 280 #if (!$services.localization.get($facetPrettyValueKey)) ... ... @@ -291,8 +291,8 @@ 291 291 #end 292 292 </a> 293 293 <div class="itemCount">$facetValue.count</div> 294 - #if ($displayToggle) 295 - <button class="btn btn-xs facet-value-toggle"> 281 + #if ($displayToggler) 282 + <button class="btn btn-xs facet-value-toggler"> 296 296 <span class='sr-only'>$escapetool.xml($facetPrettyValue)</span> 297 297 $services.icon.renderHTML('caret-down') 298 298 </button> ... ... @@ -319,7 +319,7 @@ 319 319 #end 320 320 #end 321 321 322 -#macro ( _displaySearchResultsControls)309 +#macro (displaySearchResultsSort) 323 323 #set ($defaultSortOrder = $solrConfig.sortFields.get($type)) 324 324 #if (!$defaultSortOrder) 325 325 #set ($defaultSortOrder = {'score': 'desc'}) ... ... @@ -328,63 +328,28 @@ 328 328 'asc': $services.icon.render('caret-up'), 329 329 'desc': $services.icon.render('caret-down') 330 330 }) 331 - (% class='search-results-controls' %) 332 - ((( 318 + (% class="search-options" %) 319 + * {{translation key="solr.options"/}} 320 + #if($highlightEnabled)#extendQueryString($url {'highlight': [false]})#else#extendQueryString($url {'highlight': [true]})#end 321 + * [[{{translation key="solr.options.highlight"/}}>>path:${url}||class="options-item#if($highlightEnabled) active#end" title="$services.localization.render('solr.options.highlight.title')"]] 322 + #if($facetEnabled)#extendQueryString($url {'facet': [false]})#else#extendQueryString($url {'facet': [true]})#end 323 + * [[{{translation key="solr.options.facet"/}}>>path:${url}||class="options-item#if($facetEnabled) active#end" title="$services.localization.render('solr.options.facet.title')"]] 333 333 334 - {{html clean="false"}} 335 - <div class="search-results-sort"> 336 - <label for="sort-by-input" class="sr-only">$escapetool.xml($services.localization.render('search.solr.sortBy.hint'))</label>## 337 - <select id="sort-by-input" name="sort"> 338 - #foreach ($entry in $defaultSortOrder.entrySet()) 339 - <option class="sort-item" value="$entry.key" #if($sort == $entry.key)selected='selected'#end> 340 - #set ($sortOptionNameList = $entry.key.split('_')) 341 - #set ($camelCasedSortOptionName = $sortOptionNameList.get(0)) 342 - #foreach ($namePart in $sortOptionNameList.subList(1, $sortOptionNameList.size())) 343 - #set ($camelCasedSortOptionName = "${camelCasedSortOptionName}$stringtool.capitalize($namePart)") 344 - #end 345 - $escapetool.xml($services.localization.render("search.solr.sortBy.field.$camelCasedSortOptionName")) 346 - </option> 347 - #end 348 - </select>## 349 - <label class="form-control" title="$escapetool.xml($services.localization.render("search.solr.sortOrder.$sortOrder"))">## 350 - <input id="sort-order-input" type="checkbox" name="sortOrder" value="asc" #if ("$!sortOrder" == 'asc')checked="checked"#end/>## 351 - $services.icon.renderHTML('sort-descending')## 352 - $services.icon.renderHTML('sort-ascending')## 353 - <span class="sr-only">$escapetool.xml($services.localization.render("search.solr.sortOrder.$sortOrder"))</span>## 354 - </label>## 355 - </div> 356 - <div class="search-options"> 357 - <ul>## 358 - <li>## 359 - <label>## 360 - <input id="option-highlight-input" type="checkbox" class="options-item" value="true" 361 - data-query-name="highlight" 362 - aria-describedby="option-highlight-description" 363 - title="$escapetool.xml($services.localization.render('solr.options.highlight.title'))" 364 - #if($highlightEnabled)checked#end/>## 365 - $escapetool.xml($services.localization.render('search.solr.options.showHighlight'))## 366 - </label>## 367 - <span id="option-highlight-description" class="sr-only"> 368 - $escapetool.xml($services.localization.render('solr.options.highlight.title')) 369 - </span>## 370 - </li>## 371 - <li>## 372 - <label>## 373 - <input id="option-facet-input" type="checkbox" class="options-item" value="true" data-query-name="facet" 374 - aria-describedby="option-facet-description" 375 - title="$escapetool.xml($services.localization.render('solr.options.facet.title'))" 376 - #if($facetEnabled)checked#end/>## 377 - $escapetool.xml($services.localization.render('search.solr.options.showFacet')) 378 - </label>## 379 - <span id="option-facet-description" class="sr-only"> 380 - $escapetool.xml($services.localization.render('solr.options.facet.title')) 381 - </span>## 382 - </li>## 383 - </ul>## 384 - </div> 385 - {{/html}} 386 - 387 - ))) 325 + (% class="search-results-sort" %) 326 + * {{translation key="solr.sortBy"/}} 327 + #foreach ($entry in $defaultSortOrder.entrySet()) 328 + #set ($class = 'sort-item') 329 + #set ($sortOrderIndicator = $NULL) 330 + #set ($targetSortOrder = $entry.value) 331 + #if ($sort == $entry.key) 332 + #set ($class = "$class active") 333 + #set ($sortOrderHint = $services.localization.render("solr.sortOrder.$sortOrder")) 334 + #set ($sortOrderIndicator = "(% class=""sort-item-order"" title=""$sortOrderHint"" %)$sortOrderSymbol.get($sortOrder)(%%)") 335 + #set ($targetSortOrder = "#if ($sortOrder == 'asc')desc#{else}asc#end") 336 + #end 337 + #extendQueryString($url {'sort': [$entry.key], 'sortOrder': [$targetSortOrder]}) 338 + * [[{{translation key="solr.sortBy.$entry.key"/}}$!sortOrderIndicator>>path:${url}||class="$class"]] 339 + #end 388 388 #end 389 389 390 390 #macro (extendQueryString $url $extraParameters) ... ... @@ -429,8 +429,7 @@ 429 429 ## Add the parameters required to output the RSS feed instead of the search UI. 430 430 #set ($discard = $parameters.put('outputSyntax', 'plain')) 431 431 #set ($discard = $parameters.put('media', 'rss')) 432 - <a href="$doc.getURL('get', $escapetool.url($parameters))"> 433 - $services.icon.renderHTML('rss') 384 + <a href="$doc.getURL('get', $escapetool.url($parameters))" class="hasIcon iconRSS"> 434 434 $services.localization.render('search.rss', ["[$escapetool.xml($text)]"]) 435 435 </a> 436 436 {{/html}} ... ... @@ -462,7 +462,7 @@ 462 462 #displaySearchResultLocation() 463 463 <div class="search-result-author"> 464 464 $services.localization.render('core.footer.modification', [ 465 - "#displayUser($searchResult.author {'useInlineHTML':true})",416 + "#displayUserProfileLink($searchResult.author $searchResult.author_display)", 466 466 $xwiki.formatDate($searchResult.date) 467 467 ]) 468 468 </div> ... ... @@ -484,7 +484,7 @@ 484 484 </h2> 485 485 #displaySearchResultLocation($searchResult) 486 486 <div class="search-result-uploader"> 487 - #set ($uploader = "#displayUser($searchResult.attauthor.get(0) {'useInlineHTML':true})")438 + #set ($uploader = "#displayUserProfileLink($searchResult.attauthor.get(0) $searchResult.attauthor_display.get(0))") 488 488 #set ($uploadDate = $xwiki.formatDate($searchResult.attdate.get(0))) 489 489 #set ($fileSize = "#dynamicsize($searchResult.attsize.get(0))") 490 490 $services.localization.render('solr.result.uploadedBy', [$uploader, $uploadDate, $fileSize]) ... ... @@ -535,6 +535,15 @@ 535 535 </div> 536 536 #end 537 537 489 +#macro (displayUserProfileLink $userReference $userName) 490 +#if ($userReference) 491 +## We could test if the specified user exists but we want to speed up the search. 492 +<a href="$xwiki.getURL($userReference)">$escapetool.xml($userName)</a>## 493 +#else 494 +$services.localization.render('core.users.unknownUser')## 495 +#end 496 +#end 497 + 538 538 #macro (displaySearchResultHighlighting $searchResult) 539 539 #getSearchResultHighlighting($searchResult $highlighting) 540 540 #if ($highlighting.size() > 0) ... ... @@ -558,10 +558,12 @@ 558 558 #end 559 559 </dl> 560 560 #if ($highlighting.size() > 1) 561 - <button class="search-result-highlightAll btn btn-xs btn-default hidden"> 562 - $escapetool.xml($services.localization.render('solr.result.highlightAll')) 563 - $services.icon.renderHTML('right') 564 - </button> 521 + ## We wrap the link in a DIV because otherwise the HTML cleaning generates a paragraph. 522 + <div> 523 + <a href="#" class="search-result-highlightAll hidden"> 524 + $escapetool.xml($services.localization.render('solr.result.highlightAll')) 525 + </a> 526 + </div> 565 565 #end 566 566 #end 567 567 #end ... ... @@ -633,10 +633,9 @@ 633 633 ## Set query parameters. 634 634 #set ($discard = $query.setLimit($rows)) 635 635 #set ($discard = $query.setOffset($start)) 636 - #set ($discard = $query.addFilter('searchExclusions/solr')) 637 637 #set ($discard = $query.bindValue('sort', "${sort} ${sortOrder}")) 638 638 #set ($discard = $query.bindValue('tie', $solrConfig.tieBreaker)) 639 - #set ($discard = $query.bindValue('mm', $solrConfig.minShouldMatch)) 600 + #set ($discard = $query.bindValue('mm', $solrConfig.minShouldMatch)) 640 640 #setQueryFields($query) 641 641 #setPhraseFields($query) 642 642 #setFacetFields($query) ... ... @@ -849,8 +849,6 @@ 849 849 #if ("$!sort" == '') 850 850 #set ($sort = 'score') 851 851 #end 852 - ## If at any point this default behavior is changed, be extra careful with "#sort-order-input" initialization. 853 - ## We assume here that empty values are mapped to "desc" (meaning that we use "asc" as the checkbox value). 854 854 #set ($sortOrder = $request.sortOrder) 855 855 #if ("$!sortOrder" == '') 856 856 #set ($sortOrder = 'desc') ... ... @@ -892,15 +892,12 @@ 892 892 {{/html}} 893 893 894 894 #end 895 - # _displaySearchFormBegin()854 + #displaySearchForm() 896 896 #if ($text != '') 897 897 #getSearchResults() 898 - #_displaySearchResultsControls() 899 - #_displaySearchFormEnd() 900 900 #if ($debug) 901 901 #displaySearchDebugInfo() 902 902 #end 903 - 904 904 (% class="search-results-container row" %)((( 905 905 #if ($facetEnabled) 906 906 (% class="col-xs-12 col-sm-4 col-sm-push-8 col-md-3 col-md-push-9" %)((( ... ... @@ -909,11 +909,11 @@ 909 909 #end 910 910 (% class="search-results-left col-xs-12#if ($facetEnabled) col-sm-8 col-sm-pull-4 col-md-9 col-md-pull-3#end" %) 911 911 ((( 868 + #displaySearchResultsSort() 869 + 912 912 #displaySearchResults() 913 913 ))) 914 914 ))) 915 - #else 916 - #_displaySearchFormEnd() 917 917 #end 918 918 ))) 919 919 #set($void = $services.progress.popLevel())