Implemented search; other minor changes.
h3rald h3rald@h3rald.com
Sat, 14 Oct 2017 14:23:09 +0200
6 files changed,
182 insertions(+),
15 deletions(-)
A
assets/js/search.js
@@ -0,0 +1,139 @@
+(function(window){ + var axios = window.axios; + var hostname = window.location.hostname; + var endpoint = '/search/'; + var searchInput = window.document.getElementsByClassName('search-input')[0]; + var searchButton = window.document.getElementsByClassName('search-button')[0]; + var clearButton = window.document.getElementsByClassName('clear-button')[0]; + var archivesButton = window.document.getElementsByClassName('archives-button')[0]; + var archivesDiv = window.document.getElementsByClassName('timeline')[0]; + var noResultsDiv = window.document.getElementsByClassName('no-search-results')[0]; + var resultsDiv = window.document.getElementsByClassName('search-results')[0]; + var loadingDiv = window.document.getElementsByClassName('loading')[0]; + + if (hostname === 'localhost') { + endpoint = 'http://localhost:9500/docs/'; + } + + function init() { + searchButton.addEventListener('click', reqSearch); + clearButton.addEventListener('click', reset); + searchInput.addEventListener('keypress', reqSearch); + archivesButton.addEventListener('click', archives); + search(); + } + + function result(data) { + console.log(data.id); + var id = data.id.replace(/\/index\.html$/i, ''); + var card = window.document.createElement('div'); + card.classList.add('card'); + + var header = window.document.createElement('div'); + header.classList.add('card-header'); + + var title = window.document.createElement('div'); + title.classList.add('card-title'); + title.classList.add('h5'); + + var link = window.document.createElement('a'); + link.setAttribute('href', id); + link.innerHTML = '→ ' + id; + + var subtitle = window.document.createElement('div'); + title.classList.add('card-subtitle'); + title.classList.add('text-gray'); + + var body = window.document.createElement('div'); + body.classList.add('card-body'); + body.innerHTML = data.highlight; + + // Structure + title.appendChild(link); + header.appendChild(title); + header.appendChild(subtitle); + card.appendChild(header); + card.appendChild(body); + + return card + } + + function getParam(name) { + var url = window.location.href; + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), + results = regex.exec(url); + if (!results) return null; + if (!results[2]) return ''; + return results[2].replace(/\+/g, " "); + } + + function search() { + var q = getParam('q'); + if (!q) { + archives(); + return; + } + searchInput.value = decodeURIComponent(q); + var req = endpoint + '?search=' + q + '&contents=false'; + console.log('executing...'); + axios.get(req).then(function(resp){ + results(resp.data.results); + }).catch(function(resp){ + noResults(); + }) + } + + function noResults(){ + noResultsDiv.classList.remove('d-none'); + resultsDiv.innerHTML = ''; + clearButton.classList.remove('d-none'); + loadingDiv.classList.add('d-none'); + resultsDiv.classList.add('d-none'); + archivesDiv.classList.add('d-none'); + } + + function results(items){ + var info = window.document.createElement('p'); + info.textContent = items.length + ' results found.'; + resultsDiv.innerHTML = ''; + resultsDiv.appendChild(info); + resultsDiv + items.forEach(function(item) { + resultsDiv.appendChild(result(item)); + }); + clearButton.classList.remove('d-none'); + loadingDiv.classList.add('d-none'); + noResultsDiv.classList.add('d-none'); + resultsDiv.classList.remove('d-none'); + archivesDiv.classList.add('d-none'); + } + + function archives(){ + noResultsDiv.classList.add('d-none'); + clearButton.classList.add('d-none'); + loadingDiv.classList.add('d-none'); + searchInput.value = ''; + resultsDiv.innerHTML = ''; + resultsDiv.classList.add('d-none'); + archivesDiv.classList.remove('d-none'); + } + + function reset() { + window.location.search = ''; + } + + function reqSearch(e){ + if (e && e.type === 'keypress' && e.keyCode != 13) { + return false; + } + var q = searchInput.value; + if (q) { + window.location.search = '?q=' + encodeURIComponent(q); + } else { + reset(); + } + } + + init(); +})(window)
M
assets/styles/style.css
→
assets/styles/style.css
@@ -144,8 +144,12 @@ float: right;
padding-bottom: 1rem; } -.body-text, h4, .timeline { +.body-text, h4 { clear: right; +} + +.clearfix { + clear: both; } img {@@ -154,4 +158,9 @@ }
.archives-search { float: right; + margin-bottom: 1em; +} + +.archives .card { + margin-bottom: 1em; }
M
contents/articles/10-programming-languages.html
→
contents/articles/10-programming-languages.html
@@ -6,9 +6,13 @@ popular: true
timestamp: 1229868075 tags: "programming" ----- -<blockquote> -<p>— This article has been translated into <a href="http://science.webhostinggeeks.com/10-programskih-jezika">Serbo-Croatian</a> by <cite><a href="http://webhostinggeeks.com/">Web Geeks</a></cite> —</p> -</blockquote> +<div class="toast"> + <ul> +<li>This article has been translated into <a href="http://science.webhostinggeeks.com/10-programskih-jezika">Serbo-Croatian</a> by <cite><a href="http://webhostinggeeks.com/">Web Geeks</a></cite></li> +<li>This article has been translated into <a href="https://www.homeyou.com/~edu/10-linguagens-de-programacao">Portuguese</a> by <cite><a href="https://www.homeyou.com/~edu/">Artur Weber</a></cite></li> + </ul> +</div> +<div class="v-spacer"></div> <p>If you program for fun or profit, chances are that you know C, C++, Java, <span class="caps">PHP</span>, Perl, Python or Ruby. These programming languages are all widely known, and, to a different degree, used in commercial applications. At least some of them can safely be considered <em>mainstream</em>, even if that word has become so overused and misused that has almost lost its original meaning, if it ever had one.</p> <p>If you are earning your living by coding, it’s often one of these languages that pays the bills. Nevertheless, true hackers frequently meander in other directions, exploring and discovering different paradigms and methodologies, sometimes to the most <a href="http://esolangs.org/wiki/Main_Page">esoteric</a> extremes.</p> <blockquote>
M
scripts/index.min
→
scripts/index.min
@@ -6,10 +6,13 @@
. :pwd (. "data.db") => "/" join :store -(. "contents") => "/" join cd +(. "output") => "/" join cd -"Deleting search index..." notice -store rm +(store file?) +( + "Deleting search index..." notice + store rm +) when "Importing data..." notice "litestore -s:$1 -d:articles import" (store) => % !
M
templates/_archives.mustache
→
templates/_archives.mustache
@@ -1,9 +1,23 @@
-<div class="container article-aggregation"> +<div class="container archives"> <div class="input-group archives-search"> - <input type="text" class="form-input" placeholder="Search articles..."> - <button class="btn btn-primary input-group-btn"><i class="ent ent-magnifying-glass"></i></button> + <input type="text" class="form-input search-input" placeholder="Search articles..."> + <button class="btn input-group-btn clear-button d-none"><i class="ent ent-circle-with-cross"></i></button> + <button class="btn btn-primary input-group-btn search-button"><i class="ent ent-magnifying-glass"></i></button> </div> - <div class="timeline"> + <div class="loading clearfix"></div> + <div class="no-search-results d-none clearfix"> + <div class="empty"> + <p class="empty-title h5">No results found</p> + <p class="empty-subtitle">There are no articles matching your query.</p> + <div class="empty-action"> + <button class="btn btn-primary archives-button">Go back</button> + </div> + </div> + </div> + <div class="search-results d-none clearfix"> + Results go here... + </div> + <div class="timeline clearfix d-none"> {{#archives}} <div class="timeline-item"> <div class="timeline-left">@@ -39,3 +53,4 @@ {{/articles}}
{{/archives}} </div> </div> +<script src="/js/search.js" type="text/javascript"></script>
M
templates/home.mustache
→
templates/home.mustache
@@ -114,10 +114,7 @@ </li>
</ul> </div> </div> - </div> - </div> - <div class="columns"> - <div class="column col-xs-12"> + <div class="v-spacer"></div> <div class="panel featured contact-list"> <div class="panel-header"> contact