1
0
mirror of https://github.com/balkian/balkian.github.com.git synced 2024-12-26 10:18:13 +00:00

Add search

This commit is contained in:
J. Fernando Sánchez 2019-01-11 16:03:17 +01:00
parent 7c3fb50312
commit 566a103c9a
16 changed files with 279 additions and 168 deletions

View File

@ -5,7 +5,6 @@ theme = "balkian"
preserveTaxonomyNames = true
disqusShortname = "balkian"
googleAnalytics = ""
SectionPagesMenu = "main"
Paginate = 5
pygmentsCodeFences = true
pygmentsOptions = "linenos=table"
@ -13,6 +12,8 @@ summaryLength = 50
relativeURLs = true
copyright = "This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License."
[outputs]
home = ["HTML", "RSS", "JSON"]
[taxonomies]
category = "categories"

View File

@ -1,98 +0,0 @@
+++
title = "About"
date = "2017-02-24"
menu = ["main"]
+++
Hi!
My name is Fernando. I'm a researcher and developer from Madrid, Spain.
---
<style>
about ul {
position: relative;
width: 900px;
margin: 0 auto;
}
#about li {
line-height:1.5em;
border-bottom:1px solid #DDD;
float:left;
display:inline;
width: 33.333%;
}
#about i {
/*background-color: #ffd700;*/
/*padding: 5px;*/
/*border-radius: 10px;*/
}
.icons {
text-align: center;
color: #333;
/* text-shadow: 2px 2px #FFD700; */
}
.coolicon {
position: relative;
}
.coolicon:hover .icon-stack {
visibility: none;
}
.coolicon:hover .explanation {
white-space: nowrap;
background: #FFD700;
display: block;
position:absolute;
border: 1px solid black;
z-index: 99;
top: 1em;
color: black;
font-family: Comfortaa;
/* width: 100%; */
padding: 0.5em;
/* border-radius: 0 10px 10px; */
overflow: visible;
left: 0;
/* transform-origin: 95% 50%; */
/* -moz-transform-origin: 95% 50%; */
/* -webkit-transform-origin: 95% 50%; */
-webkit-transform: rotate(-4deg);
-moz-transform: rotate(-4deg);
transform: rotate(-4deg);
}
/* .coolicon:hover { */
/* width: 5em; */
/* } */
.explanation {
display:none;
}
</style>
<div id="about" style="clear:both;">
<!-- <h1 class="title">Interests</h1> -->
<div class="icons">
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa-stack-2x"></i><i class="fa fa-stack-1x fa-linux"></i></span><span class="explanation">Linux lover</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-android"></i></span><span class="explanation">Android dev</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-github-alt"></i> </span><span class="explanation">GitHub user</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-stack-exchange"></i> </span><span class="explanation">StackExchange fan</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-music"></i> </span><span class="explanation">Music lover</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-film"></i> </span><span class="explanation">Movie fan</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-comments"></i> </span><span class="explanation">Always on IM</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-laptop"></i> </span><span class="explanation">Always on a PC</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-pencil"></i> </span><span class="explanation">Occassional writter</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-moon-o"></i> </span><span class="explanation">Night owl</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-terminal"></i></span> <span class="explanation">CLI user</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-flag"></i></span> <span class="explanation">Linguist wannabe</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-code"></i> </span> <span class="explanation">Love to code</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-book"></i></span> <span class="explanation">Keen reader</span></span>
<span class="coolicon"><span class="fa fa-stack"> <i class="fa fa-square-o fa fa-stack-2x"></i><i class="fa fa-quote-right"></i></span> <span class="explanation">Quotes on demand</span></span>
</div>
</div>

1
content/page/.#todo2.md Symbolic link
View File

@ -0,0 +1 @@
j@panther.18281:1546943267

9
content/page/about.md Normal file
View File

@ -0,0 +1,9 @@
+++
title = "About"
date = "2017-02-24"
menu = ["main"]
+++
Hi!
My name is Fernando. I'm a researcher and developer from Madrid, Spain.

30
content/page/todo.md Normal file
View File

