Commit e3c69375 authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg Committed by Tom van Bussel

Add search functionality to photos app

parent ccd0357e
This diff was suppressed by a .gitattributes entry.
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-10-05 15:13+0200\n"
"PO-Revision-Date: 2018-01-24 20:44+0100\n"
"POT-Creation-Date: 2018-11-05 21:01+0100\n"
"PO-Revision-Date: 2018-11-05 21:02+0100\n"
"Last-Translator: Sébastiaan Versteeg <se_bastiaan@outlook.com>\n"
"Language-Team: \n"
"Language: nl\n"
......@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 2.0.4\n"
"X-Generator: Poedit 2.2\n"
#: admin.py
msgid "Uploading a zip or tar file adds all contained images as photos."
......@@ -106,5 +106,13 @@ msgstr ""
"href=“mailto:media@thalia.nu”>media@thalia.nu</a>."
#: templates/photos/index.html
msgid "Next"
msgstr "Volgende"
msgid "What are you looking for?"
msgstr "Waar ben je naar op zoek?"
#: templates/photos/index.html
msgid "Search"
msgstr "Zoeken"
#: templates/photos/index.html
msgid "No albums found"
msgstr "Geen albums gevonden"
/* Solving this with dynamic a data attribute (i.e. attr(data-rotation)) does not work, as that's a string. */
#page-content {
#photos-index, #photos-album {
.rotate90 {
......@@ -32,4 +31,10 @@
padding: 20px 40px 0 40px;
}
}
.search-form {
.btn {
height: 50px;
}
}
}
{% extends 'base.html' %}
{% load i18n staticfiles compress photos_cards %}
{% load i18n staticfiles compress photos_cards alert %}
{% block title %}{% trans "Photos" %} — {{ block.super }}{% endblock %}
{% block opengraph_title %}{% trans "Photos" %} — {{ block.super }}{% endblock %}
......@@ -7,50 +7,67 @@
{% block header_image %}{% static "img/headers/fixed/banner7.jpg" %}{% endblock header_image %}
{% block body %}
<section id="photos-index" class="page-section">
<div class="container">
<h1 class="text-center section-title">{% trans "Photos" %}</h1>
{% with keys=keywords|join:" " %}
<section id="photos-albums" class="page-section">
<div class="container">
<h1 class="text-center section-title">{% trans "Photos" %}</h1>
<p class="text-center">
{% trans 'Interested in a full resolution version of a photo? Send your request to <a href="mailto:media@thalia.nu">media@thalia.nu</a>.' %}
</p>
<form class="search-form form-inline col-lg-6 offset-lg-3 row mb-2" method="get"
action="{% url 'photos:index' %}#photos-albums">
<input class="form-control col-9" name="keywords" type="text" value="{{ keys }}"
placeholder="{% trans "What are you looking for?" %}"/>
<input class="btn btn-lg btn-primary col-3" type="submit"
value="{% trans "Search" %}"/>
</form>
<p class="text-center">
{% trans 'Interested in a full resolution version of a photo? Send your request to <a href="mailto:media@thalia.nu">media@thalia.nu</a>.' %}
</p>
<div class="row">
{% for album in albums %}
<div class="col-4 col-md-3 my-3">
{% album_card album %}
{% if not albums %}
<div class="mt-4">
{% trans 'No albums found' as info_text %}
{% alert 'info' info_text dismissable=False %}
</div>
{% endfor %}
</div>
<nav>
<ul class="pagination justify-content-center mt-4">
{% if albums.has_previous %}
<li class="page-item">
<a class="page-link"
href="{% url 'photos:index' %}?page={{ albums.previous_page_number }}{% if filter %}&filter={{ filter }}{% endif %}{% if keywords %}&keywords={{ keys }}{% endif %}#albums-directory">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for page in page_range %}
<li class="page-item{% if page == albums.number %} active{% endif %}">
<a class="page-link" href="{% url 'photos:index' %}?page={{ page }}{% if filter %}&filter={{ filter }}{% endif %}{% if keywords %}&keywords={{ keys }}{% endif %}#albums-director">{{ page }}
</a>
</li>
{% else %}
<div class="row">
{% for album in albums %}
<div class="col-4 col-md-3 my-3">
{% album_card album %}
</div>
{% endfor %}
{% if albums.has_next %}
<li class="page-item">
<a class="page-link"
href="{% url 'photos:index' %}?page={{ albums.next_page_number }}{% if filter %}&filter={{ filter }}{% endif %}{% if keywords %}&keywords={{ keys }}{% endif %}">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</section>
</div>
{% endif %}
<nav>
<ul class="pagination justify-content-center mt-4">
{% if albums.has_previous %}
<li class="page-item">
<a class="page-link"
href="{% url 'photos:index' %}?page={{ albums.previous_page_number }}{% if keywords %}&keywords={{ keys }}{% endif %}#photos-albums">
<span aria-hidden="true">&laquo;</span>
<span class="sr-only">Previous</span>
</a>
</li>
{% endif %}
{% for page in page_range %}
<li class="page-item{% if page == albums.number %} active{% endif %}">
<a class="page-link" href="{% url 'photos:index' %}?page={{ page }}{% if keywords %}&keywords={{ keys }}{% endif %}#photos-albums">{{ page }}
</a>
</li>
{% endfor %}
{% if albums.has_next %}
<li class="page-item">
<a class="page-link"
href="{% url 'photos:index' %}?page={{ albums.next_page_number }}{% if keywords %}&keywords={{ keys }}{% endif %}">
<span aria-hidden="true">&raquo;</span>
<span class="sr-only">Next</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</section>
{% endwith %}
{% endblock %}
......@@ -48,7 +48,7 @@ class AlbumIndexTest(TestCase):
with self.subTest(album_objects__count=Album.objects.count()):
response = self.client.get(reverse('photos:index'))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['albums']), 12)
self.assertEqual(len(response.context['albums']), 16)
self.assertEqual(response.context['page_range'], range(1, 3))
for i in range(72):
......@@ -61,7 +61,7 @@ class AlbumIndexTest(TestCase):
with self.subTest(album_objects__count=Album.objects.count()):
response = self.client.get(reverse('photos:index'))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['albums']), 12)
self.assertEqual(len(response.context['albums']), 16)
self.assertEqual(response.context['page_range'], range(1, 6))
def test_empty_page(self):
......@@ -75,6 +75,33 @@ class AlbumIndexTest(TestCase):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['page_range'], range(1, 2))
def test_keywords(self):
Album.objects.create(
title_en='test_album1',
title_nl='test_album1',
date=date(year=2018, month=9, day=5),
slug='test_album1')
Album.objects.create(
title_en='test_album12',
title_nl='test_album12',
date=date(year=2018, month=9, day=5),
slug='test_album2')
Album.objects.create(
title_en='test_album3',
title_nl='test_album3',
date=date(year=2018, month=9, day=5),
slug='test_album3')
for (count, keywords) in [(3, ''), (2, '1'), (1, '12'), (1, '3')]:
with self.subTest(keywords=keywords):
response = self.client.get(
reverse('photos:index') + '?keywords={}'.format(keywords))
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['albums']), count)
self.assertEqual(response.context['page_range'], range(1, 2))
def test_many_pages(self):
for i in range(120):
Album.objects.create(
......@@ -86,20 +113,20 @@ class AlbumIndexTest(TestCase):
with self.subTest(page=1):
response = self.client.get(reverse('photos:index') + '?page=1')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['albums']), 12)
self.assertEqual(len(response.context['albums']), 16)
self.assertEqual(response.context['page_range'], range(1, 6))
with self.subTest(page=4):
response = self.client.get(reverse('photos:index') + '?page=4')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['albums']), 12)
self.assertEqual(len(response.context['albums']), 16)
self.assertEqual(response.context['page_range'], range(2, 7))
with self.subTest(page=9):
response = self.client.get(reverse('photos:index') + '?page=9')
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.context['albums']), 12)
self.assertEqual(response.context['page_range'], range(6, 11))
self.assertEqual(len(response.context['albums']), 8)
self.assertEqual(response.context['page_range'], range(4, 9))
class AlbumTest(TestCase):
......
......@@ -6,6 +6,7 @@ from django.contrib.auth.decorators import login_required
from django.core.paginator import EmptyPage, Paginator
from django.http import Http404
from django.shortcuts import get_object_or_404, render
from django.utils.translation import get_language
from sendfile import sendfile
from photos.models import Album, Photo
......@@ -19,13 +20,19 @@ COVER_FILENAME = 'cover.jpg'
@login_required
def index(request):
keywords = request.GET.get('keywords', '').split()
# Only show published albums
albums = Album.objects.filter(hidden=False)
for key in keywords:
albums = albums.filter(**{
f'title_{get_language()}__icontains': key
})
albums = get_annotated_accessible_albums(request, albums)
albums = albums.order_by('-date')
paginator = Paginator(albums, 12)
paginator = Paginator(albums, 16)
page = request.GET.get('page')
page = 1 if page is None or not page.isdigit() else int(page)
......@@ -50,8 +57,11 @@ def index(request):
page_range = range(page_range_start, page_range_stop)
return render(request, 'photos/index.html', {'albums': albums,
'page_range': page_range})
return render(request, 'photos/index.html', {
'albums': albums,
'page_range': page_range,
'keywords': keywords
})
def _render_album_page(request, album):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment