Removed json version of results from the ajax API. Improved checks for search existen...
authorStephen Burrows <stephen.r.burrows@gmail.com>
Wed, 8 Jun 2011 21:31:27 +0000 (17:31 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Wed, 8 Jun 2011 21:36:51 +0000 (17:36 -0400)
philo/contrib/sobol/models.py
philo/contrib/sobol/search.py
philo/contrib/sobol/static/sobol/ajax_search.js [new file with mode: 0644]
philo/contrib/sobol/templates/sobol/search/_list.html [new file with mode: 0644]
philo/contrib/sobol/templates/sobol/search/basesearch.html
philo/contrib/sobol/templates/sobol/search/googlesearch.html

index 43b78b4..27f91d1 100644 (file)
@@ -241,11 +241,12 @@ class SearchView(MultiView):
                                
                                search_instances = []
                                for slug in self.searches:
-                                       search_instance = get_search_instance(slug, search_string)
-                                       search_instances.append(search_instance)
+                                       if slug in registry:
+                                               search_instance = get_search_instance(slug, search_string)
+                                               search_instances.append(search_instance)
                                        
-                                       if self.enable_ajax_api:
-                                               search_instance.ajax_api_url = "%s?%s=%s" % (self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node), SEARCH_ARG_GET_KEY, search_string)
+                                               if self.enable_ajax_api:
+                                                       search_instance.ajax_api_url = "%s?%s=%s" % (self.reverse('ajax_api_view', kwargs={'slug': slug}, node=request.node), SEARCH_ARG_GET_KEY, search_string)
                                
                                if eventlet and not self.enable_ajax_api:
                                        pool = eventlet.GreenPool()
@@ -280,14 +281,13 @@ class SearchView(MultiView):
                """
                search_string = request.GET.get(SEARCH_ARG_GET_KEY)
                
-               if not request.is_ajax() or not self.enable_ajax_api or slug not in self.searches or search_string is None:
+               if not request.is_ajax() or not self.enable_ajax_api or slug not in registry or slug not in self.searches or search_string is None:
                        raise Http404
                
                search_instance = get_search_instance(slug, search_string)
                
                return HttpResponse(json.dumps({
-                       'results': [result.get_context() for result in search_instance.results],
-                       'rendered': [result.render() for result in search_instance.results],
-                       'hasMoreResults': search.has_more_results(),
-                       'moreResultsURL': (u"?%s" % search.more_results_querydict.urlencode()) if search.more_results_querydict else None,
+                       'results': [result.render() for result in search_instance.results],
+                       'hasMoreResults': search_instance.has_more_results,
+                       'moreResultsURL': (u"?%s" % search_instance.more_results_querydict.urlencode()) if search_instance.more_results_querydict else None,
                }), mimetype="application/json")
\ No newline at end of file
index 5cc8090..b117eaa 100644 (file)
@@ -187,7 +187,7 @@ class BaseSearchMetaclass(type):
                if 'verbose_name' not in attrs:
                        attrs['verbose_name'] = capfirst(' '.join(convert_camelcase(name).rsplit(' ', 1)[:-1]))
                if 'slug' not in attrs:
-                       attrs['slug'] = name.lower()
+                       attrs['slug'] = name[:-6].lower() if name.endswith("Search") else name.lower()
                return super(BaseSearchMetaclass, cls).__new__(cls, name, bases, attrs)
 
 
@@ -199,8 +199,8 @@ class BaseSearch(object):
        
        """
        __metaclass__ = BaseSearchMetaclass
-       #: The number of results to return from the complete list. Default: 10
-       result_limit = 10
+       #: The number of results to return from the complete list. Default: 5
+       result_limit = 5
        #: How long the items for the search should be cached (in minutes). Default: 48 hours.
        _cache_timeout = 60*48
        #: The path to the template which will be used to render the :class:`Result`\ s for this search.
@@ -272,19 +272,23 @@ class BaseSearch(object):
                """Returns any extra context to be used when rendering the ``result``."""
                return {}
        
+       @property
        def has_more_results(self):
                """Returns ``True`` if there are more results than :attr:`result_limit` and ``False`` otherwise."""
                return len(self.results) > self.result_limit
        
        @property
        def more_results_url(self):
-               """Returns the actual url for more results. This should be accessed through :attr:`more_results_querydict` in the template so that the click can be tracked."""
-               raise NotImplementedError
+               """Returns the actual url for more results. This should be accessed through :attr:`more_results_querydict` in the template so that the click can be tracked. By default, simply returns ``None``."""
+               return None
        
        @property
        def more_results_querydict(self):
                """Returns a :class:`QueryDict` for tracking whether people click on a 'more results' link."""
