Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #731 from duvholt/hierarchical-search
Hierarchical search
  • Loading branch information
benjaoming committed Dec 14, 2017
2 parents 2ce67cc + 55753e8 commit 81a9073
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 3 deletions.
17 changes: 15 additions & 2 deletions src/wiki/templates/wiki/base_site.html
Expand Up @@ -39,9 +39,22 @@
{% endblock %}
</div>
<div class="navbar-collapse collapse">
<form class="navbar-form navbar-right" id="wiki-search-form" method="GET" action="{% url 'wiki:search' %}">
<form class="navbar-form navbar-right" id="wiki-search-form" method="GET" action="{% spaceless %}
{% if article or urlpath %}
{% url 'wiki:search' article_id=article.id path=urlpath.path %}
{% else %}
{% url 'wiki:search' %}
{% endif %}
{% endspaceless %}"
>
<div class="input-group">
<input type="search" class="form-control search-query" name="q" placeholder="{% trans "Search..." %}" />
<input type="search" class="form-control search-query" name="q" placeholder="{% spaceless %}
{% if article or urlpath %}
{% trans "Search from current article..." %}
{% else %}
{% trans "Search whole wiki..." %}
{% endif %}
{% endspaceless %}" />
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
<span class="fa fa-search"></span>
Expand Down
5 changes: 5 additions & 0 deletions src/wiki/templates/wiki/search.html
Expand Up @@ -12,6 +12,11 @@ <h1 class="page-header">{% trans "Search results for:" %} {{ search_query }}</h1
<p class="lead">
<div class="pull-right">
<div class="input-group">
{% if urlpath %}
<p>{% trans "Searching in" %} {{ urlpath.article }}</p>
{% else %}
<p>{% trans "Searching whole wiki" %}</p>
{% endif %}
<input type="search" class="form-control search-query" name="q" value="{{ search_query }}" />
<span class="input-group-btn">
<button class="btn btn-default" type="submit">
Expand Down
3 changes: 3 additions & 0 deletions src/wiki/urls.py
Expand Up @@ -200,6 +200,9 @@ def get_article_path_urls(self):
url(r'^(?P<path>.+/|)_dir/$',
self.article_dir_view_class.as_view(),
name='dir'),
url(r'^(?P<path>.+/|)_search/$',
get_class_from_str(self.search_view_class).as_view(),
name='search'),
url(r'^(?P<path>.+/|)_settings/$',
self.article_settings_view_class.as_view(),
name='settings'),
Expand Down
14 changes: 13 additions & 1 deletion src/wiki/views/article.py
Expand Up @@ -670,6 +670,7 @@ class SearchView(ListView):
context_object_name = "articles"

def dispatch(self, request, *args, **kwargs):
self.urlpath = None
# Do not allow anonymous users to search if they cannot read content
if request.user.is_anonymous() and not settings.ANONYMOUS:
return redirect(settings.LOGIN_URL)
Expand All @@ -683,7 +684,17 @@ def dispatch(self, request, *args, **kwargs):
def get_queryset(self):
if not self.query:
return models.Article.objects.none().order_by('-current_revision__created')
articles = models.Article.objects.filter(
articles = models.Article.objects
path = self.kwargs.get('path', None)
if path:
try:
self.urlpath = models.URLPath.get_by_path(path)
article_ids = self.urlpath.get_descendants(
include_self=True).values_list('article_id')
articles = articles.filter(id__in=article_ids)
except (NoRootURL, models.URLPath.DoesNotExist):
raise Http404
articles = articles.filter(
Q(current_revision__title__icontains=self.query) |
Q(current_revision__content__icontains=self.query))
if not permissions.can_moderate(
Expand All @@ -696,6 +707,7 @@ def get_context_data(self, **kwargs):
kwargs = super(SearchView, self).get_context_data(**kwargs)
kwargs['search_form'] = self.search_form
kwargs['search_query'] = self.query
kwargs['urlpath'] = self.urlpath
return kwargs


Expand Down
36 changes: 36 additions & 0 deletions tests/core/test_views.py
Expand Up @@ -432,6 +432,42 @@ def test_empty_query_string(self):
response = self.client.get(resolve_url('wiki:search'), {'q': ''})
self.assertFalse(response.context['articles'])

def test_hierarchy_search(self):

c = self.client

c.post(
resolve_url('wiki:create', path=''),
{'title': 'Test0', 'slug': 'test0', 'content': 'Content test0'}
)
c.post(
resolve_url('wiki:create', path=''),
{'title': 'Test1', 'slug': 'test1', 'content': 'Content test1'}
)
c.post(
resolve_url('wiki:create', path='test0/'),
{'title': 'Subtest0', 'slug': 'subtest0', 'content': 'Content test2'}
)

response = c.get(resolve_url('wiki:search', path='test0/'), {'q': 'Content test'})
articles = response.context['articles']

def contains_title(articles, title):
return any(article.current_revision.title == title for article in articles)

self.assertTrue(contains_title(articles, 'Test0'))
self.assertFalse(contains_title(articles, 'Test1'))
self.assertTrue(contains_title(articles, 'Subtest0'))

def test_hierarchy_search_404(self):

c = self.client

response = c.get(resolve_url(
'wiki:search', path='test0/'), {'q': 'Content test'})

self.assertEqual(response.status_code, 404)


class DeletedListViewTest(RequireRootArticleMixin, ArticleWebTestUtils, DjangoClientTestBase):

Expand Down

0 comments on commit 81a9073

Please sign in to comment.