Tag intersections.
authorRadek Czajka <rczajka@rczajka.pl>
Tue, 29 Nov 2022 14:55:47 +0000 (15:55 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Tue, 29 Nov 2022 14:55:47 +0000 (15:55 +0100)
src/catalogue/static/2022/book/filter.js
src/catalogue/templates/catalogue/2022/author_detail.html
src/catalogue/templatetags/catalogue_tags.py
src/catalogue/views.py
src/wolnelektury/static/2022/styles/local.scss

index 15d4e34..ac26749 100644 (file)
@@ -2,6 +2,13 @@
 
     $(".quick-filter").each(function() {
         let bookList = $('#' + $(this).data('for'));
+        let filterList = $('.' + $(this).data('filters'));
+        $(this).on('focus', function() {
+            filterList.addClass('filters-enabled');
+        });
+        $(this).on('blur', function() {
+            filterList.removeClass('filters-enabled');
+        });
         $(this).on('input propertychange', function() {
             let search = $(this).val().toLowerCase();
             bookList.children().each(function() {
index 17514ed..c063d9e 100644 (file)
@@ -1,11 +1,12 @@
 {% extends '2022/base.html' %}
+{% load catalogue_tags %}
 
 {% load choose_cites from social_tags %}
 
 
 {% block breadcrumbs %}
   <a href="/katalog/"><span>Katalog</span></a>
-  <a href="/katalog/autor/"><span>Autor</span></a>
+  <a href="{{ tags.0.get_absolute_catalogue_url }}"><span>{{ tags.0.get_category_display|title }}</span></a>
 {% endblock %}
 
 {% block main %}
       <div class="l-books__header">
         <div class="l-books__input">
           <i class="icon icon-filter"></i>
-          <input type="text" placeholder="filtry, tytuł" class="quick-filter" data-for="book-list">
+          <input type="text" placeholder="filtry, tytuł" class="quick-filter" data-for="book-list" data-filters="with-filter">
+          <div class="filter-container">
+            {% for tag in tags %}
+              {% if forloop.counter > 1 %}
+                <span class="filter">
+                  <a href="{{ tag.get_absolute_url }}">{{ tag }}</a>
+                  <a href="{% catalogue_url 'books' tags -tag %}">✖</a>
+                </span>
+              {% endif %}
+            {% endfor %}
+          </div>
+
+          </span>
         </div>
         <div class="l-books__sorting">
              <span>Sortuj:</span>
              </div>
       </div>
     </div>
+    <div class="l-author with-filter">
+
+      <div class="row">
+        <h2>{% nice_title_from_tags tags categories %}</h2>
+        <div class="filter-container">
+          {% for tag in suggest %}
+            <span class="filter">
+              <a href="{% catalogue_url 'books' tags tag %}">{{ tag }}</a>
+            </span>
+          {% endfor %}
+        </div>
+      </div>
+    </div>
 
     <div class="l-section l-section--col">
       <div class="l-books__grid" id="book-list">
index 7189e95..718ffd3 100644 (file)
@@ -65,66 +65,78 @@ def book_title_html(book):
 
 @register.simple_tag
 def title_from_tags(tags):
+    # TODO: Remove this after adding flection mechanism
+    return simple_title(tags)
+
+
+@register.simple_tag
+def nice_title_from_tags(tags, related_tags):
     def split_tags(tags):
         result = {}
         for tag in tags:
-            result[tag.category] = tag
+            result.setdefault(tag.category, []).append(tag)
         return result
 
-    # TODO: Remove this after adding flection mechanism
-    return simple_title(tags)
-
-    class Flection(object):
-        def get_case(self, name, flection):
-            return name
-    flection = Flection()
-
     self = split_tags(tags)
 
-    title = ''
-
-    # Specjalny przypadek oglądania wszystkich lektur na danej półce
-    if len(self) == 1 and 'set' in self:
-        return 'Półka %s' % self['set']
-
-    # Specjalny przypadek "Twórczość w pozytywizmie", wtedy gdy tylko epoka
-    # jest wybrana przez użytkownika
-    if 'epoch' in self and len(self) == 1:
-        text = 'Twórczość w %s' % flection.get_case(str(self['epoch']), 'miejscownik')
-        return capfirst(text)
-
-    # Specjalny przypadek "Dramat w twórczości Sofoklesa", wtedy gdy podane
-    # są tylko rodzaj literacki i autor
-    if 'kind' in self and 'author' in self and len(self) == 2:
-        text = '%s w twórczości %s' % (
-            str(self['kind']), flection.get_case(str(self['author']), 'dopełniacz'))
-        return capfirst(text)
-
-    # Przypadki ogólniejsze
-    if 'theme' in self:
-        title += 'Motyw %s' % str(self['theme'])
+    pieces = []
+    plural = True
+    epoch_reduntant = False
 
     if 'genre' in self:
-        if 'theme' in self:
-            title += ' w %s' % flection.get_case(str(self['genre']), 'miejscownik')
+        pieces.append([
+            t.plural or t.name for t in self['genre']
+        ])
+        epoch_reduntant = self['genre'][-1].genre_epoch_specific
+    else:
+        # If we don't have genre,
+        # look if maybe we only have one genre in this context?
+        if 'genre' in related_tags and len(related_tags['genre']) == 1:
+            pieces.append([
+                t.plural or t.name for t in related_tags['genre']
+            ])
+            epoch_reduntant = related_tags['genre'][-1].genre_epoch_specific
+        elif 'kind' in self:
+            # Only use kind if not talking about genre.
+            pieces.append([
+                t.collective_noun or t.name for t in self['kind']
+            ])
+            plural = False
+        elif 'kind' in related_tags and len(related_tags['kind']) == 1:
+            # No info on genre, but there's only one kind related.
+            subpieces = []
+            pieces.append([
+                t.collective_noun or t.name for t in self['kind']
+            ])
+            plural = False
         else:
-            title += str(self['genre'])
+            # We can't say anything about genre or kind.
+            pieces.append(['Twórczość'])
+            plural = False
 
-    if 'kind' in self or 'author' in self or 'epoch' in self:
-        if 'genre' in self or 'theme' in self:
-            if 'kind' in self:
-                title += ' w %s ' % flection.get_case(str(self['kind']), 'miejscownik')
-            else:
-                title += ' w twórczości '
+    if not epoch_reduntant and 'epoch' in self:
+        if plural:
+            form = lambda t: t.adjective_nonmasculine_plural or t.name
         else:
-            title += '%s ' % str(self.get('kind', 'twórczość'))
+            form = lambda t: t.adjective_feminine_singular or t.name
+        pieces.append([
+            form(t) for t in self['epoch']
+        ])
 
     if 'author' in self:
-        title += flection.get_case(str(self['author']), 'dopełniacz')
-    elif 'epoch' in self:
-        title += flection.get_case(str(self['epoch']), 'dopełniacz')
-
-    return capfirst(title)
+        pieces.append([
+            t.genitive or t.name for t in self['author']
+        ])
+    
+    p = []
+    for sublist in pieces:
+        for item in sublist[:-2]:
+            p.append(item) + ','
+        for item in sublist[-2:-1]:
+            p.append(item) + ' i'
+        p.append(sublist[-1])
+
+    return ' '.join(p)
 
 
 @register.simple_tag
index d1fc0c9..8c66af7 100644 (file)
@@ -122,6 +122,10 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
             objects = prefetch_relations(objects, 'author')
 
     categories = split_tags(*related_tag_lists)
+    suggest = []
+    for c in ['author', 'epoch', 'kind', 'genre']:
+        if len(categories.get(c, [])) > 1:
+            suggest.extend(categories[c][:4])
 
     objects = list(objects)
 
@@ -137,6 +141,7 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
     result = {
         'object_list': objects,
         'categories': categories,
+        'suggest': suggest,
         'list_type': list_type,
         'tags': tags,
 
@@ -147,16 +152,16 @@ def object_list(request, objects, fragments=None, related_tags=None, tags=None,
     if extra:
         result.update(extra)
 
-    is_author = len(tags) == 1 and tags[0].category == 'author'
     is_set = len(tags) == 1 and tags[0].category == 'set'
     is_theme = len(tags) == 1 and tags[0].category == 'theme'
     new_layout = request.EXPERIMENTS['layout']
-    if is_author and new_layout.value:
-        template = 'catalogue/2022/author_detail.html'
-    elif is_set and new_layout.value:
+
+    if is_set and new_layout.value:
         template = 'catalogue/2022/set_detail.html'
     elif is_theme and new_layout.value:
         template = 'catalogue/2022/theme_detail.html'
+    elif new_layout.value:
+        template = 'catalogue/2022/author_detail.html'
     else:
         template = 'catalogue/tagged_object_list.html'
         
index 5f63275..1dea8ca 100644 (file)
@@ -179,3 +179,54 @@ $teal: #007880;
         }
     }
 }
+
+
+.filter-container {
+    position: absolute;
+    top: 15px;
+    bottom: 25px;
+
+    display: flex;
+    align-items: center;
+
+    .filter {
+        background: #FBC40F;
+        padding: 5px 10px;
+        margin-left: 5px;
+        border-radius: 15px;
+    }
+}
+
+.with-filter {
+    padding: 20px 0 0;
+    position: relative;
+
+    h2 {
+        margin-bottom: 0;
+    }
+}
+.with-filter .row div.filter-container {
+    background: white;
+    top: 0;
+    bottom: 100%;
+    opacity: 0;
+    overflow: hidden;
+
+    transition: opacity .2s, all .3s;
+    
+}
+.with-filter.filters-enabled {
+    .row div.filter-container{
+        top: 15px;
+        bottom: 5px;
+        opacity: 1;
+    }
+}
+
+.l-books__input .filter-container {
+    top: 0;
+    bottom: 0;
+    right: 10px;
+    padding: 10px 0;
+
+}