-               return make_tracking_querydict(self.search_arg, self.more_results_url)
+               url = self.more_results_url
+               if url:
+                       return make_tracking_querydict(self.search_arg, url)
+               return None
        
        def __unicode__(self):
                return self.verbose_name
@@ -344,6 +348,7 @@ class GoogleSearch(JSONSearch):
        _cache_timeout = 60
        verbose_name = "Google search (current site)"
        result_template = "sobol/search/googlesearch.html"
+       _more_results_url = None
        
        @property
        def query_format_str(self):
diff --git a/philo/contrib/sobol/static/sobol/ajax_search.js b/philo/contrib/sobol/static/sobol/ajax_search.js
new file mode 100644 (file)
index 0000000..d4885b6
--- /dev/null
@@ -0,0 +1,33 @@
+(function($){
+       var sobol = window.sobol = {}
+       sobol.setup = function(){
+               var searches = sobol.searches = $('article.search');
+               for (i=0;i<searches.length;i++) {
+                       (function(){
+                               var s = searches[i];
+                               $.ajax({
+                                       url: s.getAttribute('data-url'),
+                                       dataType: 'json',
+                                       success: function(data){
+                                               $(s).removeClass('loading')
+                                               if (data['results'].length) {
+                                                       s.innerHTML += "<dl>" + data['results'].join("") + "</dl>";
+                                                       if(data['hasMoreResults'] && data['moreResultsURL']) s.innerHTML += "<footer><p><a href='" + data['moreResultsURL'] + "'>See more results</a></p></footer>";
+                                               } else {
+                                                       $(s).addClass('empty')
+                                                       s.innerHTML += "<p>No results found.</p>"
+                                               }
+                                       },
+                                       error: function(data, textStatus, errorThrown){
+                                               $(s).removeClass('loading');
+                                               text = errorThrown ? errorThrown : textStatus ? textStatus : "Error occurred."
+                                               if (errorThrown) {
+                                                       s.innerHTML += "<p>" + errorThrown + "</p>"
+                                               };
+                                       }
+                               });
+                       }());
+               };
+       };
+       $(sobol.setup);
+}(jQuery));
\ No newline at end of file
diff --git a/philo/contrib/sobol/templates/sobol/search/_list.html b/philo/contrib/sobol/templates/sobol/search/_list.html
new file mode 100644 (file)
index 0000000..f78d861
--- /dev/null
@@ -0,0 +1,23 @@
+{% with node.view.enable_ajax_api as ajax %}
+{% if ajax %}<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script><script type="text/javascript" src="{{ STATIC_URL }}sobol/ajax_search.js"></script>{% endif %}
+{% for search in searches %}
+<article {% if ajax %}class="search loading {{ search.slug }}" data-url="{{ search.ajax_api_url }}" data-title="{{ search }}"{% else %}class="search {{ search.slug }}"{% endif %}>
+       <header>
+               <a name='{{ search.slug }}'></a>
+               <h1>{{ search }}</h1>
+       </header>
+       {% if not ajax %}
+               <dl>
+               {% for result in search.results %}
+               {{ result }}
+               {% endfor %}
+               </dl>
+               {% if search.has_more_results and search.more_results_url %}
+               <footer>
+                       <p><a href="?{{ search.more_results_querydict.urlencode }}">See more results</a></p>
+               </footer>
+               {% endif %}
+       {% endif %}
+</article>
+{% endfor %}
+{% endwith %}
\ No newline at end of file
index 9469143..e7661ac 100644 (file)
@@ -1 +1 @@
-{% if url %}<a href='{{ url }}'>{% endif %}{{ title }}{% if url %}</a>{% endif %}
\ No newline at end of file
+<dt>{% if url %}<a href='{{ url }}'>{% endif %}{{ title }}{% if url %}</a>{% endif %}</dt>
\ No newline at end of file
index 1b22388..8d23132 100644 (file)
@@ -1,4 +1,2 @@
-<article>
-       <h1><a href="{{ url }}">{{ title|safe }}</a></h1>
-       <p>{{ content|safe }}</p>
-</article>
\ No newline at end of file
+<dt><a href="{{ url }}">{{ title|safe }}</a></dt>
+<dd>{{ result.content|safe }}</dd>
\ No newline at end of file