diff options
author | ArthurHoaro <arthur@hoa.ro> | 2016-02-23 19:21:14 +0100 |
---|---|---|
committer | ArthurHoaro <arthur@hoa.ro> | 2016-02-28 14:17:40 +0100 |
commit | c51fae92dc7d3080def81a2797e0d683b3e6d82a (patch) | |
tree | 394f9419589c1983d9be9834b89c8be2e8ef237c | |
parent | 6c3d6a31f413862941fe514e7167c04fe71ba1a7 (diff) | |
download | Shaarli-c51fae92dc7d3080def81a2797e0d683b3e6d82a.tar.gz Shaarli-c51fae92dc7d3080def81a2797e0d683b3e6d82a.tar.zst Shaarli-c51fae92dc7d3080def81a2797e0d683b3e6d82a.zip |
Allow crossed search between terms and tags
* Partial fix of #449
* Current use case: search term + click on tag.
* LinkFilter now returns all links if no filter is given.
* Unit tests.
-rw-r--r-- | application/LinkDB.php | 3 | ||||
-rw-r--r-- | application/LinkFilter.php | 27 | ||||
-rw-r--r-- | inc/shaarli.css | 4 | ||||
-rw-r--r-- | index.php | 120 | ||||
-rw-r--r-- | tests/LinkFilterTest.php | 51 | ||||
-rw-r--r-- | tpl/linklist.html | 38 |
6 files changed, 178 insertions, 65 deletions
diff --git a/application/LinkDB.php b/application/LinkDB.php index 9488ac45..1b505620 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php | |||
@@ -353,8 +353,7 @@ You use the community supported version of the original Shaarli project, by Seba | |||
353 | public function filter($type = '', $request = '', $casesensitive = false, $privateonly = false) | 353 | public function filter($type = '', $request = '', $casesensitive = false, $privateonly = false) |
354 | { | 354 | { |
355 | $linkFilter = new LinkFilter($this->_links); | 355 | $linkFilter = new LinkFilter($this->_links); |
356 | $requestFilter = is_array($request) ? implode(' ', $request) : $request; | 356 | return $linkFilter->filter($type, $request, $casesensitive, $privateonly); |
357 | return $linkFilter->filter($type, trim($requestFilter), $casesensitive, $privateonly); | ||
358 | } | 357 | } |
359 | 358 | ||
360 | /** | 359 | /** |
diff --git a/application/LinkFilter.php b/application/LinkFilter.php index 17594e8f..3fd803cb 100644 --- a/application/LinkFilter.php +++ b/application/LinkFilter.php | |||
@@ -55,16 +55,25 @@ class LinkFilter | |||
55 | switch($type) { | 55 | switch($type) { |
56 | case self::$FILTER_HASH: | 56 | case self::$FILTER_HASH: |
57 | return $this->filterSmallHash($request); | 57 | return $this->filterSmallHash($request); |
58 | break; | 58 | case self::$FILTER_TAG | self::$FILTER_TEXT: |
59 | if (!empty($request)) { | ||
60 | $filtered = $this->links; | ||
61 | if (isset($request[0])) { | ||
62 | $filtered = $this->filterTags($request[0], $casesensitive, $privateonly); | ||
63 | } | ||
64 | if (isset($request[1])) { | ||
65 | $lf = new LinkFilter($filtered); | ||
66 | $filtered = $lf->filterFulltext($request[1], $privateonly); | ||
67 | } | ||
68 | return $filtered; | ||
69 | } | ||
70 | return $this->noFilter($privateonly); | ||
59 | case self::$FILTER_TEXT: | 71 | case self::$FILTER_TEXT: |
60 | return $this->filterFulltext($request, $privateonly); | 72 | return $this->filterFulltext($request, $privateonly); |
61 | break; | ||
62 | case self::$FILTER_TAG: | 73 | case self::$FILTER_TAG: |
63 | return $this->filterTags($request, $casesensitive, $privateonly); | 74 | return $this->filterTags($request, $casesensitive, $privateonly); |
64 | break; | ||
65 | case self::$FILTER_DAY: | 75 | case self::$FILTER_DAY: |
66 | return $this->filterDay($request); | 76 | return $this->filterDay($request); |
67 | break; | ||
68 | default: | 77 | default: |
69 | return $this->noFilter($privateonly); | 78 | return $this->noFilter($privateonly); |
70 | } | 79 | } |
@@ -138,6 +147,10 @@ class LinkFilter | |||
138 | */ | 147 | */ |
139 | private function filterFulltext($searchterms, $privateonly = false) | 148 | private function filterFulltext($searchterms, $privateonly = false) |
140 | { | 149 | { |
150 | if (empty($searchterms)) { | ||
151 | return $this->links; | ||
152 | } | ||
153 | |||
141 | $filtered = array(); | 154 | $filtered = array(); |
142 | $search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8'); | 155 | $search = mb_convert_case(html_entity_decode($searchterms), MB_CASE_LOWER, 'UTF-8'); |
143 | $exactRegex = '/"([^"]+)"/'; | 156 | $exactRegex = '/"([^"]+)"/'; |
@@ -219,6 +232,12 @@ class LinkFilter | |||
219 | */ | 232 | */ |
220 | public function filterTags($tags, $casesensitive = false, $privateonly = false) | 233 | public function filterTags($tags, $casesensitive = false, $privateonly = false) |
221 | { | 234 | { |
235 | // Implode if array for clean up. | ||
236 | $tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags; | ||
237 | if (empty($tags)) { | ||
238 | return $this->links; | ||
239 | } | ||
240 | |||
222 | $searchtags = self::tagsStrToArray($tags, $casesensitive); | 241 | $searchtags = self::tagsStrToArray($tags, $casesensitive); |
223 | $filtered = array(); | 242 | $filtered = array(); |
224 | if (empty($searchtags)) { | 243 | if (empty($searchtags)) { |
diff --git a/inc/shaarli.css b/inc/shaarli.css index 8a7409b2..2e41988e 100644 --- a/inc/shaarli.css +++ b/inc/shaarli.css | |||
@@ -33,6 +33,10 @@ h1 { | |||
33 | margin-bottom: 20px; | 33 | margin-bottom: 20px; |
34 | } | 34 | } |
35 | 35 | ||
36 | em { | ||
37 | font-style: italic; | ||
38 | } | ||
39 | |||
36 | /* Buttons */ | 40 | /* Buttons */ |
37 | .bigbutton { | 41 | .bigbutton { |
38 | background-color: #c0c0c0; | 42 | background-color: #c0c0c0; |
@@ -623,7 +623,7 @@ class pageBuilder | |||
623 | if (!empty($_GET['searchtags'])) { | 623 | if (!empty($_GET['searchtags'])) { |
624 | $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']); | 624 | $searchcrits .= '&searchtags=' . urlencode($_GET['searchtags']); |
625 | } | 625 | } |
626 | elseif (!empty($_GET['searchterm'])) { | 626 | if (!empty($_GET['searchterm'])) { |
627 | $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']); | 627 | $searchcrits .= '&searchterm=' . urlencode($_GET['searchterm']); |
628 | } | 628 | } |
629 | $this->tpl->assign('searchcrits', $searchcrits); | 629 | $this->tpl->assign('searchcrits', $searchcrits); |
@@ -709,11 +709,19 @@ function showRSS() | |||
709 | // Read links from database (and filter private links if user it not logged in). | 709 | // Read links from database (and filter private links if user it not logged in). |
710 | 710 | ||
711 | // Optionally filter the results: | 711 | // Optionally filter the results: |
712 | if (!empty($_GET['searchterm'])) { | 712 | $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; |
713 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); | 713 | $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : ''; |
714 | if (! empty($searchtags) && ! empty($searchterm)) { | ||
715 | $linksToDisplay = $LINKSDB->filter( | ||
716 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
717 | array($searchtags, $searchterm) | ||
718 | ); | ||
714 | } | 719 | } |
715 | elseif (!empty($_GET['searchtags'])) { | 720 | elseif ($searchtags) { |
716 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); | 721 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags); |
722 | } | ||
723 | elseif ($searchterm) { | ||
724 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm); | ||
717 | } | 725 | } |
718 | else { | 726 | else { |
719 | $linksToDisplay = $LINKSDB; | 727 | $linksToDisplay = $LINKSDB; |
@@ -807,11 +815,19 @@ function showATOM() | |||
807 | ); | 815 | ); |
808 | 816 | ||
809 | // Optionally filter the results: | 817 | // Optionally filter the results: |
810 | if (!empty($_GET['searchterm'])) { | 818 | $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; |
811 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); | 819 | $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : ''; |
820 | if (! empty($searchtags) && ! empty($searchterm)) { | ||
821 | $linksToDisplay = $LINKSDB->filter( | ||
822 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
823 | array($searchtags, $searchterm) | ||
824 | ); | ||
812 | } | 825 | } |
813 | else if (!empty($_GET['searchtags'])) { | 826 | elseif ($searchtags) { |
814 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); | 827 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags); |
828 | } | ||
829 | elseif ($searchterm) { | ||
830 | $linksToDisplay = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm); | ||
815 | } | 831 | } |
816 | else { | 832 | else { |
817 | $linksToDisplay = $LINKSDB; | 833 | $linksToDisplay = $LINKSDB; |
@@ -1165,11 +1181,19 @@ function renderPage() | |||
1165 | if ($targetPage == Router::$PAGE_PICWALL) | 1181 | if ($targetPage == Router::$PAGE_PICWALL) |
1166 | { | 1182 | { |
1167 | // Optionally filter the results: | 1183 | // Optionally filter the results: |
1168 | if (!empty($_GET['searchterm'])) { | 1184 | $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; |
1169 | $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $_GET['searchterm']); | 1185 | $searchterm = !empty($_GET['searchterm']) ? escape($_GET['searchterm']) : ''; |
1186 | if (! empty($searchtags) && ! empty($searchterm)) { | ||
1187 | $links = $LINKSDB->filter( | ||
1188 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
1189 | array($searchtags, $searchterm) | ||
1190 | ); | ||
1170 | } | 1191 | } |
1171 | elseif (! empty($_GET['searchtags'])) { | 1192 | elseif ($searchtags) { |
1172 | $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, trim($_GET['searchtags'])); | 1193 | $links = $LINKSDB->filter(LinkFilter::$FILTER_TAG, $searchtags); |
1194 | } | ||
1195 | elseif ($searchterm) { | ||
1196 | $links = $LINKSDB->filter(LinkFilter::$FILTER_TEXT, $searchterm); | ||
1173 | } | 1197 | } |
1174 | else { | 1198 | else { |
1175 | $links = $LINKSDB; | 1199 | $links = $LINKSDB; |
@@ -1963,29 +1987,46 @@ function importFile() | |||
1963 | // This function fills all the necessary fields in the $PAGE for the template 'linklist.html' | 1987 | // This function fills all the necessary fields in the $PAGE for the template 'linklist.html' |
1964 | function buildLinkList($PAGE,$LINKSDB) | 1988 | function buildLinkList($PAGE,$LINKSDB) |
1965 | { | 1989 | { |
1966 | // ---- Filter link database according to parameters | 1990 | // Filter link database according to parameters. |
1967 | $search_type = ''; | 1991 | $searchtags = !empty($_GET['searchtags']) ? escape($_GET['searchtags']) : ''; |
1968 | $search_crits = ''; | 1992 | $searchterm = !empty($_GET['searchterm']) ? escape(trim($_GET['searchterm'])) : ''; |
1969 | $privateonly = !empty($_SESSION['privateonly']) ? true : false; | 1993 | $privateonly = !empty($_SESSION['privateonly']) ? true : false; |
1970 | 1994 | ||
1971 | // Fulltext search | 1995 | // Search tags + fullsearch. |
1972 | if (isset($_GET['searchterm'])) { | 1996 | if (! empty($searchtags) && ! empty($searchterm)) { |
1973 | $search_crits = escape(trim($_GET['searchterm'])); | 1997 | $linksToDisplay = $LINKSDB->filter( |
1974 | $search_type = LinkFilter::$FILTER_TEXT; | 1998 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, |
1975 | $linksToDisplay = $LINKSDB->filter($search_type, $search_crits, false, $privateonly); | 1999 | array($searchtags, $searchterm), |
2000 | false, | ||
2001 | $privateonly | ||
2002 | ); | ||
1976 | } | 2003 | } |
1977 | // Search by tag | 2004 | // Search by tags. |
1978 | elseif (isset($_GET['searchtags'])) { | 2005 | elseif (! empty($searchtags)) { |
1979 | $search_crits = explode(' ', escape(trim($_GET['searchtags']))); | 2006 | $linksToDisplay = $LINKSDB->filter( |
1980 | $search_type = LinkFilter::$FILTER_TAG; | 2007 | LinkFilter::$FILTER_TAG, |
1981 | $linksToDisplay = $LINKSDB->filter($search_type, $search_crits, false, $privateonly); | 2008 | $searchtags, |
2009 | false, | ||
2010 | $privateonly | ||
2011 | ); | ||
2012 | } | ||
2013 | // Fulltext search. | ||
2014 | elseif (! empty($searchterm)) { | ||
2015 | $linksToDisplay = $LINKSDB->filter( | ||
2016 | LinkFilter::$FILTER_TEXT, | ||
2017 | $searchterm, | ||
2018 | false, | ||
2019 | $privateonly | ||
2020 | ); | ||
1982 | } | 2021 | } |
1983 | // Detect smallHashes in URL. | 2022 | // Detect smallHashes in URL. |
1984 | elseif (isset($_SERVER['QUERY_STRING']) | 2023 | elseif (! empty($_SERVER['QUERY_STRING']) |
1985 | && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/', $_SERVER['QUERY_STRING'])) { | 2024 | && preg_match('/[a-zA-Z0-9-_@]{6}(&.+?)?/', $_SERVER['QUERY_STRING']) |
1986 | $search_type = LinkFilter::$FILTER_HASH; | 2025 | ) { |
1987 | $search_crits = substr(trim($_SERVER["QUERY_STRING"], '/'), 0, 6); | 2026 | $linksToDisplay = $LINKSDB->filter( |
1988 | $linksToDisplay = $LINKSDB->filter($search_type, $search_crits); | 2027 | LinkFilter::$FILTER_HASH, |
2028 | substr(trim($_SERVER["QUERY_STRING"], '/'), 0, 6) | ||
2029 | ); | ||
1989 | 2030 | ||
1990 | if (count($linksToDisplay) == 0) { | 2031 | if (count($linksToDisplay) == 0) { |
1991 | $PAGE->render404('The link you are trying to reach does not exist or has been deleted.'); | 2032 | $PAGE->render404('The link you are trying to reach does not exist or has been deleted.'); |
@@ -2041,21 +2082,18 @@ function buildLinkList($PAGE,$LINKSDB) | |||
2041 | } | 2082 | } |
2042 | 2083 | ||
2043 | // Compute paging navigation | 2084 | // Compute paging navigation |
2044 | $searchterm = empty($_GET['searchterm']) ? '' : '&searchterm=' . $_GET['searchterm']; | 2085 | $searchtagsUrl = empty($searchtags) ? '' : '&searchtags=' . urlencode($searchtags); |
2045 | $searchtags = empty($_GET['searchtags']) ? '' : '&searchtags=' . $_GET['searchtags']; | 2086 | $searchtermUrl = empty($searchterm) ? '' : '&searchterm=' . urlencode($searchterm); |
2046 | $previous_page_url = ''; | 2087 | $previous_page_url = ''; |
2047 | if ($i != count($keys)) { | 2088 | if ($i != count($keys)) { |
2048 | $previous_page_url = '?page=' . ($page+1) . $searchterm . $searchtags; | 2089 | $previous_page_url = '?page=' . ($page+1) . $searchtermUrl . $searchtagsUrl; |
2049 | } | 2090 | } |
2050 | $next_page_url=''; | 2091 | $next_page_url=''; |
2051 | if ($page>1) { | 2092 | if ($page>1) { |
2052 | $next_page_url = '?page=' . ($page-1) . $searchterm . $searchtags; | 2093 | $next_page_url = '?page=' . ($page-1) . $searchtermUrl . $searchtagsUrl; |
2053 | } | 2094 | } |
2054 | 2095 | ||
2055 | $token = ''; | 2096 | $token = isLoggedIn() ? getToken() : ''; |
2056 | if (isLoggedIn()) { | ||
2057 | $token = getToken(); | ||
2058 | } | ||
2059 | 2097 | ||
2060 | // Fill all template fields. | 2098 | // Fill all template fields. |
2061 | $data = array( | 2099 | $data = array( |
@@ -2065,8 +2103,8 @@ function buildLinkList($PAGE,$LINKSDB) | |||
2065 | 'page_current' => $page, | 2103 | 'page_current' => $page, |
2066 | 'page_max' => $pagecount, | 2104 | 'page_max' => $pagecount, |
2067 | 'result_count' => count($linksToDisplay), | 2105 | 'result_count' => count($linksToDisplay), |
2068 | 'search_type' => $search_type, | 2106 | 'search_term' => $searchterm, |
2069 | 'search_crits' => $search_crits, | 2107 | 'search_tags' => $searchtags, |
2070 | 'redirector' => empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'], // Optional redirector URL. | 2108 | 'redirector' => empty($GLOBALS['redirector']) ? '' : $GLOBALS['redirector'], // Optional redirector URL. |
2071 | 'token' => $token, | 2109 | 'token' => $token, |
2072 | 'links' => $linkDisp, | 2110 | 'links' => $linkDisp, |
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php index 31fd4cf4..ef1cc10a 100644 --- a/tests/LinkFilterTest.php +++ b/tests/LinkFilterTest.php | |||
@@ -12,6 +12,8 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
12 | */ | 12 | */ |
13 | protected static $linkFilter; | 13 | protected static $linkFilter; |
14 | 14 | ||
15 | protected static $NB_LINKS_REFDB = 7; | ||
16 | |||
15 | /** | 17 | /** |
16 | * Instanciate linkFilter with ReferenceLinkDB data. | 18 | * Instanciate linkFilter with ReferenceLinkDB data. |
17 | */ | 19 | */ |
@@ -27,7 +29,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
27 | public function testFilter() | 29 | public function testFilter() |
28 | { | 30 | { |
29 | $this->assertEquals( | 31 | $this->assertEquals( |
30 | 7, | 32 | self::$NB_LINKS_REFDB, |
31 | count(self::$linkFilter->filter('', '')) | 33 | count(self::$linkFilter->filter('', '')) |
32 | ); | 34 | ); |
33 | 35 | ||
@@ -36,6 +38,16 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
36 | 2, | 38 | 2, |
37 | count(self::$linkFilter->filter('', '', false, true)) | 39 | count(self::$linkFilter->filter('', '', false, true)) |
38 | ); | 40 | ); |
41 | |||
42 | $this->assertEquals( | ||
43 | self::$NB_LINKS_REFDB, | ||
44 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '')) | ||
45 | ); | ||
46 | |||
47 | $this->assertEquals( | ||
48 | self::$NB_LINKS_REFDB, | ||
49 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '')) | ||
50 | ); | ||
39 | } | 51 | } |
40 | 52 | ||
41 | /** | 53 | /** |
@@ -341,4 +353,41 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase | |||
341 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free')) | 353 | count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free')) |
342 | ); | 354 | ); |
343 | } | 355 | } |
356 | |||
357 | /** | ||
358 | * Test crossed search (terms + tags). | ||
359 | */ | ||
360 | public function testFilterCrossedSearch() | ||
361 | { | ||
362 | $terms = '"Free Software " stallman "read this" @website stuff'; | ||
363 | $tags = 'free'; | ||
364 | $this->assertEquals( | ||
365 | 1, | ||
366 | count(self::$linkFilter->filter( | ||
367 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
368 | array($tags, $terms) | ||
369 | )) | ||
370 | ); | ||
371 | $this->assertEquals( | ||
372 | 2, | ||
373 | count(self::$linkFilter->filter( | ||
374 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
375 | array('', $terms) | ||
376 | )) | ||
377 | ); | ||
378 | $this->assertEquals( | ||
379 | 1, | ||
380 | count(self::$linkFilter->filter( | ||
381 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
382 | array($tags, '') | ||
383 | )) | ||
384 | ); | ||
385 | $this->assertEquals( | ||
386 | self::$NB_LINKS_REFDB, | ||
387 | count(self::$linkFilter->filter( | ||
388 | LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT, | ||
389 | '' | ||
390 | )) | ||
391 | ); | ||
392 | } | ||
344 | } | 393 | } |
diff --git a/tpl/linklist.html b/tpl/linklist.html index ca91699e..c0d42006 100644 --- a/tpl/linklist.html +++ b/tpl/linklist.html | |||
@@ -11,16 +11,16 @@ | |||
11 | <div id="headerform" class="search"> | 11 | <div id="headerform" class="search"> |
12 | <form method="GET" class="searchform" name="searchform"> | 12 | <form method="GET" class="searchform" name="searchform"> |
13 | <input type="text" tabindex="1" id="searchform_value" name="searchterm" placeholder="Search text" | 13 | <input type="text" tabindex="1" id="searchform_value" name="searchterm" placeholder="Search text" |
14 | {if="!empty($search_crits) && $search_type=='fulltext'"} | 14 | {if="!empty($search_term)"} |
15 | value="{$search_crits}" | 15 | value="{$search_term}" |
16 | {/if} | 16 | {/if} |
17 | > | 17 | > |
18 | <input type="submit" value="Search" class="bigbutton"> | 18 | <input type="submit" value="Search" class="bigbutton"> |
19 | </form> | 19 | </form> |
20 | <form method="GET" class="tagfilter" name="tagfilter"> | 20 | <form method="GET" class="tagfilter" name="tagfilter"> |
21 | <input type="text" tabindex="2" name="searchtags" id="tagfilter_value" placeholder="Filter by tag" | 21 | <input type="text" tabindex="2" name="searchtags" id="tagfilter_value" placeholder="Filter by tag" |
22 | {if="!empty($search_crits) && $search_type=='tags'"} | 22 | {if="!empty($search_tags)"} |
23 | value="{function="implode(' ', $search_crits)"}" | 23 | value="{$search_tags}" |
24 | {/if} | 24 | {/if} |
25 | autocomplete="off" class="awesomplete" data-multiple data-minChars="1" | 25 | autocomplete="off" class="awesomplete" data-multiple data-minChars="1" |
26 | data-list="{loop="$tags"}{$key}, {/loop}" | 26 | data-list="{loop="$tags"}{$key}, {/loop}" |
@@ -44,19 +44,23 @@ | |||
44 | </div> | 44 | </div> |
45 | 45 | ||
46 | {if="count($links)==0"} | 46 | {if="count($links)==0"} |
47 | <div id="searchcriteria">Nothing found.</i></div> | 47 | <div id="searchcriteria">Nothing found.</div> |
48 | {else} | 48 | {elseif="!empty($search_term) or !empty($search_tags)"} |
49 | {if="$search_type=='fulltext'"} | 49 | <div id="searchcriteria"> |
50 | <div id="searchcriteria">{$result_count} results for <i>{$search_crits}</i></div> | 50 | {$result_count} results |
51 | {/if} | 51 | {if="!empty($search_term)"} |
52 | {if="$search_type=='tags'"} | 52 | for <em>{$search_term}</em> |
53 | <div id="searchcriteria">{$result_count} results for tags <i> | 53 | {/if} |
54 | {loop="search_crits"} | 54 | {if="!empty($search_tags)"} |
55 | <span class="linktag" title="Remove tag"> | 55 | {$exploded_tags=explode(' ', $search_tags)} |
56 | <a href="?removetag={function="urlencode($value)"}">{$value} <span class="remove">x</span></a> | 56 | tagged |
57 | </span> | 57 | {loop="$exploded_tags"} |
58 | {/loop}</i></div> | 58 | <span class="linktag" title="Remove tag"> |
59 | {/if} | 59 | <a href="?removetag={function="urlencode($value)"}">{$value} <span class="remove">x</span></a> |
60 | </span> | ||
61 | {/loop} | ||
62 | {/if} | ||
63 | </div> | ||
60 | {/if} | 64 | {/if} |
61 | <ul> | 65 | <ul> |
62 | {loop="links"} | 66 | {loop="links"} |