summaryrefslogtreecommitdiff
path: root/themes/new_theme/layouts
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2018-04-29 18:50:33 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2018-04-29 18:50:33 +0200
commit50a4e701cd5791b5400ca4c8b438b17baee351b0 (patch)
tree6db06916d47297c8cde3008f1fa80265066b7982 /themes/new_theme/layouts
parente2bcd2fa26b04fd2ea246b1eb765b9b52e7324fa (diff)
downloadwww-andreasbaumann-cc-50a4e701cd5791b5400ca4c8b438b17baee351b0.tar.gz
www-andreasbaumann-cc-50a4e701cd5791b5400ca4c8b438b17baee351b0.tar.bz2
replace google site search with an ElasticLunr search
Diffstat (limited to 'themes/new_theme/layouts')
-rw-r--r--themes/new_theme/layouts/partials/ranklist.html271
-rw-r--r--themes/new_theme/layouts/partials/ranklist_strus.html316
-rw-r--r--themes/new_theme/layouts/partials/sidebar.html2
-rw-r--r--themes/new_theme/layouts/partials/widgets/google_site_search.html2
4 files changed, 345 insertions, 246 deletions
diff --git a/themes/new_theme/layouts/partials/ranklist.html b/themes/new_theme/layouts/partials/ranklist.html
index 9b732d1..5c7786b 100644
--- a/themes/new_theme/layouts/partials/ranklist.html
+++ b/themes/new_theme/layouts/partials/ranklist.html
@@ -1,106 +1,29 @@
<script src="/js/jquery.js" type="text/javascript"></script>
<script src="/js/url-search-params.js" type="text/javascript"></script>
-<script src="/js/Snowball.min.js" type="text/javascript"></script>
+<script src="/js/elasticlunr.min.js" type="text/javascript"></script>
<script src="/js/loadingoverlay.min.js" type="text/javascript"></script>
<script language="Javascript">
- var englishStemmer = new Snowball( "english" );
-
- function stem( s ) {
- englishStemmer.setCurrent( s );
- englishStemmer.stem( );
- return englishStemmer.getCurrent( );
- }
-
- function normalize_term( s ) {
- var r = stem( s );
- return r.toLowerCase( );
- }
-
- function get_terms( s ) {
- var terms = [];
- var words = s.trim( ).split( ' ' );
- for( var i in words ) {
- terms.push(
- {
- term: {
- type: "word",
- value: normalize_term( words[i] )
- }
- }
- );
- }
- return terms;
- }
-
- function get_features( query ) {
- var features = [];
- var words = query.trim( ).split( ' ' );
- for( var i in words ) {
- features.push(
- {
- name: "feat",
- value: {
- term: {
- type: "word",
- value: normalize_term( words[i] )
- }
- },
- weight: 1.0
- }
- );
- }
- features.push(
- {
- name: "sel",
- value: {
- expression : {
- operator: "union",
- range: 0,
- cardinality: 0,
- terms: get_terms( query )
- }
- },
- weight: 1.0
- }
- )
- return features;
- }
-
- function draw_ranklist( query, data ) {
+ function draw_ranklist( query, results ) {
var html = '';
-
- if( data.ranklist.ranks.length == 0 ) {
+
+ if( results.length == 0 ) {
return "<p>No hits for query '" + query + "'...</p>";
} else {
- html += "<p>" + data.ranklist.documents_ranked + " hits found</p>";
+ html += "<p>" + results.length + " hits found</p>";
}
-
+
var start = 1;
html += "<ol class=\"ranklist\" start=\"" + start + "\">";
- for( var i = 0; i < data.ranklist.ranks.length; i++ ) {
- var rank = data.ranklist.ranks[i];
- var abstract = '';
- var title = '';
- var title_attribute = 'No title';
- var docid = '';
- html += "<li>";
- for( var j = 0; j < rank.attributes.length; j++ ) {
- var attribute = rank.attributes[j];
- if( attribute.key == 'title' ) {
- title += ' ' + attribute.value;
- } else if( attribute.key == 'title_attribute' ) {
- title_attribute = attribute.value;
- } else if( attribute.key == 'docid' ) {
- docid = attribute.value;
- } else if( attribute.key == 'text' ) {
- abstract += ' ' + escapeHtml( attribute.value );
- }
- }
+ for( var i = 0; i < results.length; i++ ) {
+ var rank = results[i]['doc'];
+ var abstract = rank['abstract'];
+ var title = rank['title'];
if( title == '' ) {
- title = title_attribute;
+ title = 'No title';
}
- title = title.replaceAll( "#SMARK#", "<i>" ).replaceAll( "#EMARK#", "</i>" );
+ var docid = results[i]['ref'];
+ html += "<li>";
html += "<div class='title'>"
html += "<a href=\"" + docid + "\">" + title + "</a></div>";
if( abstract != '' ) {
@@ -110,6 +33,7 @@
html += "</li>";
}
html += "</ol>";
+
return html;
}
@@ -123,153 +47,14 @@
}
function executeQuery( query ) {
- var request = {
- query: {
- first_rank: 0,
- nof_ranks: 100,
- features: get_features( query ),
- select: [
- "sel"
- ],
- restrict: [
- ],
- exclude: [
- ],
- weighting: [
- {
- name: "bm25",
- params: [
- {
- key : "match",
- value : "feat"
- }
- ],
- weight : 1.0
- }
- ],
- summarizer: [
- {
- attribute: "docid",
- name: "attribute",
- params: [
- {
- key : "name",
- value : "docid"
- }
- ]
- },
- {
- attribute: "title_attribute",
- name: "attribute",
- params: [
- {
- key : "name",
- value : "title"
- }
- ],
- resultnames: [
- {
- key : "resultname",
- value : "title_attribute"
- }
- ]
- },
- {
- attribute: "title",
- name: "test",
- params: [
- {
- key: "type",
- value: "title"
- },
- {
- key: "match",
- value: "feat"
- },
- {
- key: "N",
- value: 50
- },
- {
- key: "add_dots",
- value: 0
- },
- {
- key: "start_first_match",
- value: 0
- },
- {
- key: "mark",
- value: "#SMARK#%1%#EMARK#"
- }
- ],
- resultnames: [
- {
- key: "resultname",
- value: "title"
- }
- ]
- },
- {
- attribute: "abstract",
- name: "test",
- params: [
- {
- key: "type",
- value: "text"
- },
- {
- key: "match",
- value: "feat"
- },
- {
- key: "N",
- value: 50
- },
- {
- key: "add_dots",
- value: 1
- },
- //~ {
- //~ key: "sentence",
- //~ value: "sentence"
- //~ },
- //~ {
- //~ key: "nof_sentences",
- //~ value: 3
- //~ },
- {
- key: "start_first_match",
- value: 1
- },
- {
- key: "mark",
- value: "#SMARK#%1%#EMARK#"
- }
- ],
- resultnames: [
- {
- key: "resultname",
- value: "text"
- }
- ]
- }
- ]
- }
- };
- var json = JSON.stringify( request, null, " " );
- console.log( "debug request: " + json );
-
$( "#query" ).LoadingOverlay( "show" );
-
+
$.ajax( {
- type : 'POST',
- url : {{ .Site.Params.strus_url }},
- data : json,
- contentType : 'application/json',
+ type : 'GET',
+ url : '/index/posts.index',
cache : false,
- timeout: 5000
+ timeout : 5000
} )
.error( function( x, t, m ) {
var html = '';
@@ -279,26 +64,24 @@
msg = t;
}
msg = escapeHtml( msg );
- html = "<pre><font color='red'>There was an error communicating to the strusWebService, reason: " + msg + "</font></pre>\n";
+ html = "<pre><font color='red'>There was an error loading the Elasticlunr index, reason: " + msg + "</font></pre>\n";
$( '#ranklist' ).html( html );
$( "#query" ).LoadingOverlay( "hide", true );
} )
.success( function( data ) {
- var json = JSON.stringify( data, null, " " );
- console.log( "debug answer: " + json );
- if( data.result == 'ok' ) {
- var html = draw_ranklist( query, data );
- $( '#ranklist' ).html( html );
- } else {
- var json = JSON.stringify( data, null, " " );
- var html = "<p>The strusWebService returned the following error:</p><pre><font color='red'>" + json + "</font></pre>";
- $( '#ranklist' ).html( html );
- }
+ var index = elasticlunr.Index.load( JSON.parse( data ) );
+
+ var results = index.search( query, { fields: { title : { boost : 2 }, content : { boost : 1 } } } );
+
+ var html = draw_ranklist( query, results );
+
+ $( '#ranklist' ).html( html );
$( "#query" ).LoadingOverlay( "hide" );
} );
+
};
$( window ).load( function( ) {
diff --git a/themes/new_theme/layouts/partials/ranklist_strus.html b/themes/new_theme/layouts/partials/ranklist_strus.html
new file mode 100644
index 0000000..9b732d1
--- /dev/null
+++ b/themes/new_theme/layouts/partials/ranklist_strus.html
@@ -0,0 +1,316 @@
+<script src="/js/jquery.js" type="text/javascript"></script>
+<script src="/js/url-search-params.js" type="text/javascript"></script>
+<script src="/js/Snowball.min.js" type="text/javascript"></script>
+<script src="/js/loadingoverlay.min.js" type="text/javascript"></script>
+<script language="Javascript">
+
+ var englishStemmer = new Snowball( "english" );
+
+ function stem( s ) {
+ englishStemmer.setCurrent( s );
+ englishStemmer.stem( );
+ return englishStemmer.getCurrent( );
+ }
+
+ function normalize_term( s ) {
+ var r = stem( s );
+ return r.toLowerCase( );
+ }
+
+ function get_terms( s ) {
+ var terms = [];
+ var words = s.trim( ).split( ' ' );
+ for( var i in words ) {
+ terms.push(
+ {
+ term: {
+ type: "word",
+ value: normalize_term( words[i] )
+ }
+ }
+ );
+ }
+ return terms;
+ }
+
+ function get_features( query ) {
+ var features = [];
+ var words = query.trim( ).split( ' ' );
+ for( var i in words ) {
+ features.push(
+ {
+ name: "feat",
+ value: {
+ term: {
+ type: "word",
+ value: normalize_term( words[i] )
+ }
+ },
+ weight: 1.0
+ }
+ );
+ }
+ features.push(
+ {
+ name: "sel",
+ value: {
+ expression : {
+ operator: "union",
+ range: 0,
+ cardinality: 0,
+ terms: get_terms( query )
+ }
+ },
+ weight: 1.0
+ }
+ )
+ return features;
+ }
+
+ function draw_ranklist( query, data ) {
+ var html = '';
+
+ if( data.ranklist.ranks.length == 0 ) {
+ return "<p>No hits for query '" + query + "'...</p>";
+ } else {
+ html += "<p>" + data.ranklist.documents_ranked + " hits found</p>";
+ }
+
+ var start = 1;
+ html += "<ol class=\"ranklist\" start=\"" + start + "\">";
+ for( var i = 0; i < data.ranklist.ranks.length; i++ ) {
+ var rank = data.ranklist.ranks[i];
+ var abstract = '';
+ var title = '';
+ var title_attribute = 'No title';
+ var docid = '';
+ html += "<li>";
+ for( var j = 0; j < rank.attributes.length; j++ ) {
+ var attribute = rank.attributes[j];
+ if( attribute.key == 'title' ) {
+ title += ' ' + attribute.value;
+ } else if( attribute.key == 'title_attribute' ) {
+ title_attribute = attribute.value;
+ } else if( attribute.key == 'docid' ) {
+ docid = attribute.value;
+ } else if( attribute.key == 'text' ) {
+ abstract += ' ' + escapeHtml( attribute.value );
+ }
+ }
+ if( title == '' ) {
+ title = title_attribute;
+ }
+ title = title.replaceAll( "#SMARK#", "<i>" ).replaceAll( "#EMARK#", "</i>" );
+ html += "<div class='title'>"
+ html += "<a href=\"" + docid + "\">" + title + "</a></div>";
+ if( abstract != '' ) {
+ abstract = abstract.replaceAll( "#SMARK#", "<b>" ).replaceAll( "#EMARK#", "</b>" );
+ html += "<div class='abstract'>" + abstract + "</div>";
+ }
+ html += "</li>";
+ }
+ html += "</ol>";
+ return html;
+ }
+
+ String.prototype.replaceAll = function(search, replacement) {
+ var target = this;
+ return target.replace(new RegExp(search, 'g'), replacement);
+ };
+
+ function escapeHtml( text ) {
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;" );
+ }
+
+ function executeQuery( query ) {
+ var request = {
+ query: {
+ first_rank: 0,
+ nof_ranks: 100,
+ features: get_features( query ),
+ select: [
+ "sel"
+ ],
+ restrict: [
+ ],
+ exclude: [
+ ],
+ weighting: [
+ {
+ name: "bm25",
+ params: [
+ {
+ key : "match",
+ value : "feat"
+ }
+ ],
+ weight : 1.0
+ }
+ ],
+ summarizer: [
+ {
+ attribute: "docid",
+ name: "attribute",
+ params: [
+ {
+ key : "name",
+ value : "docid"
+ }
+ ]
+ },
+ {
+ attribute: "title_attribute",
+ name: "attribute",
+ params: [
+ {
+ key : "name",
+ value : "title"
+ }
+ ],
+ resultnames: [
+ {
+ key : "resultname",
+ value : "title_attribute"
+ }
+ ]
+ },
+ {
+ attribute: "title",
+ name: "test",
+ params: [
+ {
+ key: "type",
+ value: "title"
+ },
+ {
+ key: "match",
+ value: "feat"
+ },
+ {
+ key: "N",
+ value: 50
+ },
+ {
+ key: "add_dots",
+ value: 0
+ },
+ {
+ key: "start_first_match",
+ value: 0
+ },
+ {
+ key: "mark",
+ value: "#SMARK#%1%#EMARK#"
+ }
+ ],
+ resultnames: [
+ {
+ key: "resultname",
+ value: "title"
+ }
+ ]
+ },
+ {
+ attribute: "abstract",
+ name: "test",
+ params: [
+ {
+ key: "type",
+ value: "text"
+ },
+ {
+ key: "match",
+ value: "feat"
+ },
+ {
+ key: "N",
+ value: 50
+ },
+ {
+ key: "add_dots",
+ value: 1
+ },
+ //~ {
+ //~ key: "sentence",
+ //~ value: "sentence"
+ //~ },
+ //~ {
+ //~ key: "nof_sentences",
+ //~ value: 3
+ //~ },
+ {
+ key: "start_first_match",
+ value: 1
+ },
+ {
+ key: "mark",
+ value: "#SMARK#%1%#EMARK#"
+ }
+ ],
+ resultnames: [
+ {
+ key: "resultname",
+ value: "text"
+ }
+ ]
+ }
+ ]
+ }
+ };
+
+ var json = JSON.stringify( request, null, " " );
+ console.log( "debug request: " + json );
+
+ $( "#query" ).LoadingOverlay( "show" );
+
+ $.ajax( {
+ type : 'POST',
+ url : {{ .Site.Params.strus_url }},
+ data : json,
+ contentType : 'application/json',
+ cache : false,
+ timeout: 5000
+ } )
+ .error( function( x, t, m ) {
+ var html = '';
+ if( x.status > 0 ) {
+ msg = x.responseText;
+ } else {
+ msg = t;
+ }
+ msg = escapeHtml( msg );
+ html = "<pre><font color='red'>There was an error communicating to the strusWebService, reason: " + msg + "</font></pre>\n";
+ $( '#ranklist' ).html( html );
+
+ $( "#query" ).LoadingOverlay( "hide", true );
+ } )
+ .success( function( data ) {
+ var json = JSON.stringify( data, null, " " );
+ console.log( "debug answer: " + json );
+
+ if( data.result == 'ok' ) {
+ var html = draw_ranklist( query, data );
+ $( '#ranklist' ).html( html );
+ } else {
+ var json = JSON.stringify( data, null, " " );
+ var html = "<p>The strusWebService returned the following error:</p><pre><font color='red'>" + json + "</font></pre>";
+ $( '#ranklist' ).html( html );
+ }
+
+ $( "#query" ).LoadingOverlay( "hide" );
+ } );
+ };
+
+ $( window ).load( function( ) {
+ var paramsString = window.location.search;
+ var searchParams = new URLSearchParams( paramsString );
+ if( searchParams.has( "q" ) ) {
+ executeQuery( searchParams.get( "q" ) );
+ } else {
+ // TODO: come up with something here
+ } // Show full page LoadingOverlay
+ } );
+
+</script>
+<div id="ranklist">
+</div>
diff --git a/themes/new_theme/layouts/partials/sidebar.html b/themes/new_theme/layouts/partials/sidebar.html
index 8241753..a69d2a9 100644
--- a/themes/new_theme/layouts/partials/sidebar.html
+++ b/themes/new_theme/layouts/partials/sidebar.html
@@ -1,5 +1,5 @@
<aside class="sidebar" itemscope="itemscope" itemtype="http://schema.org/WPSideBar">
- {{ partial "widgets/google_site_search.html" . }}
+ {{ partial "widgets/elasticlunr_search.html" . }}
{{ $section := .Section }}
{{ if or ( eq $section "blog" ) ( eq $section "" ) }}
{{ partial "widgets/recent.html" . }}
diff --git a/themes/new_theme/layouts/partials/widgets/google_site_search.html b/themes/new_theme/layouts/partials/widgets/google_site_search.html
index 2c4befa..6221b27 100644
--- a/themes/new_theme/layouts/partials/widgets/google_site_search.html
+++ b/themes/new_theme/layouts/partials/widgets/google_site_search.html
@@ -4,7 +4,7 @@
<form class="widget-search__form" role="search" method="get" action="//google.com/search">
<label>
<span class="screen-reader-text">Search for:</span>
- <input class="widget-search__field" type="search" placeholder="GOOGLE SEARCH..." value="" name="q">
+ <input class="widget-search__field" type="search" placeholder="SEARCH..." value="" name="q">
</label>
<input class="widget-search__submit" type="submit" value="Search">
<input type="hidden" name="sitesearch" value="{{ .Site.BaseURL }}" />