Modifications pour le document Solr Search Macros
Modifié par Florent Charton le 2026/03/13 11:04
Depuis la version 1.1
modifié par superadmin
sur 2022/06/20 08:49
sur 2022/06/20 08:49
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/13.10.6]
À la version 4.1
modifié par Florent Charton
sur 2026/01/13 15:01
sur 2026/01/13 15:01
Commentaire de modification :
Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/17.10.2]
Résumé
-
Propriétés de la Page (2 modifications, 0 ajouts, 0 suppressions)
Détails
- Propriétés de la Page
-
- Auteur du document
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki. superadmin1 +xwiki:XWiki.fcharton - Contenu
-
... ... @@ -4,13 +4,11 @@ 4 4 #set ($rangePattern = $regextool.compile('^[\[{](.+) TO (.+)[\]}]$')) 5 5 #set ($wildcardPattern = $regextool.compile('^\(.*\*.*\)$')) 6 6 7 -#macro (displaySearchForm) 7 +#macro (_displaySearchFormBegin) 8 8 #set($void = $services.progress.startStep('#displaySearchForm')) 9 9 {{html clean="false"}} 10 - <form class="search-form row" action="$doc.getURL()" role="search">10 + <form class="search-form" 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)"/> 14 14 <input type="hidden" name="highlight" value="$highlightEnabled"/> 15 15 <input type="hidden" name="facet" value="$facetEnabled"/> 16 16 ## The parameter used to determine if the request has been redirected with default search filters. ... ... @@ -27,23 +27,36 @@ 27 27 #end 28 28 #end 29 29 </div> 30 - <div class=" col-xs-12col-sm-6">28 + <div class="search-bar"> 31 31 <div class="input-group"> 32 - <input type="search" name="text" class="form-control withTip useTitleAsTip" 33 - title="$services.localization.render('search.page.bar.query.title')" value="$escapetool.xml($text)"/> 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 + <label class='sr-only' for='search-page-bar-input'> 35 + $escapetool.xml($services.localization.render('search.page.bar.query.title')) 36 + </label> 34 34 <span class="input-group-btn"> 35 35 <button type="submit" class="btn btn-primary"> 36 36 $services.icon.renderHTML('search') 37 - <span class="sr-only">$services.localization.render('search.page.bar.submit')</span>40 + <span>$escapetool.xml($services.localization.render('search.page.bar.submit'))</span> 38 38 </button> 39 39 </span> 40 40 </div> 41 41 </div> 42 - </form> 43 43 {{/html}} 44 44 #set($void = $services.progress.endStep()) 45 45 #end 46 46 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 + 47 47 #macro (displaySearchDebugInfo) 48 48 (% class="search-debug" %)((( 49 49 === Debug Information === ... ... @@ -108,12 +108,12 @@ 108 108 #end 109 109 #extendQueryString($url $resetParameters) 110 110 [[{{translation key="solr.facets.resetAll"}}>>path:$url 111 - ||class="search-facets-action-reset"]]## Continue in the same paragraph. 122 + ||class="search-facets-action-reset force-no-underline"]]## Continue in the same paragraph. 112 112 {{html clean="false"}} 113 - <a href="#" class="search-facets-action-collapseAll hidden"> 124 + <a href="#" class="search-facets-action-collapseAll hidden force-no-underline"> 114 114 $escapetool.xml($services.localization.render('solr.facets.collapseAll')) 115 115 </a> 116 - <a href="#" class="search-facets-action-expandAll hidden"> 127 + <a href="#" class="search-facets-action-expandAll hidden force-no-underline"> 117 117 $escapetool.xml($services.localization.render('solr.facets.expandAll')) 118 118 </a> 119 119 <span class="clearfloats"></span> ... ... @@ -178,11 +178,18 @@ 178 178 #else 179 179 #set ($facetPrettyName = $facetField.name) 180 180 #end 181 - <div class="search-facet-header">$escapetool.xml($facetPrettyName)</div> 192 + <div class="search-facet-header"> 193 + <label>$escapetool.xml($facetPrettyName) 194 + <button class="btn btn-xs facet-toggle" 195 + aria-controls="$escapetool.xml($facetField.name)-dropdown"> 196 + $services.icon.renderHTML('caret-down') 197 + </button> 198 + </label> 199 + </div> 182 182 #end 183 183 184 184 #macro (displaySearchFacetBody $facetField) 185 - <div class="search-facet-body"> 203 + <div id="$escapetool.xml($facetField.name)-dropdown" class="search-facet-body"> 186 186 #set ($facetDisplayer = $solrConfig.facetDisplayers.get($facetField.name)) 187 187 #if (!$facetDisplayer && $facetField.name.startsWith('property.')) 188 188 ## Choose a facet displayer based on the property type. ... ... @@ -232,6 +232,10 @@ 232 232 #end 233 233 234 234 #macro (displaySearchFacetValue $facetValue $customQueryStringParameters $customValueDisplayer) 253 + #displaySearchFacetValue($facetValue $customQueryStringParameters $customValueDisplayer false) 254 +#end 255 + 256 +#macro (displaySearchFacetValue $facetValue $customQueryStringParameters $customValueDisplayer $displayToggle) 235 235 #set ($selectedValues = []) 236 236 #if ($facetRequestValues) 237 237 #set ($discard = $selectedValues.addAll($facetRequestValues.subList(0, $facetRequestValues.size()))) ... ... @@ -246,8 +246,8 @@ 246 246 #set ($discard = $queryStringParameters.putAll($customQueryStringParameters)) 247 247 #end 248 248 #extendQueryString($url $queryStringParameters) 249 - < divclass="itemCount">$facetValue.count</div>250 - <ahref="$url"class="itemName#if ($selected)selected#end#if($facetValue.name== '')empty#end">271 + <a href="$url" class="itemName#if ($selected) selected#end#if ($facetValue.name == '') empty#end" 272 + #if ($facetValue.name != '')data-facetvalue="$escapetool.xml($facetValue.name)"#end> 251 251 #if ($facetValue.name == '') 252 252 #set ($facetPrettyValueKey = "solr.field.${facetField.name}.emptyValue") 253 253 #if (!$services.localization.get($facetPrettyValueKey)) ... ... @@ -263,7 +263,13 @@ 263 263 $escapetool.xml($facetPrettyValue) 264 264 #end 265 265 </a> 266 - <div class="clearfloats"></div> 288 + <div class="itemCount">$facetValue.count</div> 289 + #if ($displayToggle) 290 + <button class="btn btn-xs facet-value-toggle"> 291 + <span class='sr-only'>$escapetool.xml($facetPrettyValue)</span> 292 + $services.icon.renderHTML('caret-down') 293 + </button> 294 + #end 267 267 #end 268 268 269 269 #** ... ... @@ -286,7 +286,7 @@ 286 286 #end 287 287 #end 288 288 289 -#macro (displaySearchResults Sort)317 +#macro (_displaySearchResultsControls) 290 290 #set ($defaultSortOrder = $solrConfig.sortFields.get($type)) 291 291 #if (!$defaultSortOrder) 292 292 #set ($defaultSortOrder = {'score': 'desc'}) ... ... @@ -295,28 +295,63 @@ 295 295 'asc': $services.icon.render('caret-up'), 296 296 'desc': $services.icon.render('caret-down') 297 297 }) 298 - (% class="search-options" %) 299 - * {{translation key="solr.options"/}} 300 - #if($highlightEnabled)#extendQueryString($url {'highlight': [false]})#else#extendQueryString($url {'highlight': [true]})#end 301 - * [[{{translation key="solr.options.highlight"/}}>>path:${url}||class="options-item#if($highlightEnabled) active#end" title="$services.localization.render('solr.options.highlight.title')"]] 302 - #if($facetEnabled)#extendQueryString($url {'facet': [false]})#else#extendQueryString($url {'facet': [true]})#end 303 - * [[{{translation key="solr.options.facet"/}}>>path:${url}||class="options-item#if($facetEnabled) active#end" title="$services.localization.render('solr.options.facet.title')"]] 326 + (% class='search-results-controls' %) 327 + ((( 304 304 305 - (% class="search-results-sort" %) 306 - * {{translation key="solr.sortBy"/}} 307 - #foreach ($entry in $defaultSortOrder.entrySet()) 308 - #set ($class = 'sort-item') 309 - #set ($sortOrderIndicator = $NULL) 310 - #set ($targetSortOrder = $entry.value) 311 - #if ($sort == $entry.key) 312 - #set ($class = "$class active") 313 - #set ($sortOrderHint = $services.localization.render("solr.sortOrder.$sortOrder")) 314 - #set ($sortOrderIndicator = "(% class=""sort-item-order"" title=""$sortOrderHint"" %)$sortOrderSymbol.get($sortOrder)(%%)") 315 - #set ($targetSortOrder = "#if ($sortOrder == 'asc')desc#{else}asc#end") 316 - #end 317 - #extendQueryString($url {'sort': [$entry.key], 'sortOrder': [$targetSortOrder]}) 318 - * [[{{translation key="solr.sortBy.$entry.key"/}}$!sortOrderIndicator>>path:${url}||class="$class"]] 319 - #end 329 + {{html clean="false"}} 330 + <div class="search-results-sort"> 331 + <label for="sort-by-input" class="sr-only">$escapetool.xml($services.localization.render('search.solr.sortBy.hint'))</label>## 332 + <select id="sort-by-input" name="sort"> 333 + #foreach ($entry in $defaultSortOrder.entrySet()) 334 + <option class="sort-item" value="$entry.key" #if($sort == $entry.key)selected='selected'#end> 335 + #set ($sortOptionNameList = $entry.key.split('_')) 336 + #set ($camelCasedSortOptionName = $sortOptionNameList.get(0)) 337 + #foreach ($namePart in $sortOptionNameList.subList(1, $sortOptionNameList.size())) 338 + #set ($camelCasedSortOptionName = "${camelCasedSortOptionName}$stringtool.capitalize($namePart)") 339 + #end 340 + $escapetool.xml($services.localization.render("search.solr.sortBy.field.$camelCasedSortOptionName")) 341 + </option> 342 + #end 343 + </select>## 344 + <label class="form-control" title="$escapetool.xml($services.localization.render("search.solr.sortOrder.$sortOrder"))">## 345 + <input id="sort-order-input" type="checkbox" name="sortOrder" value="asc" #if ("$!sortOrder" == 'asc')checked="checked"#end/>## 346 + $services.icon.renderHTML('sort-descending')## 347 + $services.icon.renderHTML('sort-ascending')## 348 + <span class="sr-only">$escapetool.xml($services.localization.render("search.solr.sortOrder.$sortOrder"))</span>## 349 + </label>## 350 + </div> 351 + <div class="search-options"> 352 + <ul>## 353 + <li>## 354 + <label>## 355 + <input id="option-highlight-input" type="checkbox" class="options-item" value="true" 356 + data-query-name="highlight" 357 + aria-describedby="option-highlight-description" 358 + title="$escapetool.xml($services.localization.render('solr.options.highlight.title'))" 359 + #if($highlightEnabled)checked#end/>## 360 + $escapetool.xml($services.localization.render('search.solr.options.showHighlight'))## 361 + </label>## 362 + <span id="option-highlight-description" class="sr-only"> 363 + $escapetool.xml($services.localization.render('solr.options.highlight.title')) 364 + </span>## 365 + </li>## 366 + <li>## 367 + <label>## 368 + <input id="option-facet-input" type="checkbox" class="options-item" value="true" data-query-name="facet" 369 + aria-describedby="option-facet-description" 370 + title="$escapetool.xml($services.localization.render('solr.options.facet.title'))" 371 + #if($facetEnabled)checked#end/>## 372 + $escapetool.xml($services.localization.render('search.solr.options.showFacet')) 373 + </label>## 374 + <span id="option-facet-description" class="sr-only"> 375 + $escapetool.xml($services.localization.render('solr.options.facet.title')) 376 + </span>## 377 + </li>## 378 + </ul>## 379 + </div> 380 + {{/html}} 381 + 382 + ))) 320 320 #end 321 321 322 322 #macro (extendQueryString $url $extraParameters) ... ... @@ -361,7 +361,8 @@ 361 361 ## Add the parameters required to output the RSS feed instead of the search UI. 362 362 #set ($discard = $parameters.put('outputSyntax', 'plain')) 363 363 #set ($discard = $parameters.put('media', 'rss')) 364 - <a href="$doc.getURL('get', $escapetool.url($parameters))" class="hasIcon iconRSS"> 427 + <a href="$doc.getURL('get', $escapetool.url($parameters))"> 428 + $services.icon.renderHTML('rss') 365 365 $services.localization.render('search.rss', ["[$escapetool.xml($text)]"]) 366 366 </a> 367 367 {{/html}} ... ... @@ -393,7 +393,7 @@ 393 393 #displaySearchResultLocation() 394 394 <div class="search-result-author"> 395 395 $services.localization.render('core.footer.modification', [ 396 - "#displayUser ProfileLink($searchResult.author$searchResult.author_display)",460 + "#displayUser($searchResult.author {'useInlineHTML': true})", 397 397 $xwiki.formatDate($searchResult.date) 398 398 ]) 399 399 </div> ... ... @@ -415,7 +415,7 @@ 415 415 </h2> 416 416 #displaySearchResultLocation($searchResult) 417 417 <div class="search-result-uploader"> 418 - #set ($uploader = "#displayUser ProfileLink($searchResult.attauthor.get(0)$searchResult.attauthor_display.get(0))")482 + #set ($uploader = "#displayUser($searchResult.attauthor.get(0) {'useInlineHTML': true})") 419 419 #set ($uploadDate = $xwiki.formatDate($searchResult.attdate.get(0))) 420 420 #set ($fileSize = "#dynamicsize($searchResult.attsize.get(0))") 421 421 $services.localization.render('solr.result.uploadedBy', [$uploader, $uploadDate, $fileSize]) ... ... @@ -466,15 +466,6 @@ 466 466 </div> 467 467 #end 468 468 469 -#macro (displayUserProfileLink $userReference $userName) 470 -#if ($userReference) 471 -## We could test if the specified user exists but we want to speed up the search. 472 -<a href="$xwiki.getURL($userReference)">$escapetool.xml($userName)</a>## 473 -#else 474 -$services.localization.render('core.users.unknownUser')## 475 -#end 476 -#end 477 - 478 478 #macro (displaySearchResultHighlighting $searchResult) 479 479 #getSearchResultHighlighting($searchResult $highlighting) 480 480 #if ($highlighting.size() > 0) ... ... @@ -498,12 +498,10 @@ 498 498 #end 499 499 </dl> 500 500 #if ($highlighting.size() > 1) 501 - ## We wrap the link in a DIV because otherwise the HTML cleaning generates a paragraph. 502 - <div> 503 - <a href="#" class="search-result-highlightAll hidden"> 504 - $escapetool.xml($services.localization.render('solr.result.highlightAll')) 505 - </a> 506 - </div> 556 + <button class="search-result-highlightAll btn btn-xs btn-default hidden"> 557 + $escapetool.xml($services.localization.render('solr.result.highlightAll')) 558 + $services.icon.renderHTML('right') 559 + </button> 507 507 #end 508 508 #end 509 509 #end ... ... @@ -575,9 +575,10 @@ 575 575 ## Set query parameters. 576 576 #set ($discard = $query.setLimit($rows)) 577 577 #set ($discard = $query.setOffset($start)) 631 + #set ($discard = $query.addFilter('searchExclusions/solr')) 578 578 #set ($discard = $query.bindValue('sort', "${sort} ${sortOrder}")) 579 579 #set ($discard = $query.bindValue('tie', $solrConfig.tieBreaker)) 580 - #set ($discard = $query.bindValue('mm', $solrConfig.minShouldMatch)) 634 + #set ($discard = $query.bindValue('mm', $solrConfig.minShouldMatch)) 581 581 #setQueryFields($query) 582 582 #setPhraseFields($query) 583 583 #setFacetFields($query) ... ... @@ -779,10 +779,7 @@ 779 779 #end 780 780 ## 781 781 ## Pagination 782 - #set ($rows = $numbertool.toNumber($request.rows).intValue()) 783 - #if ("$!rows" == '') 784 - #set ($rows = 10) 785 - #end 836 + #getAndValidateQueryLimitFromRequest('rows', 10, $rows) 786 786 #set ($start = $numbertool.toNumber($request.firstIndex).intValue()) 787 787 #if ("$!start" == '') 788 788 #set ($start = 0) ... ... @@ -793,6 +793,8 @@ 793 793 #if ("$!sort" == '') 794 794 #set ($sort = 'score') 795 795 #end 847 + ## If at any point this default behavior is changed, be extra careful with "#sort-order-input" initialization. 848 + ## We assume here that empty values are mapped to "desc" (meaning that we use "asc" as the checkbox value). 796 796 #set ($sortOrder = $request.sortOrder) 797 797 #if ("$!sortOrder" == '') 798 798 #set ($sortOrder = 'desc') ... ... @@ -834,12 +834,15 @@ 834 834 {{/html}} 835 835 836 836 #end 837 - #displaySearchForm() 890 + #_displaySearchFormBegin() 838 838 #if ($text != '') 839 839 #getSearchResults() 893 + #_displaySearchResultsControls() 894 + #_displaySearchFormEnd() 840 840 #if ($debug) 841 841 #displaySearchDebugInfo() 842 842 #end 898 + 843 843 (% class="search-results-container row" %)((( 844 844 #if ($facetEnabled) 845 845 (% class="col-xs-12 col-sm-4 col-sm-push-8 col-md-3 col-md-push-9" %)((( ... ... @@ -848,11 +848,11 @@ 848 848 #end 849 849 (% class="search-results-left col-xs-12#if ($facetEnabled) col-sm-8 col-sm-pull-4 col-md-9 col-md-pull-3#end" %) 850 850 ((( 851 - #displaySearchResultsSort() 852 - 853 853 #displaySearchResults() 854 854 ))) 855 855 ))) 910 + #else 911 + #_displaySearchFormEnd() 856 856 #end 857 857 ))) 858 858 #set($void = $services.progress.popLevel()) ... ... @@ -894,8 +894,7 @@ 894 894 ## 895 895 ## Output the feed. 896 896 ## 897 - #set ($discard = $response.setContentType('application/rss+xml')) 898 - $xwiki.feed.getFeedOutput($feed, 'rss_2.0') 953 + #rawResponse($xwiki.feed.getFeedOutput($feed, 'rss_2.0'), 'application/rss+xml') 899 899 #end 900 900 901 901 #macro (handleSolrSearchRequest)