Added Wikipedia Info box in search results
authorveltr
Wed, 25 Sep 2013 17:34:18 +0200
changeset 118 3d102aed3213
parent 117 18b5748069f7
child 119 984d0da5e84d
Added Wikipedia Info box in search results
src/jocondelab/static/jocondelab/css/front-common.css
src/jocondelab/static/jocondelab/js/front-common.js
src/jocondelab/static/jocondelab/js/front-notice.js
src/jocondelab/static/jocondelab/js/front-search.js
src/jocondelab/templates/jocondelab/front_search.html
src/jocondelab/templates/jocondelab/partial/notice_list.html
src/jocondelab/templatetags/jlutils.py
src/jocondelab/views/front_office.py
--- a/src/jocondelab/static/jocondelab/css/front-common.css	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/static/jocondelab/css/front-common.css	Wed Sep 25 17:34:18 2013 +0200
@@ -343,10 +343,15 @@
     overflow: hidden;
     float: left;
     position: relative;
+    background: #ffffff;
+}
+
+html[dir=rtl] .notice-item {
+    float: right;
 }
 
 .notice-image {
-    font-size: 0; line-height: 0;
+    font-size: 10px;
 }
 
 .notice-item.notice-hover {
@@ -362,12 +367,12 @@
 }
 
 .notice-contents {
-    position: absolute; padding: 9px; z-index: 1;
-    background: url('../img/background-pinstripe-yellow.png'); border: 1px solid #cccccc; box-shadow: 0 0 5px #333333;
+    position: absolute; padding: 10px; z-index: 1;
 }
 
 .notice-hover .notice-contents {
-    z-index: 2;
+    z-index: 2; background: url('../img/background-pinstripe-yellow.png');
+    border: 1px solid #cccccc; box-shadow: 0 0 5px #333333; padding: 9px;
 }
 
 .notice-contents h2 {
@@ -407,6 +412,32 @@
     font-weight: bold;
 }
 
+/* Wikipedia Box in search results */
+
+.wiki-info {
+    float: left; width: 480px; height: 320px; background: #e8e8f8;
+}
+
+.wiki-info-title {
+    font-size: 16px; font-weight: 700; margin: 10px;
+}
+
+.wiki-info-abstract {
+    font-size: 13px; margin: 0 10px 10px;
+}
+
+.wiki-info-source {
+    color: #0063DC; font-size: 10px; margin: 10px;
+}
+
+.wiki-info-image {
+    max-width: 220px; max-height: 300px; float: left; margin: 10px 10px 2px;
+}
+
+html[dir=rtl] .wiki-info, html[dir=rtl] .wiki-info-image {
+    float: right;
+}
+
 /* Smaller screens adaptation */
 
 @media screen and (max-width: 720px) {
@@ -429,6 +460,42 @@
     }
 }
 
+@media screen and (max-width: 740px) and (min-width: 380px) {
+    .wiki-info {
+        width: 360px; height: 240px;
+    }
+    .wiki-info-image {
+        max-width: 160px; max-height: 220px;
+    }
+    .wiki-info-abstract {
+        font-size: 12px;
+    }
+}
+
+@media screen and (max-width: 380px) and (min-width: 260px) {
+    .wiki-info {
+        width: 240px; height: 240px;
+    }
+    .wiki-info-image {
+        max-width: 100px; max-height: 120px;
+    }
+    .wiki-info-abstract {
+        font-size: 12px;
+    }
+}
+
+@media screen and (max-width: 260px) {
+    .wiki-info {
+        width: 120px; height: 360px;
+    }
+    .wiki-info-image {
+        display: none;
+    }
+    .wiki-info-abstract {
+        font-size: 12px;
+    }
+}
+
 @media screen and (max-width: 540px) {
     
     .header-widgets {
--- a/src/jocondelab/static/jocondelab/js/front-common.js	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/static/jocondelab/js/front-common.js	Wed Sep 25 17:34:18 2013 +0200
@@ -4,8 +4,7 @@
    
     var $searchInput = $(".search-input"),
         originalValue = $searchInput.val(),
-        allowSubmit = false,
-        ajaxsearch = window.ajaxsearch || false;
+        allowSubmit = false;
     
     function submitIfChanged(e, ui) {
         var val = $searchInput.val();
@@ -14,17 +13,6 @@
         }
     }
     
-    if (ajaxsearch) {
-        $(".search-form").submit(function() {
-            var val = $searchInput.val();
-            if (val && val !== originalValue) {
-                originalValue = val;
-                loadSearchResults({ q: val });
-            }
-            return false;
-        });
-    }
-    
     $searchInput.tagit({
         autocomplete: {
             source: urls.ajax_terms,
@@ -195,18 +183,6 @@
             }
             showDbpediaBox(dbpediaUri);
         });
-        $sel.click(function(e) {
-            if (ajaxsearch) {
-                var $this = $(this);
-                allowSubmit = false;
-                $searchInput.tagit("removeAll");
-                $searchInput.tagit("createTag",$this.text());
-                allowSubmit = true;
-                hideDbpediaBox();
-                loadSearchResults({ dbpedia_uri: $this.attr("data-dbpedia-uri") });
-                return false;
-            }
-        });
         $sel.mouseleave(hideDbpediaBox);
     }
         
