Permalink
Browse files

A new Post and a search function. :]

  • Loading branch information...
1 parent 466585f commit 42a0bfe6c9f445c4f8014ad780076ad3a6475e60 @pylight committed Apr 19, 2012
@@ -7,15 +7,17 @@
{% capture next_month %}{{ post.previous.date | date: "%B" }}{% endcapture %}
{% if forloop.first %}
+ <div id="archive">
<div class="nicehead"><span class="nice">{{this_year}}</span></div>
<span class="bighead">{{this_month}}</span>
<ul class="posts">
{% endif %}
- <li><span>{{ post.date | date_to_string }}</span> &raquo; <a href="{{site.baseurl}}{{ post.url }}">{{ post.title }}</a> <span class="niceinfo" style="color: #dedede;">#{{ post.category }}</span> </li>
+ <li><span class="archiveDate">{{ post.date | date_to_string }}</span> &raquo; <a href="{{site.baseurl}}{{ post.url }}">{{ post.title }}</a> <span class="niceinfo archiveTag" style="color: #dedede;">#{{ post.category }}</span> </li>
{% if forloop.last %}
- </ul>
+ </ul>
+ </div>
{% else %}
{% if this_year != next_year %}
</ul>
@@ -24,7 +26,7 @@
<ul class="posts">
{% else %}
{% if this_month != next_month %}
- </ul>
+ </ul>
<span class="bighead">{{next_month}}</span>
<ul class="posts">
{% endif %}
View
@@ -14,54 +14,52 @@
<link rel="stylesheet" href="{{site.baseurl}}/css/screen.css" type="text/css" media="screen, projection" />
<!-- Scripts -->
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
- <script src="{{site.baseurl}}/js/random.js" type="text/javascript"></script>
- <script src="{{site.baseurl}}/js/randomPost.js" type="text/javascript"></script>
- {% include js/flattr.html %}
-
+ <script src="{{site.baseurl}}/js/jquery.min.js" type="text/javascript"></script>
+ <script src="{{site.baseurl}}/js/random.js" type="text/javascript"></script>
+ <script src="{{site.baseurl}}/js/randomPost.js" type="text/javascript"></script>
+ <script src="{{site.baseurl}}/js/jquery.bbq.min.js" type="text/javascript"></script>
+ {% include js/flattr.html %}
</head>
<body>
- <!-- Tool- & Egobox :) -->
- <div id="toolbox"><a href="javascript:void(0)" title="hide everything but content" id="cleanup">clean layout</a> <a href="javascript:void(0)" title="show a random blogpost" onclick="javascript:getRandomPost();" id="random">random post</a>
- <span id="toolboxnote"> &lt;---- Toolbox!</span>
- </div>
<noscript><span id="jswarning">You should activate JavaScript to enjoy this blog! ...orly? ya rly!</span></noscript>
-
- <div id="egobox">
+<div class="site">
+<header>
+ <div id="egobox">
<span id="stalknote">stalk me here ----&gt;</span>
<a href="https://github.com/pylight/" title="see my projects on github" id="githublink"><img src="{{site.baseurl}}/images/icons/egobox/github.png" alt="github"/></a>
<a href="https://twitter.com/#!/GanzSicherNet" title="follow me on twitter" id="twitterlink"><img src="{{site.baseurl}}/images/icons/egobox/twitter.png" alt="twitter"/></a>
<a href="http://feeds.feedburner.com/GanzSicherNet" title="subscribe my RSS-Feed" id="rsslink"><img src="{{site.baseurl}}/images/icons/egobox/rss.png" alt="rss"/></a>
<a href="http://gsn.idea.informer.com/" title="give me feedback!" id="feedbacklink">Feedback</a>
</div>
-
-<div class="site">
-<header>
-
+
<!-- Logo -->
- <a href="{{site.baseurl}}/"><img id="logo" style="border:none;" alt="Ganz-Sicher.net Blog" src="{{site.baseurl}}/images/logo.png" /></a>
+ <a href="{{site.baseurl}}/" id="logolink"><img id="logo" style="border:none;" alt="Ganz-Sicher.net Blog" src="{{site.baseurl}}/images/logo.png" /></a>
+
+ <div>
+ <span id="slogan"></span>
- <!-- Header links -->
- <nav>
- <a class="extra" href="{{site.baseurl}}/">/home</a> ·
- <a class="extra" href="{{site.baseurl}}/archive.html">archive</a> ·
- <a class="extra" href="{{site.baseurl}}/licence.html">licence</a> ·
- <a class="extra" href="{{site.baseurl}}/blogroll.html">blogroll</a> ·
- <a class="extra" href="/enter/impressum.html">impress</a> ·
- <a class="extra" href="{{site.baseurl}}/about.html">about</a>
- </nav>
-
- <!-- Slogan -->
- <span id="slogan"></span>
+ <!-- Header links -->
+ <nav>
+ <a class="extra" href="{{site.baseurl}}/archive.html" style="border: none;">archive</a>
+ <a class="extra" href="{{site.baseurl}}/licence.html">licence</a>
+ <a class="extra" href="{{site.baseurl}}/blogroll.html">blogroll</a>
+ <a href="javascript:void(0)" title="show a random blogpost" onclick="javascript:getRandomPost();" class="extra">random!</a>
+ <a class="extra" href="javascript:void(0)" title="hide everything but content" id="cleanup">clean layout</a>
+ <a class="extra" href="/enter/impressum.html">impress</a>
+ <a class="extra" href="{{site.baseurl}}/about.html">about</a>
+ </nav>
+ </div>
+
+ <input type="search" name="query" id="query" placeholder="Search me!">
</header>
{{ content }}
<div class="footer">
- &copy; 2009 - {{ site.time | date:"%Y" }} <a href="/">Ganz-Sicher.Net Blog</a> · proudly powered by <a href="http://jekyllrb.com/">jekyll</a> & <a href="http://validator.w3.org/check/referer">optimized</a> for HTML5
+ &copy; 2009 - {{ site.time | date:"%Y" }} <a href="/">Ganz-Sicher.Net Blog</a> · proudly powered by <a href="http://jekyllrb.com/">jekyll</a> &amp; <a href="http://validator.w3.org/check/referer">optimized</a> for HTML5
</div>
View
@@ -1,15 +1,25 @@
---
layout: default
---
+<!-- Jquery Site-Search -->
+<script src="{{site.baseurl}}/js/search.js" type="text/javascript"></script>
+<script>$(document).ready(function(){ $('#query').show(); $(window).trigger( 'hashchange' ); });</script>
+
+<div id="searchresults">
+ <h3 id="searchtitle">Suchergebnis</h3>
+ <div id="results"></div>
+</div>
+
+<div id="prepost">
+<h1>{{ page.title }}</h1>
+<span id="articleinfo">Artikel vom {{ page.date | date:"%d.%m.%Y" }}, <b>Bereich</b>: {{ page.category }}</span>
+
<div id="socialbuttons">
{% include js/twitter.html %}
{% include js/gplus.html %}
{% include flattr.html %}
</div>
-<div id="prepost">
-<h1>{{ page.title }}</h1>
-<span id="articleinfo">Artikel vom {{ page.date | date:"%d.%m.%Y" }}, <b>Bereich</b>: {{ page.category }}</span>
</div>
<div id="post">
@@ -1,6 +1,6 @@
---
layout: post
-title: Libre Office - Start beschleunigen & Spashscreen deaktiveren
+title: Libre Office - Start beschleunigen &amp; Spashscreen deaktiveren
wordpress_id: 1376
wordpress_url: http://ganz-sicher.net/blog/?p=1376
date: 2011-06-13 15:57:00.000000000 +02:00
@@ -0,0 +1,218 @@
+---
+layout: post
+title: Einfache Suchfunktion mit jQuery für (statische) Blogs
+date: 2012-04-19 23:05
+category: programmierung-scripting
+---
+<img src="{{site.url}}/images/blog/old-edit-find.png" class="lefticon" alt="" />
+Nachdem ich mit meinem Blog auf [Jekyll](http://jekyllrb.com/) <a href="{{site.url}}/blognews/Umstieg-von-Wordpress-nach-Jekyll/">umgestiegen bin</a>, habe ich zunächst auf eine Suchfunktion verzichtet. Da Jekyll statische HTML-Seiten erzeugt, werden für die Suche oft externe Dienste wie die [Googles Custom Search](https://developers.google.com/custom-search/v1/overview), [Tapir](http://tapirgo.com/) oder [indexthank](http://indextank.com/) empfohlen. Letzterer Anbieter hat sein Angebot mittlerweile bereits eingestellt und verweist auf der Homepage auf Alternativen. Die Abhängigkeit von einem solchen Dienst hat mich daher eher abgeschreckt. Gerade weil eine Suchfunktion meist keine ressourcenschonende Sache ist, ist eine lange Lebensdauer dieser Suchdienste keine Selbstverständlichkeit. Auch erschien es mir für ein paar zig HTML-Seiten ein ziemlicher Overkill zu sein. ;)
+Jetzt besitzt das Blog eine kleine Javascript/jQuery-getriebene Suche (oben rechts!) - reicht meiner Meinung nach völlig und ist mit einem einfachen Ajax-Request / dem Filtern des RSS-Feeds mit wenig Code einsatzbereit.<!--more-->
+
+Eigene Suchfunktion mit jQuery
+===============================
+Um mich nicht mit fremden Federn zu schmücken: Die Idee für die jQuery-Suchfunktion stammt von [hier](http://joevennix.com/2011/05/25/How-I-Implement-Static-Site-Search.html). Ich habe den Code leicht angepasst, die wesentliche Funktionsweise bleibt aber die selbe: Der RSS-Feed (der eine einfache XML-Datei ist), wird mit einem $ajax-Call geladen und mit Query und javascript in einem Array gespeichert. Dessen Einträge werden dann mit einem einfachen Regex auf die Suchbegriffe geprüft und bei Treffern in ein anderes Array gelegt. Das Treffer-Array kann dann als HTML-Code ausgegeben werden. Damit auch Suchadressen direkt in den Browser eingegeben werden können, wird [jQuery BBQ](http://benalman.com/projects/jquery-bbq-plugin/) verwendet, die einfache Benutzung von "Hash-Adressen" (z.B. [ganz-sicher.net/blog/#search=test](http://ganz-sicher.net/blog/#search=test)) ermöglicht.
+
+HTML-Code
+---------
+
+{% highlight html %}
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
+ <script src="https://raw.github.com/cowboy/jquery-bbq/v1.2.1/jquery.ba-bbq.min.js" type="text/javascript"></script>
+
+ <!-- Suchfeld -->
+ <input type="search" name="query" id="query" placeholder="Search me!">
+
+ <!-- main code: jQuery siteSearch -->
+ <script src="js/search.js" type="text/javascript"></script>
+
+ <!-- show search input after page loaded / show search results when user starts search from the browser-address-bar -->
+ <script>$(document).ready(function(){ $('#query').show(); $(window).trigger( 'hashchange' ); });</script>
+
+ <!-- hidden by default, matches will be added to #results later -->
+ <div id="searchresults">
+ <h3 id="searchtitle">Search results</h3>
+ <div id="results"></div>
+ </div>
+{% endhighlight %}
+
+Da die Suche nur mit JavaScript nutzbar ist, wird Suchfeld sowie Ergebnisbereich (#searchresults) per Default nicht angezeigt und erst mit JavaScript sichtbar gemacht.
+
+
+CSS-Code
+---------
+
+{% highlight css %}
+#query
+{
+ background-image: url("http://ganz-sicher.net/blog/images/icons/search.png");
+ background-position: 2px center;
+ background-repeat: no-repeat;
+ border: 1px solid #CBD0D5;
+ color: gray;
+ float: right;
+ margin: 2px 2px 0 0;
+ padding: 1px 3px 1px 24px;
+ width: 200px;
+ display: none;
+}
+
+#searchresults
+{
+ display: none;
+ margin: 15px 0 35px 0;
+ display: none;
+ border: 1px solid yellowGreen;
+ padding: 5px;
+ background: whitesmoke;
+}
+
+#searchtitle
+{
+ color: #ccc;
+ text-shadow: 1px 1px white;
+ float: right;
+}
+{% endhighlight %}
+
+
+search.js Code
+==============
+
+Die <a href="{{site.baseurl}}/js/search.js">search.js</a> enthält den die wichtigsten Funktionen für die Suche, im Einzelnen sind das:
+
+ * ein jQuery-Eventhandler, der beim Abschicken (Eingabetaste) einer Suchanfrage die Browseradresse ändert
+ * eine jQuery .bind()-Funktion, die daraufhin aufgerufen wird, den Feed (und die Einträge) lädt und dann findEntries() aufruft
+ * eine findEntries()-Funktion, die Treffer in ein Array legt und den Ergebnis-HTML-Code erzeugt
+ * eine (optionale) simpleDate()-Funktion, die das Jekyll-Datum in ein lesbares Datum umwandelt
+
+jQuery-Eventhandler für das Suchfeld
+--------------------------------------
+{% highlight javascript %}
+var feedLocation = '/blog/feed.xml';
+var defaultSearchInput = 'Search me!';
+
+var oldHtml = null;
+var entries = null;
+
+
+// start searching if enter key is pressed in the focused search field
+$('#query').keypress(function(e) {
+ var code = (e.keyCode ? e.keyCode : e.which);
+ var query = $('#query').val();
+
+ if (code == 13) {
+
+ if (query != '') {
+ window.location.hash = 'search='+escape(query.replace(/\s/g, '+'));
+ e.preventDefault();
+ }
+ else {
+ $('#searchresults').hide();
+ }
+ }
+});
+{% endhighlight %}
+
+Die findEntries()-Funktion
+---------------------------
+{% highlight javascript %}
+// given regex q, find matches in entries dom document
+// generates a HTML string (resultString) with the search result, adds it to the #results div and
+// makes the result element visible
+function findEntries(q) {
+ var matches = [];
+ var rq = new RegExp(q, 'im');
+
+ for (var i = 0; i < entries.length; i++) {
+ var entry = entries[i];
+
+ // get elements
+ var title = $(entry.getElementsByTagName('title')[0]).text();
+ var link = $(entry.getElementsByTagName('link')[0]).text();
+ var content = $(entry.getElementsByTagName('description')[0]).text();
+
+ // add matches
+ if (rq.test(title) || rq.test(link) || rq.test(content)) {
+ var updated = simpleDate($(entry.getElementsByTagName('published')[0]).text());
+ matches.push({'title':title, 'link':link, 'date':updated});
+ }
+ }
+
+ // Build search results
+ var resultCount = matches.length;
+ var resultString;
+
+ if (resultCount > 0){
+ resultString = "<span id='articleinfo' style='font-size: 14px; padding: 2px 20px; background-position: 2px 2px; border: 1px solid #ddd;'>" + resultCount + " Entries were found! :)</span><br />";
+
+ // show all entries
+ for (var i = 0; i < resultCount ; i++) {
+ resultString += '<span style="color: rgb(170, 170, 170); font-family: Monaco,\'Courier New\',monospace; font-size: 13px;">' +matches[i]['date'] + ' » </span> <a href="' + matches[i]['link'] + '">' + matches[i]['title'] + '</a><br />';
+ }
+
+ }
+ else {
+ resultString = "No entries found. ;/";
+ }
+
+ // show the hidden result-div
+ $('#results').html(resultString);
+ $('#searchresults').show();
+
+}
+{% endhighlight %}
+
+jQuery .bind()-Funktion
+------------------------
+{% highlight javascript %}
+$(window).bind('hashchange', function(e) {
+
+ // called when the part of the URL after the hash (#) changes
+ var query = $.param.fragment(); // e.g. "#search=text"
+
+ if (/[#]*search=(.*)/.test(query)) {
+ query = $.param.fragment().replace('+', ' ').replace('search=', '');
+ $('#query').val(query); // in case the user browsed to the search
+ if (query) {
+ if (oldHtml == null) { // save state!
+ oldHtml = $('#content').html();
+ }
+ $('#content').html('<div id="loader"></div>');
+ $('#footer').hide();
+ $('#query').blur().attr('disabled', true);
+ if (entries == null) {
+
+ // lazily load and parse the atom.xml feed
+ $.ajax({type: 'GET', url: feedLocation, data: '', dataType:'xml', async: false, success: function(data) {
+ entries = data.getElementsByTagName('item');
+ findEntries(query);
+ }});
+ } else {
+ // search the pre-loaded atom.xml feed
+ findEntries(query);
+ }
+ // disable the search bar until current search is complete
+ $('#query').blur().attr('disabled', false);
+ }
+ } else {
+ // revert to original page, hide search results
+ if (oldHtml == null) {
+ oldHtml = $('#content').html();
+ }
+ $('#content').html(oldHtml);
+ $('#footer').show();
+ $('#query').blur();
+ oldHtml = null;
+ }
+});
+{% endhighlight %}
+
+Demo
+----
+Wie bereits geschrieben, kann diese Suchfunktion nach Herzenslust oben rechts getestet werden. Wenn ihr die Suche bei eurem eigenen XML-Feed ausprobieren möchtet, solltet ihr darauf achten, dass Sonderzeichen richtig escaped werden (z.B. &amp; statt &), der ajax-Request schlägt sonst z.B. beim Chrome fehl.
+Falls ihr weitere Fragen dazu habt, antworte ich gerne im Kommentarbereich, auch für Verbesserungsvorschläge bin ich immer offen. ;)
+
+
+Linkliste (Archiv) filtern mit jQuery
+======================================
+Neben dieser netten kleinen Suche, habe ich mich auch auf meiner <a href="{{site.baseurl}}/archive.html">Archivseite</a> inspirieren lassen. Die Filter-Funktion auf [dieser 404-Seite](http://edwardhotchkiss.com/404.html) hat es mir angetan. ([Blogeintrag dazu](http://edwardhotchkiss.com/blog/2012/03/11/jekyll-live-search-with-angular.js/)). Da ich neben jQuery nicht auch noch [AngularJS](http://angularjs.org/) einsetzen wollte, habe ich das mit jQuery (mithilfe von eines [jQuery Listfilters](http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html) und [jQuery highlight](http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html)) nachgebaut. Das Ergebnis findet sich unter <a href="{{site.baseurl}}/js/archiveFilter.js">archiveFilter.js</a>.
View
@@ -5,7 +5,15 @@
<div id="home">
<div class="nicehead"><span class="nice">Blog Archive</span> <span class="niceinfo">(all posts, German)</span></div>
- Diese Seite enthält alle Artikel, die ich in meinem Blog geschrieben habe. Die Links sind absteigend nach Datum der Veröffentlichung sortiert.
+ This Page contains all (german) Blogposts. The list is ordered by Date (descending order), you can filter by date/title/tag by using the following input field.
+
+ <form class="filterform" action="#">
+ <input id="searchText" class="filterinput" type="text" placeholder="Enter a search term to filter the posts below!" />
+ </form>
+
+
+<script src="{{site.baseurl}}/js/archiveFilter.js" type="text/javascript"></script>
+<script src="{{site.baseurl}}/js/highlight.js" type="text/javascript"></script>
{% assign posts_collate = site.posts %}
{% include posts_collate.html %}
Oops, something went wrong.

0 comments on commit 42a0bfe

Please sign in to comment.