diff --git a/defaults/yacy.init b/defaults/yacy.init index 66c78683e..0cccf84cb 100644 --- a/defaults/yacy.init +++ b/defaults/yacy.init @@ -860,6 +860,8 @@ search.result.noreferrer=false # search result lines may show additional information for each search hit # these information pieces may be switched on or off search.result.show.keywords = false +# Maximum number of keywords initially displayed. The eventual remaining ones can then be expanded. +search.result.keywords.firstMaxCount = 100 search.result.show.date = true search.result.show.size = false search.result.show.metadata = false diff --git a/htroot/ConfigSearchPage_p.html b/htroot/ConfigSearchPage_p.html index 541e8deab..2d8d54693 100644 --- a/htroot/ConfigSearchPage_p.html +++ b/htroot/ConfigSearchPage_p.html @@ -237,7 +237,13 @@ var solr= $.getJSON("solr/collection1/select?q=*:*&defType=edismax&start=0&rows= http://url-of-the-search-result.net

- Tags: keyword subject keyword2 keyword3 + + Tags: keyword subject keyword2 keyword3 +

diff --git a/htroot/ConfigSearchPage_p.java b/htroot/ConfigSearchPage_p.java index 4dadefb8c..db4ed6644 100644 --- a/htroot/ConfigSearchPage_p.java +++ b/htroot/ConfigSearchPage_p.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.sql.Date; import java.util.Map; import java.util.Properties; + import net.yacy.cora.date.GenericFormatter; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.util.ConcurrentLog; @@ -69,7 +70,15 @@ public class ConfigSearchPage_p { sb.setConfig("search.video", post.getBoolean("search.video")); sb.setConfig("search.app", post.getBoolean("search.app")); - sb.setConfig("search.result.show.keywords", post.getBoolean("search.result.show.keywords")); + sb.setConfig(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS, post.getBoolean(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS)); + + // maximum number of initially displayed keywords/tags + int keywordsFirstMaxCount = post.getInt(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, + SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT_DEFAULT); + if (keywordsFirstMaxCount > 0) { + sb.setConfig(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, keywordsFirstMaxCount); + } + sb.setConfig("search.result.show.date", post.getBoolean("search.result.show.date")); sb.setConfig("search.result.show.size", post.getBoolean("search.result.show.size")); sb.setConfig("search.result.show.metadata", post.getBoolean("search.result.show.metadata")); @@ -160,7 +169,12 @@ public class ConfigSearchPage_p { sb.setConfig("search.audio", config.getProperty("search.audio","false")); sb.setConfig("search.video", config.getProperty("search.video","false")); sb.setConfig("search.app", config.getProperty("search.app","false")); - sb.setConfig("search.result.show.keywords", config.getProperty("search.result.show.keywords","false")); + sb.setConfig(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS, + config.getProperty(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS, + Boolean.toString(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS_DEFAULT))); + sb.setConfig(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, + config.getProperty(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, + String.valueOf(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT_DEFAULT))); sb.setConfig("search.result.show.date", config.getProperty("search.result.show.date","true")); sb.setConfig("search.result.show.size", config.getProperty("search.result.show.size","false")); sb.setConfig("search.result.show.metadata", config.getProperty("search.result.show.metadata","false")); @@ -198,7 +212,14 @@ public class ConfigSearchPage_p { prop.put("search.video", sb.getConfigBool("search.video", false) ? 1 : 0); prop.put("search.app", sb.getConfigBool("search.app", false) ? 1 : 0); - prop.put("search.result.show.keywords", sb.getConfigBool("search.result.show.keywords", false) ? 1 : 0); + prop.put(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS, + sb.getConfigBool(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS, + SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS_DEFAULT) ? 1 : 0); + + prop.put(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, + sb.getConfigInt(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, + SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT_DEFAULT)); + prop.put("search.result.show.date", sb.getConfigBool("search.result.show.date", false) ? 1 : 0); prop.put("search.result.show.size", sb.getConfigBool("search.result.show.size", false) ? 1 : 0); prop.put("search.result.show.metadata", sb.getConfigBool("search.result.show.metadata", false) ? 1 : 0); diff --git a/htroot/env/base.css b/htroot/env/base.css index e174da007..c92eee974 100644 --- a/htroot/env/base.css +++ b/htroot/env/base.css @@ -423,6 +423,22 @@ p.tags { line-height: 1.4; } +/* Button to expand/collapse tags beyond the initial number of tags display limit */ +.expandKeywordsBtn { + margin-top: 0.2em; +} + +.expandKeywordsBtn[aria-expanded="true"] .glyphicon:before { + /* Repeated same char as in the glyphicon-chevron-left class */ + content: "\e079\e079"; +} + +.expandKeywordsBtn[aria-expanded="false"] .glyphicon:before { + /* Repeated same char as in the glyphicon-chevron-right class */ + content: "\e080\e080"; +} + + div.bookmark p { margin:1px; } diff --git a/htroot/js/yacysearch.js b/htroot/js/yacysearch.js index 263e2e536..f9927f3bd 100644 --- a/htroot/js/yacysearch.js +++ b/htroot/js/yacysearch.js @@ -264,4 +264,25 @@ function statistics(offset, itemscount, itemsperpage, totalcount, localIndexCoun } } - +/** + * Toggle visibility on a block of tags (keywords) beyond the initial limit of tags to display. + * @param {HTMLButtonElement} button the button used to expand the tags + * @param {String} moreTagsId the id of the container of tags which visibility has to be toggled + */ +function toggleMoreTags(button, moreTagsId) { + var moreTagsContainer = document.getElementById(moreTagsId); + if(button != null && moreTagsContainer != null) { + if(button.getAttribute("aria-expanded") == "true") { + /* Additionnaly we modify the aria-expanded state for improved accessiblity */ + button.setAttribute("aria-expanded", "false"); + button.title = "Show all"; + moreTagsContainer.className = "hidden"; + } else { + /* Additionnaly we modify the aria-expanded state for improved accessiblity */ + button.setAttribute("aria-expanded", "true"); + button.title = "Show only the first elements"; + moreTagsContainer.className = ""; + } + } + +} \ No newline at end of file diff --git a/htroot/yacysearchitem.html b/htroot/yacysearchitem.html index f8d34311d..901f16a05 100644 --- a/htroot/yacysearchitem.html +++ b/htroot/yacysearchitem.html @@ -25,7 +25,18 @@

#[description]#

#[urlname]#

- #(showKeywords)#::

Tags: #{keywords}##[tagword]# #{/keywords}#

#(/showKeywords)# + #(showKeywords)#::

Tags: #{keywords}##[tagword]# #{/keywords}# + #(moreKeywords)#:: + + #(/moreKeywords)# +

+ #(/showKeywords)#

#(showDate)#::#[date]##(/showDate)# #(showEvent)#::on #[date]##(/showEvent)# diff --git a/htroot/yacysearchitem.java b/htroot/yacysearchitem.java index 090be47c7..fb04ef4a8 100644 --- a/htroot/yacysearchitem.java +++ b/htroot/yacysearchitem.java @@ -250,7 +250,8 @@ public class yacysearchitem { prop.put("content_showEvent", showEvent ? 1 : 0); Collection snapshotPaths = sb.getConfigBool("search.result.show.snapshots", true) ? Transactions.findPaths(result.url(), null, State.ANY) : null; if (fileType == FileType.HTML) { // html template specific settings - boolean showKeywords = (sb.getConfigBool("search.result.show.keywords", false) && !result.dc_subject().isEmpty()); + boolean showKeywords = (sb.getConfigBool(SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS, + SwitchboardConstants.SEARCH_RESULT_SHOW_KEYWORDS_DEFAULT) && !result.dc_subject().isEmpty()); prop.put("content_showKeywords", showKeywords); prop.put("content_showDate", sb.getConfigBool("search.result.show.date", true) && !showEvent ? 1 : 0); prop.put("content_showSize", sb.getConfigBool("search.result.show.size", true) ? 1 : 0); @@ -267,13 +268,16 @@ public class yacysearchitem { if (showEvent) prop.put("content_showEvent_date", GenericFormatter.RFC1123_SHORT_FORMATTER.format(events[0])); if (showKeywords) { // tokenize keywords - StringTokenizer stoc = new StringTokenizer(result.dc_subject()," "); + final StringTokenizer stoc = new StringTokenizer(result.dc_subject()," "); String rawNavQueryModifier; Navigator navi = theSearch.navigatorPlugins.get("keywords"); boolean naviAvail = navi != null; + final int firstMaxKeywords = sb.getConfigInt(SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT, + SwitchboardConstants.SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT_DEFAULT); int i = 0; - while (stoc.hasMoreTokens()) { - String word = stoc.nextToken(); + while (stoc.hasMoreTokens() + && i < firstMaxKeywords) { + final String word = stoc.nextToken(); prop.putHTML("content_showKeywords_keywords_" + i + "_tagword", word); if (naviAvail) { // use query modifier if navigator available rawNavQueryModifier = navi.getQueryModifier(word); @@ -285,6 +289,24 @@ public class yacysearchitem { i++; } prop.put("content_showKeywords_keywords", i); + if(stoc.hasMoreTokens()) { + prop.put("content_showKeywords_moreKeywords", "1"); + prop.put("content_showKeywords_moreKeywords_urlhash", urlhash); + i = 0; + while (stoc.hasMoreTokens()) { + final String word = stoc.nextToken(); + prop.putHTML("content_showKeywords_moreKeywords_keywords_" + i + "_tagword", word); + if (naviAvail) { // use query modifier if navigator available + rawNavQueryModifier = navi.getQueryModifier(word); + } else { // otherwise just use the keyword as additional query word + rawNavQueryModifier = word; + } + prop.put("content_showKeywords_moreKeywords_keywords_" + i + "_tagurl", QueryParams.navurl(fileType, 0, + theSearch.query, rawNavQueryModifier, naviAvail, authenticated).toString()); + i++; + } + prop.put("content_showKeywords_moreKeywords_keywords", i); + } } prop.put("content_showDate_date", GenericFormatter.RFC1123_SHORT_FORMATTER.format(result.moddate())); prop.putHTML("content_showSize_sizename", RSSMessage.sizename(result.filesize())); diff --git a/source/net/yacy/search/SwitchboardConstants.java b/source/net/yacy/search/SwitchboardConstants.java index 03b94c8b2..8ce6a8d04 100644 --- a/source/net/yacy/search/SwitchboardConstants.java +++ b/source/net/yacy/search/SwitchboardConstants.java @@ -570,6 +570,18 @@ public final class SwitchboardConstants { /** Default setting value controlling whether the ranking score value should be displayed for each search result in the HTML results page */ public static final boolean SEARCH_RESULT_SHOW_RANKING_DEFAULT = false; + + /** Key of the setting controlling whether a tags/keywords list should be displayed for each search result in the HTML results page */ + public static final String SEARCH_RESULT_SHOW_KEYWORDS = "search.result.show.keywords"; + + /** Default setting value controlling whether the ranking score value should be displayed for each search result in the HTML results page */ + public static final boolean SEARCH_RESULT_SHOW_KEYWORDS_DEFAULT = false; + + /** Key of the setting controlling the maximum number of tags/keywords initially displayed for each search result in the HTML results page (the eventual remaining ones can then be expanded) */ + public static final String SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT = "search.result.keywords.firstMaxCount"; + + /** Default setting value controlling the maximum number of tags/keywords initially displayed for each search result in the HTML results page (the eventual remaining ones can then be expanded) */ + public static final int SEARCH_RESULT_KEYWORDS_FISRT_MAX_COUNT_DEFAULT = 100; /** * ranking+evaluation