@@ -256,9 +232,12 @@
     function adaptGrid() {
         var $tblist = $(".notice-list");
         if ($tblist.length) {
-            gridsize = $tblist.children(":first").width() || 160;
+            gridsize = $(".notice-item").width() || 160;
+            var delta = $tblist.parent().width() % gridsize,
+                l = Math.floor(delta/2),
+                r = delta - l;
             $tblist.css({
-                padding: "0 " + Math.floor($tblist.parent().width() % gridsize / 2) + "px"
+                padding: "0 " + l + "px 0 " + r + "px"
             });
         }
         throttledCheckSizes();
@@ -272,13 +251,13 @@
                 $img = $(this).find(".notice-image"),
                 $md = $(this).find(".notice-metadata"),
                 img = $img[0],
+                iw = img.width,
                 ih = img.height;
-            if (ih < 30) {
+            if (!img.complete || iw < 30 || ih < 30) {
                 notloaded = true;
                 return;
             }
-            var iw = img.width,
-                scale = gridsize / Math.min(iw, ih),
+            var scale = Math.min(2, gridsize / Math.min(iw, ih)),
                 nw = scale * iw,
                 nh = scale * ih,
                 ww = $win.width(),
@@ -297,17 +276,17 @@
                 left: isleft ? "0" : "",
                 right: isleft ? "" : "0",
                 width: isfull ? nw : (nw + 260),
-                "margin-top": ((gridsize - nh) / 3 - 10) + "px",
+                "margin-top": ((gridsize - nh) / 2 - 10) + "px",
                 "margin-left": isleft ? ((gridsize - nw) / 2 - 10) + "px" : 0,
                 "margin-right": isleft ? 0 : ((gridsize - nw) / 2 - 10) + "px"
             });
         });
         if (notloaded) {
-            setTimeout(throttledCheckSizes, 500);
+            setTimeout(throttledCheckSizes, 800);
         }
     }
     
