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
Commentaire de modification : Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/17.10.4]
À la version 2.1
modifié par Florent Charton
sur 2024/08/08 18:44
Commentaire de modification : Install extension [org.xwiki.platform:xwiki-platform-search-solr-ui/15.10.11]

Résumé

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,26 @@
25 25   #end
26 26   #end
27 27   </div>
28 - <div class="search-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 withTip useTitleAsTip'
36 + 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>
40 + <span class="sr-only">$services.localization.render('search.page.bar.submit')</span>
41 41   </button>
42 42   </span>
43 43   </div>
44 44   </div>
45 + </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.
114 + ||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">
116 + <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">
119 + <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)
151 + <div class="search-facet#if ($facetRequestValues || $facetValuesLimit) expanded#end" data-name="$facetField.name">
152 + #displaySearchFacetHeader($facetField)
153 + #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)
170 +#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">
185 + <span id="$escapetool.xml($facetField.name)-toggler-hint">$escapetool.xml($facetPrettyName)</span>
186 + <button class="btn btn-xs facet-toggler"
187 + aria-controls="$escapetool.xml($facetField.name)-dropdown"
188 + 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">
194 +#macro (displaySearchFacetBody $facetField)
195 + <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)
248 +#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>
263 + <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">
280 + #if ($displayToggler)
281 + <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)
308 +#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 - (((
317 + (% class="search-options" %)
318 + * {{translation key="solr.options"/}}
319 + #if($highlightEnabled)#extendQueryString($url {'highlight': [false]})#else#extendQueryString($url {'highlight': [true]})#end
320 + * [[{{translation key="solr.options.highlight"/}}>>path:${url}||class="options-item#if($highlightEnabled) active#end" title="$services.localization.render('solr.options.highlight.title')"]]
321 + #if($facetEnabled)#extendQueryString($url {'facet': [false]})#else#extendQueryString($url {'facet': [true]})#end
322 + * [[{{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 - )))
324 + (% class="search-results-sort" %)
325 + * {{translation key="solr.sortBy"/}}
326 + #foreach ($entry in $defaultSortOrder.entrySet())
327 + #set ($class = 'sort-item')
328 + #set ($sortOrderIndicator = $NULL)
329 + #set ($targetSortOrder = $entry.value)
330 + #if ($sort == $entry.key)
331 + #set ($class = "$class active")
332 + #set ($sortOrderHint = $services.localization.render("solr.sortOrder.$sortOrder"))
333 + #set ($sortOrderIndicator = "(% class=""sort-item-order"" title=""$sortOrderHint"" %)$sortOrderSymbol.get($sortOrder)(%%)")
334 + #set ($targetSortOrder = "#if ($sortOrder == 'asc')desc#{else}asc#end")
335 + #end
336 + #extendQueryString($url {'sort': [$entry.key], 'sortOrder': [$targetSortOrder]})
337 + * [[{{translation key="solr.sortBy.$entry.key"/}}$!sortOrderIndicator>>path:${url}||class="$class"]]
338 + #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')
383 + <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})",
415 + "#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})")
437 + #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  
488 +#macro (displayUserProfileLink $userReference $userName)
489 +#if ($userReference)
490 +## We could test if the specified user exists but we want to speed up the search.
491 +<a href="$xwiki.getURL($userReference)">$escapetool.xml($userName)</a>##
492 +#else
493 +$services.localization.render('core.users.unknownUser')##
494 +#end
495 +#end
496 +
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>
520 + ## We wrap the link in a DIV because otherwise the HTML cleaning generates a paragraph.
521 + <div>
522 + <a href="#" class="search-result-highlightAll hidden">
523 + $escapetool.xml($services.localization.render('solr.result.highlightAll'))
524 + </a>
525 + </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))
599 + #set ($discard = $query.bindValue('mm', $solrConfig.minShouldMatch))
640 640   #setQueryFields($query)
641 641   #setPhraseFields($query)
642 642   #setFacetFields($query)
... ... @@ -838,7 +838,10 @@
838 838   #end
839 839   ##
840 840   ## Pagination
841 - #getAndValidateQueryLimitFromRequest('rows', 10, $rows)
801 + #set ($rows = $numbertool.toNumber($request.rows).intValue())
802 + #if ("$!rows" == '')
803 + #set ($rows = 10)
804 + #end
842 842   #set ($start = $numbertool.toNumber($request.firstIndex).intValue())
843 843   #if ("$!start" == '')
844 844   #set ($start = 0)
... ... @@ -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()
856 + #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   (((
870 + #displaySearchResultsSort()
871 +
912 912   #displaySearchResults()
913 913   )))
914 914   )))
915 - #else
916 - #_displaySearchFormEnd()
917 917   #end
918 918   )))
919 919   #set($void = $services.progress.popLevel())