@ -0,0 +1,30 @@
---
title: To-do
menu: main
---
### PhD
- [x] Write my first workshop paper as main author
- [x] Write my first journal paper
- [x] Write my first book chapter
- [x] Chair a W3C Community Group
- [ ] Collaborate in a W3C recommendation
- [ ] Become a doctor!
### Technical
- [x] Write a NodeJS App. Maia [See [ISSUES](http://github.com/gsi-upm/maia/issues)]
- [x] Write my first Django Application
- [ ] Develop a distributed LibP2P golang application
- [ ] Github repo with +100 stars
### Languages
- [x] English
- [ ] Chinese
- [ ] Greek
- [ ] German
- [ ] Esperanto
### Personal
- [x] Run a 10k
- [ ] Blog regularly for a year

View File

@ -6,15 +6,17 @@ title: Index of projects
Ongoing Projects
================
* [Senpy](http://senpy.readthedocs.io): a framework for semantic sentiment and emotion analysis services.
* [Soil](http://soilsim.readthedocs.io): an agent-based simulator for social networks based on nx-sim and networkx.
* [Onyx](http://gsi.dit.upm.es/ontologies/onyx): an ontology for emotion analysis that includes concepts from W3C's provenance.
* [Marl](http://gsi.dit.upm.es/ontologies/marl): I updated this ontology, originally created by Adam Westerski, to make it compatible with the W3C's provenance ontology.
Past Projects
=============
* [Marl](http://gsi.dit.upm.es/ontologies/marl): I updated this ontology, originally created by Adam Westerski, to make it compatible with the W3C's provenance ontology.
* [Hermes](http://github.com/balkian/hermes): one of my first projects, developed together with David Pérez as the special custom assignment in one of our courses. Hermes is an affective bot designed to mimic the behavour of humans. It included a plug-in system for its sensors and actuators. The information from its sensors changed its emotional state, which was shown via its actuators. Among others, it could fetch inforation from Twitter or its host system and change the expressions of an external Face made with servo motors or speak via its Text-To-Speech software. For instance, it could detect it was running out of battery, showing a sad face and sending an alerting tweet. You can see it in action in these two youtube videos: [Part 1](http://www.youtube.com/watch?v=KnEYahPD9z4) and [Part 2](http://www.youtube.com/watch?v=lQZldCTPEJc).
* [EESTEC.net](http://github.com/eestec/eestec.portal): the Plone based official portal of EESTEC. I fixed some bugs and implemented basic features. It's still an ongoing project.
* [Maia](http://github.com/gsi-upm/maia): the Modular Architecture for Intelligent Agents is an evented agent architecture that aims to update the classical frameworks for intelligent agents with the concepts emerged from the Live Web.
* [EESTEC.net](http://github.com/eestec/eestec.portal): the Plone based official portal of EESTEC. It has been my first and only experience with Plone. I fixed some bugs and implemented basic features.
For more information, checl my [complete list of public repositories in <a href="http://github.com/balkian"><i class="fa fa-github"> Github</i></a>.
For more information, check my list of public repositories in <a href="http://github.com/balkian"><i class="fab fa-github"> Github</i></a>.

View File

@ -1,24 +0,0 @@
---
title: Index of projects
---
Ongoing Projects
================
* `Onyx <http://gsi.dit.upm.es/ontologies/onyx>`_: an ontology for emotion analysis that includes concepts from W3C's provenance.
* `Marl <http://gsi.dit.upm.es/ontologies/marl>`_: I updated this ontology, originally created by Adam Westerski, to make it compatible with the W3C's provenance ontology.
Past Projects
=============
* `Hermes <http://github.com/balkian/hermes>`_: one of my first projects, developed together with David Pérez as the special custom assignment in one of our courses. Hermes is an affective bot designed to mimic the behavour of humans. It included a plug-in system for its sensors and actuators. The information from its sensors changed its emotional state, which was shown via its actuators. Among others, it could fetch inforation from Twitter or its host system and change the expressions of an external Face made with servo motors or speak via its Text-To-Speech software. For instance, it could detect it was running out of battery, showing a sad face and sending an alerting tweet. You can see it in action in these two youtube videos: `Part 1 <http://www.youtube.com/watch?v=KnEYahPD9z4>`_ and `Part 2 <http://www.youtube.com/watch?v=lQZldCTPEJc>`_.
* `EESTEC.net <http://github.com/eestec/eestec.portal>`_: the Plone based official portal of EESTEC. I fixed some bugs and implemented basic features. It's still an ongoing project.
* `Maia <http://github.com/gsi-upm/maia>`_: the Modular Architecture for Intelligent Agents is an evented agent architecture that aims to update the classical frameworks for intelligent agents with the concepts emerged from the Live Web.
For more information, checl my [complete list of public repositories in |github|.
.. |github| raw:: html
<a href="http://github.com/balkian"><i class="icon-github"> Github</i></a>

7
content/project/otro.md Normal file
View File

@ -0,0 +1,7 @@
---
title: just a test
type: page
---
It does nothing

59
content/search.md Normal file
View File

@ -0,0 +1,59 @@
---
title: "Search Results"
layout: "search"
sitemap:
priority : 0.1
---
This file exists solely to respond to /search URL with the related `search` layout template.
No content shown here is rendered, all content is based in the template layouts/page/search.html
Setting a very low sitemap priority will tell search engines this is not important content.
This implementation uses Fusejs, jquery and mark.js
## Initial setup
Search depends on additional output content type of JSON in config.toml
\```
[outputs]
home = ["HTML", "JSON"]
\```
## Searching additional fileds
To search additional fields defined in front matter, you must add it in 2 places.
### Edit layouts/_default/index.JSON
This exposes the values in /index.json
i.e. add `category`
\```
...
"contents":{{ .Content | plainify | jsonify }}
{{ if .Params.tags }},
"tags":{{ .Params.tags | jsonify }}{{end}},
"categories" : {{ .Params.categories | jsonify }},
...
\```
### Edit fuse.js options to Search
`static/js/search.js`
\```
keys: [
"title",
"contents",
"tags",
"categories"
]
\```
<div id="search-results"></div>
<script id="search-result-template" type="text/x-js-template">
<div id="summary-${key}">
<h3><a href="${link}">${title}</a></h3>
<p>${snippet}</p>
</div>
</script>

View File

@ -1,39 +0,0 @@
---
title: To-Do
---
<h2>Things To Do</h2>
This is intended as my public "todo.txt". Both to keep it accessible and to feel ashamed of the many things I leave undone:
<ul class="todo">
<li> PhD
<ul>
<li class="done" >Write my first workshop paper as main author</li>
<li>Write my first journal paper</li>
<li>Become a doctor!</li>
</ul>
</li>
<li> Technical
<ul>
<li class="done" >Write a NodeJS App. Maia [See <a href="http://github.com/gsi-upm/maia/issues">ISSUES</a>]</li>
<li class="done" >Write my first Django Application</li>
<li class="done">Win my first Hackathon</li>
<li>Github repo with +100 stars</li>
</ul>
</li>
<li> Languages
<ul>
<li class="done">English</a></li>
<li >Chinese</a></li>
<li >Greek</a></li>
<li >German</a></li>
<li >Esperanto</a></li>
</ul>
</li>
<li> Personal
<ul>
<li>Run a 10k</li>
<li>Blog regularly for a year</li>
</ul>
</li>
</ul>

View File

@ -37,6 +37,9 @@
<a href="//jfernando.es" target="_blank"><li>
CV
</li></a>
<a href="{{ "/search" | relURL }}"><li>
<i class="fa fa-search"></i>
</li></a>
</ul>
</header>
<!--Body content-->
@ -68,5 +71,7 @@
</div>
<script src="{{ "/js/jquery-2.0.2.min.js" | relURL }}"></script>
{{ block "footerfiles" . }}
{{ end }}
</body>
</html>

View File

@ -0,0 +1,5 @@
{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
{{- $.Scratch.Add "index" (dict "title" .Title "tags" .Params.tags "categories" .Params.categories "contents" .Plain "permalink" .Permalink) -}}
{{- end -}}
{{- $.Scratch.Get "index" | jsonify -}}

View File

@ -1,5 +1,5 @@
{{ define "content" }}
<h1>{{ .Data.Plural | humanize}}</h1>
<h2>{{ .Data.Plural | humanize}}</h2>
<div>
{{ $data := .Data }}
{{ $total := .Site.Pages | len}}

View File

@ -0,0 +1,30 @@
{{ define "footerfiles" }}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/3.2.0/fuse.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/jquery.mark.min.js"></script>
<script src="{{ "/js/search.js" | relURL }}"></script>
{{ end }}
{{ define "content" }}
<section class="resume-section p-3 p-lg-5 d-flex flex-column">
<div class="my-auto" >
<form class="search">
<input type="text" name="s" class="searchTerm" placeholder="What are you looking for?">
<button type="submit" class="searchButton">
<i class="fas fa-2x fa-search"></i>
</button>
</form>
<div id="search-results">
<h3>Matching pages</h3>
</div>
</div>
</section>
<!-- this template is sucked in by search.js and appended to the search-results div above. So editing here will adjust style -->
<script id="search-result-template" type="text/x-js-template">
<div id="summary-${key}">
<h4><a href="${link}">${title}</a></h4>
<p>${snippet}</p>
${ isset tags }<p>Tags: ${tags}</p>${ end }
${ isset categories }<p>Categories: ${categories}</p>${ end }
</div>
</script>
{{ end }}

View File

@ -385,9 +385,8 @@ footer a:hover {
border: 0;
}
.todo {
.todo , .task-list {
list-style-type: none;
font-weight: bold;
}
.todo ul {
@ -805,3 +804,18 @@ pre {
margin: 0;
padding: 1em;
}
.search {
width: 100%;
padding: 0;
}
.searchTerm {
padding: 0.5em 1em;
}
.search > * {
vertical-align: middle;
margin:0;
height: 100%;
}

View File

@ -0,0 +1,109 @@
summaryInclude=60;
var fuseOptions = {
shouldSort: true,
includeMatches: true,
threshold: 0.0,
tokenize:true,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 1,
keys: [
{name:"title",weight:0.8},
{name:"contents",weight:0.5},
{name:"tags",weight:0.3},
{name:"categories",weight:0.3}
]
};
var searchQuery = param("s");
if(searchQuery){
$("#search-query").val(searchQuery);
executeSearch(searchQuery);
}else {
$('#search-results').append("<p>Please enter a word or phrase above</p>");
}
function executeSearch(searchQuery){
$.getJSON( "/index.json", function( data ) {
var pages = data;
var fuse = new Fuse(pages, fuseOptions);
var result = fuse.search(searchQuery);
console.log({"matches":result});
if(result.length > 0){
populateResults(result);
}else{
$('#search-results').append("<p>No matches found</p>");
}
});
}
function populateResults(result){
$.each(result,function(key,value){
var contents= value.item.contents;
var snippet = "";
var snippetHighlights=[];
var tags =[];
if( fuseOptions.tokenize ){
snippetHighlights.push(searchQuery);
}else{
$.each(value.matches,function(matchKey,mvalue){
if(mvalue.key == "tags" || mvalue.key == "categories" ){
snippetHighlights.push(mvalue.value);
}else if(mvalue.key == "contents"){
start = mvalue.indices[0][0]-summaryInclude>0?mvalue.indices[0][0]-summaryInclude:0;
end = mvalue.indices[0][1]+summaryInclude<contents.length?mvalue.indices[0][1]+summaryInclude:contents.length;
snippet += contents.substring(start,end);
snippetHighlights.push(mvalue.value.substring(mvalue.indices[0][0],mvalue.indices[0][1]-mvalue.indices[0][0]+1));
}
});
}
if(snippet.length<1){
snippet += contents.substring(0,summaryInclude*2);
}
//pull template from hugo templarte definition
var templateDefinition = $('#search-result-template').html();
//replace values
var output = render(templateDefinition,{key:key,title:value.item.title,link:value.item.permalink,tags:value.item.tags,categories:value.item.categories,snippet:snippet});
$('#search-results').append(output);
$.each(snippetHighlights,function(snipkey,snipvalue){
$("#summary-"+key).mark(snipvalue);
});
});
}
function param(name) {
return decodeURIComponent((location.search.split(name + '=')[1] || '').split('&')[0]).replace(/\+/g, ' ');
}
function render(templateString, data) {
var conditionalMatches,conditionalPattern,copy;
conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
//since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
copy = templateString;
while ((conditionalMatches = conditionalPattern.exec(templateString)) !== null) {
if(data[conditionalMatches[1]]){
//valid key, remove conditionals, leave contents.
copy = copy.replace(conditionalMatches[0],conditionalMatches[2]);
}else{
//not valid, remove entire section
copy = copy.replace(conditionalMatches[0],'');
}
}
templateString = copy;
//now any conditionals removed we can do simple substitution
var key, find, re;
for (key in data) {
find = '\\$\\{\\s*' + key + '\\s*\\}';
re = new RegExp(find, 'g');
templateString = templateString.replace(re, data[key]);
}
return templateString;
}