-    var throttledCheckSizes = _(checkSizes).throttle(200);
+    var throttledCheckSizes = _(checkSizes).throttle(500);
     
     window.bindResultsMouseover = function() {
         var $items = $(".notice-item");
@@ -339,13 +318,37 @@
     
     /* AJAX SCROLL LOAD */
     
-    var max_scroll_pages = 4;
+    var max_scroll_pages = 3, currentpage;
+    
+    function loadMorePages(query) {
+        $(".load-more").hide();
+        $win.off("scroll.ajaxload");
+        $(".notice-list").empty();
+        $(".loading-please-wait").show();
+        currentpage++;
+        $(".notice-list").attr("data-current-page", currentpage);
+        $.ajax({
+            url: urls.ajax_search,
+            data: _({ page: currentpage }).extend(query),
+            dataType: "html",
+            success: function(html) {
+                $(".notice-list").html(html);
+                bindResultsMouseover();
+                $(".loading-please-wait").hide();
+                scrollLoad(query);
+            }
+        });
+    }
     
     window.scrollLoad = function(query) {
+        currentpage = parseInt($(".notice-list").attr("data-current-page"));
         var loadingnext = false,
-            currentpage = parseInt($(".notice-list").attr("data-current-page")),
             page_count = parseInt($(".notice-list").attr("data-page-count")),
             max_page = Math.min(currentpage + max_scroll_pages, page_count);
+        $(".load-more").hide().off("click").click(function() {
+            loadMorePages(query);
+            return false;
+        });
         $win.on("scroll.ajaxload", function() {
             if (loadingnext || currentpage >= max_page) {
                 return;
@@ -366,9 +369,7 @@
                         bindResultsMouseover();
                         $(".loading-please-wait").hide();
                         if (currentpage >= max_page && currentpage < page_count) {
-                            $(".load-more").show().find("a").attr("href",
-                                urls.ajax_search + "?" + $.param(_({ page: currentpage + 1 }).extend(data))
-                            );
+                            $(".load-more").show();
                         }
                     }
                 });
@@ -396,9 +397,33 @@
     
     /* */
     
+    var $wikinfo = $(".wiki-info"), $wiabstract = $(".wiki-info-abstract"), abstract = $wiabstract.text(), wkw, wkh, wkcontents;
+    
+    function resizeWikiInfo() {
+        if (!$wikinfo.length) {
+            return;
+        }
+        var w = $wikinfo.width(), h = $wikinfo.height();
+        if (w === wkw && h === wkh) {
+            return;
+        }
+        wkw = w;
+        wkh = h;
+        var leftSpace = h - ($(".wiki-info-title").outerHeight(true) + $(".wiki-info-source").outerHeight(true));
+        $wiabstract.text(abstract);
+        var shortenedAbstract = abstract;
+        while ($wiabstract.height() > leftSpace) {
+            shortenedAbstract = shortenedAbstract.replace(/\s[\S]+$/,'…');
+            $wiabstract.text(shortenedAbstract);
+        }
+    }
+    
+    resizeWikiInfo();
+    
     $win.resize(function() {
         adaptGrid();
         recentreDbpediaBox();
+        resizeWikiInfo();
     }).scroll(recentreDbpediaBox);
     
     $overlayImg.load(recentreDbpediaBox);
--- a/src/jocondelab/static/jocondelab/js/front-notice.js	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/static/jocondelab/js/front-notice.js	Wed Sep 25 17:34:18 2013 +0200
@@ -176,8 +176,8 @@
         }
         var o = $curitem.offset();
         $overlay.css({
-            top: o.top + $curitem.outerHeight(),
-            left: o.left - $overlay.outerWidth(),
+            top: o.top + $curitem.outerHeight(true),
+            left: o.left - $overlay.outerWidth(true),
         }).show().attr("data-dbpedia-uri", termdata.dbpedia_uri);
         if (termdata.local.thumbnail) {
             $overlayImg.attr("src",termdata.local.thumbnail).show();
--- a/src/jocondelab/static/jocondelab/js/front-search.js	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/static/jocondelab/js/front-search.js	Wed Sep 25 17:34:18 2013 +0200
@@ -6,8 +6,8 @@
     
     bindResultsMouseover();
     dbpediaBox.bind(".term-cloud a");
-    if (searchterm) {
-        scrollLoad({ q: searchterm });
+    if (typeof queryobj === "object" && queryobj) {
+        scrollLoad(queryobj);
     }
     
 });
--- a/src/jocondelab/templates/jocondelab/front_search.html	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/templates/jocondelab/front_search.html	Wed Sep 25 17:34:18 2013 +0200
@@ -3,11 +3,10 @@
 
 {% block js_declaration %}
     {{block.super}}
+    <script type="text/javascript">
+        var queryobj = {% if queryobj %}{{queryobj|safe}}{% else %}null{% endif %};
+    </script>
     <script type="text/javascript" src="{{STATIC_URL}}jocondelab/js/front-search.js"></script>
-    <script type="text/javascript">
-        var searchterm = "{{searchterm|safe}}",
-            ajaxsearch = true;
-    </script>
 {% endblock %}
 
 {% block title %}JocondeLab &raquo; {% if searchterm %}{% trans 'Résultats pour&nbsp;: &laquo;&nbsp;' %}{{searchterm}}{% trans '&nbsp;&raquo;' %}{% else %}{% trans 'Recherche' %}{% endif %}{% endblock %}
--- a/src/jocondelab/templates/jocondelab/partial/notice_list.html	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/templates/jocondelab/partial/notice_list.html	Wed Sep 25 17:34:18 2013 +0200
@@ -1,5 +1,22 @@
 {% load i18n %}
+{% load jlutils %}
 
+{% if wkinfo %}
+    <li class="wiki-info">
+        {% if wkinfo.thumbnail %}
+        <a href="{{wkinfo.label|wikiurl:lang}}" target="_blank">
+            <img class="wiki-info-image" src="{{wkinfo.thumbnail}}" alt="{{wkinfo.label}}" />
+        </a>
+        {% endif %}
+        <h3 class="wiki-info-title">
+            <a href="{{wkinfo.label|wikiurl:lang}}" target="_blank">{{wkinfo.label}}</a>
+        </h3>
+        <p class="wiki-info-abstract">{{wkinfo.abstract}}</p>
+        <p class="wiki-info-source">
+            <a href="{{wkinfo.label|wikiurl:lang}}" target="_blank">{% trans 'Source : Wikipédia' %}</a>
+        </p>
+    </li>
+{% endif %}
 {% for notice in notices %}
     <li class="notice-item" data-notice-id="{{notice.id}}">
         <div class="notice-contents">
--- a/src/jocondelab/templatetags/jlutils.py	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/templatetags/jlutils.py	Wed Sep 25 17:34:18 2013 +0200
@@ -1,4 +1,5 @@
 from django import template
+from django.utils.http import urlquote
 
 register = template.Library()
 
@@ -9,4 +10,8 @@
             "linked_terms": context['terms_by_thesaurus'].get(fieldname.upper(),None),
             "base_field": getattr(context['object'],fieldname.lower()),
             "row_class": kwargs.get("row_class", None)
-    }
\ No newline at end of file
+    }
+
+@register.filter
+def wikiurl(label, lang):
+    return u"http://%s.wikipedia.org/wiki/%s"%(lang, urlquote(label.replace(" ","_")))
\ No newline at end of file
--- a/src/jocondelab/views/front_office.py	Wed Sep 25 12:47:19 2013 +0200
+++ b/src/jocondelab/views/front_office.py	Wed Sep 25 17:34:18 2013 +0200
@@ -16,6 +16,11 @@
 
 class SearchView(TemplateView):
     
+    # This view is used for
+    # - the home and search pages, displaying random images
+    # - search result pages
+    # - ajax-fetched results
+    
     def get(self, request):
                 
         context = {}
@@ -30,6 +35,7 @@
         show_years = request.GET.get('show_years',False)
         emptysearch = ((not queryterms) and (not dbpedia_uri) and (not from_year))
         npp = request.GET.get('count', 12 if emptysearch else 30)
+        context["lang"] = lang
         context["current_page"] = page
         
         if self.template_name is None:
@@ -42,26 +48,37 @@
                     self.template_name = "jocondelab/front_search.html"
         
         qs = Notice.objects.filter(image=True)
+        
         if emptysearch:
             context["count"] = qs.count()
             ns = qs.order_by('?')[:npp]
         else:
             if dbpedia_uri:
                 qs = qs.filter(noticeterm__term__dbpedia_uri=dbpedia_uri)
+                context["queryobj"] = json.dumps({'dbpedia_uri': dbpedia_uri})
                 if page == 1:
                     termobj = Term.objects.filter(dbpedia_uri=dbpedia_uri)[0]
                     if termobj:
                         termtrans = termobj.dbpedia_fields.filter(language_code = lang)
-                        context["searchterm"] = termtrans[0].label if termtrans.count() else termobj.label
+                        if termtrans.exists():
+                            context["wkinfo"] = termtrans[0]
+                            context["searchterm"] = termtrans[0].label
+                        else:
+                            context["searchterm"] = termobj.label
             if queryterms:
                 context["searchterm"] = querystr
-                for term in queryterms:
-                    fs = DbpediaFields.objects.filter(label=term, language_code=lang).values('term_id').distinct()
+                context["queryobj"] = json.dumps({'q': querystr})
+                for i, term in enumerate(queryterms):
+                    fs = DbpediaFields.objects.filter(label=term, language_code=lang)
+                    if i == 0 and page == 1 and len(queryterms) == 1 and fs.exists():
+                        context["wkinfo"] = fs[0]
+                    fs = fs.values('term_id').distinct()
                     qs = qs.filter(noticeterm__term__in=fs)
             if from_year:
+                context["queryobj"] = json.dumps({'from_year': from_year, 'to_year': to_year})
                 context["searchterm"] = u"%s – %s"%(from_year, to_year)
                 qs = qs.filter(years__start_year__lte=to_year, years__end_year__gte=from_year)
-            qs = qs.distinct()
+            qs = qs.order_by('id').distinct()
             paginator = Paginator(qs, npp)
             context["count"] = paginator.count
             ns = paginator.page(page)
@@ -188,6 +205,7 @@
                      'uri': w['term__dbpedia_uri'],
                      'font_size': "%.2f"%(1. + float(n-i)/n)
                                  } for i, w in enumerate(wqs)]
+            random.shuffle(context['words'])
         
         if thesaurus is not None:
             alphabets = [{