From cce75c3e7962ecb35fad9b2b7492da300e1bcf09 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org>
Date: Tue, 26 Oct 2021 10:36:25 +0200
Subject: [PATCH] Rework homepage with htmx

---
 .../scipost/assets/css/_list_group.scss       |  4 +-
 .../templates/scipost/_index_news.html        | 21 ++++
 .../scipost/_index_participates_in.html       | 14 +++
 .../scipost/_index_publications.html          |  7 ++
 .../templates/scipost/_index_sponsors.html    | 17 ++++
 .../templates/scipost/_index_submissions.html |  7 ++
 .../scipost/templates/scipost/bare_base.html  |  2 +
 .../scipost/templates/scipost/footer.html     |  6 +-
 .../scipost/templates/scipost/index.html      | 96 ++++++++-----------
 scipost_django/scipost/urls.py                | 26 +++++
 scipost_django/scipost/views.py               | 34 ++++++-
 .../templates/submissions/pool/pool2.html     |  4 -
 12 files changed, 168 insertions(+), 70 deletions(-)
 create mode 100644 scipost_django/scipost/templates/scipost/_index_news.html
 create mode 100644 scipost_django/scipost/templates/scipost/_index_participates_in.html
 create mode 100644 scipost_django/scipost/templates/scipost/_index_publications.html
 create mode 100644 scipost_django/scipost/templates/scipost/_index_sponsors.html
 create mode 100644 scipost_django/scipost/templates/scipost/_index_submissions.html

diff --git a/scipost_django/scipost/static/scipost/assets/css/_list_group.scss b/scipost_django/scipost/static/scipost/assets/css/_list_group.scss
index 86c6255bb..626ea2b2e 100644
--- a/scipost_django/scipost/static/scipost/assets/css/_list_group.scss
+++ b/scipost_django/scipost/static/scipost/assets/css/_list_group.scss
@@ -134,11 +134,9 @@ ul.news-list {
             overflow: hidden;
             padding: 0;
             margin: 0.5rem 0;
-            transition: max-height 0.3s ease-in-out;
         }
 
-        &:first-child p,
-        &:hover p {
+        &:first-child p {
             max-height: 1000px;
         }
     }
diff --git a/scipost_django/scipost/templates/scipost/_index_news.html b/scipost_django/scipost/templates/scipost/_index_news.html
new file mode 100644
index 000000000..e47e22fbe
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/_index_news.html
@@ -0,0 +1,21 @@
+<div id="news">
+  <h2 class="title">
+    News
+    <button class="btn btn-link btn-sm m-0 mb-1" href="{% url 'scipost:feeds' %}" aria-label="RSS feeds">{% include 'bi/rss-fill.html' %}</button>
+  </h2>
+  <ul class="news-list">
+    {% for news in news_items %}
+      <li>
+        <h3><a href="{% url 'news:news' %}#news_{{ news.id }}">{{ news.headline }}</a></h3>
+        <div class="text-muted">{{ news.date|date:'j F Y' }}</div>
+        <p>
+	  {{ news.blurb_short }}
+	  <br>
+	  <br>
+	  <a href="{% url 'news:news' %}#news_{{ news.id }}" class="my-1">Read more &rarr;</a>
+        </p>
+      </li>
+    {% endfor %}
+  </ul>
+  <a href="{% url 'news:news' %}" class="my-1">See complete News list</a>
+</div>
diff --git a/scipost_django/scipost/templates/scipost/_index_participates_in.html b/scipost_django/scipost/templates/scipost/_index_participates_in.html
new file mode 100644
index 000000000..7954bedd5
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/_index_participates_in.html
@@ -0,0 +1,14 @@
+{% load static %}
+
+<div class="row">
+  <div class="col-md-4">
+    <h1>SciPost participates in</h1>
+  </div>
+  <div class="col-md-8 logos">
+    <a href="https://www.crossref.org" target="_blank" rel="noopener"><img src="https://assets.crossref.org/logo/crossref-logo-200.svg" width="100" alt="Crossref logo"></a>
+    <a href="https://www.doaj.org" target="_blank" rel="noopener"><img src="{% static 'scipost/images/doaj_logo_200.jpg' %}" width="90" alt="DOAJ logo"></a>
+    <a href="https://www.clockss.org" target="_blank" rel="noopener"><img src="{% static 'scipost/images/clockss_original_logo_boxed_ai-cropped-90.png' %}" width="80" alt="Clockss logo"></a>
+    <a href="https://i4oc.org/" target="_blank" rel="noopener"><img width="100" src="{% static 'scipost/images/I4OC.png' %}" alt="I4OC logo"></a>
+    <a href="https://freejournals.org" target="_blank" rel="noopener"><img width="100" src="{% static 'scipost/images/FJN-logo-long.png' %}" alt="FJN logo"></a>
+  </div>
+</div>
diff --git a/scipost_django/scipost/templates/scipost/_index_publications.html b/scipost_django/scipost/templates/scipost/_index_publications.html
new file mode 100644
index 000000000..4e65e24c2
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/_index_publications.html
@@ -0,0 +1,7 @@
+<ul class="list-group list-group-flush px-3 mb-3">
+  {% for publication in publications %}
+    <li class="list-group-item py-2">
+      {% include 'journals/_publication_li_content.html' with publication=publication %}
+    </li>
+  {% endfor %}
+</ul>
diff --git a/scipost_django/scipost/templates/scipost/_index_sponsors.html b/scipost_django/scipost/templates/scipost/_index_sponsors.html
new file mode 100644
index 000000000..472c7bfb2
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/_index_sponsors.html
@@ -0,0 +1,17 @@
+{% load static %}
+<div id="sponsor-logos"
+     hx-get="{% url 'scipost:_index_sponsors' %}"
+     hx-trigger="every 15s"
+     hx-swap="outerHTML swap:1s"
+>
+  <ul class="list list-unstyled">
+    {% for sponsor in current_sponsors %}
+      {% if sponsor.logo %}
+	<li class="p-2">
+	  <img class="rounded" style="max-height: 10em;"
+	       src="{{ sponsor.logo.url }}" alt="{{ sponsor.name }} logo">
+	</li>
+      {% endif %}
+    {% endfor %}
+  </ul>
+</div>
diff --git a/scipost_django/scipost/templates/scipost/_index_submissions.html b/scipost_django/scipost/templates/scipost/_index_submissions.html
new file mode 100644
index 000000000..3bd5f7aee
--- /dev/null
+++ b/scipost_django/scipost/templates/scipost/_index_submissions.html
@@ -0,0 +1,7 @@
+<ul class="list-group list-group-flush px-3 mb-3">
+  {% for submission in submissions %}
+    <li class="list-group-item py-2">
+      {% include 'submissions/_submission_card_content_homepage.html' with submission=submission %}
+    </li>
+  {% endfor %}
+</ul>
diff --git a/scipost_django/scipost/templates/scipost/bare_base.html b/scipost_django/scipost/templates/scipost/bare_base.html
index 4f8b97c8c..5e59a7b77 100644
--- a/scipost_django/scipost/templates/scipost/bare_base.html
+++ b/scipost_django/scipost/templates/scipost/bare_base.html
@@ -10,6 +10,8 @@
       {% render_bundle 'base' %}
     {% endblock basebundle %}
 
+    <script src="https://unpkg.com/htmx.org@1.6.0" integrity="sha384-G4dtlRlMBrk5fEiRXDsLjriPo8Qk5ZeHVVxS8KhX6D7I9XXJlNqbdvRlp9/glk5D" crossorigin="anonymous"></script>
+
     <link rel="shortcut icon" href="{% static 'scipost/images/scipost_favicon.png' %}"/>
 
     <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
diff --git a/scipost_django/scipost/templates/scipost/footer.html b/scipost_django/scipost/templates/scipost/footer.html
index 6510184a5..d7ff1c7b9 100644
--- a/scipost_django/scipost/templates/scipost/footer.html
+++ b/scipost_django/scipost/templates/scipost/footer.html
@@ -49,10 +49,10 @@
     <div class="row">
       <div class="col-12">
         <br>
-        <a rel="license noopener" href="//creativecommons.org/licenses/by/4.0/" target="_blank" class="m-2">
-          <img alt="Creative Commons License" style="border-width:0" src="//licensebuttons.net/l/by/4.0/80x15.png" />
+        <a rel="license noopener" href="https://creativecommons.org/licenses/by/4.0/" target="_blank" class="m-2">
+          <img alt="Creative Commons License" style="border-width:0" src="https://licensebuttons.net/l/by/4.0/80x15.png" />
         </a>
-        Except where otherwise noted, all content on {{ request.get_host }} is licensed under a <a rel="license noopener" href="//creativecommons.org/licenses/by/4.0/" target="_blank">Creative Commons Attribution 4.0 International License</a>.
+        Except where otherwise noted, all content on {{ request.get_host }} is licensed under a <a rel="license noopener" href="https://creativecommons.org/licenses/by/4.0/" target="_blank">Creative Commons Attribution 4.0 International License</a>.
       </div>
     </div>
   </div>
diff --git a/scipost_django/scipost/templates/scipost/index.html b/scipost_django/scipost/templates/scipost/index.html
index c660c10fb..61f159517 100644
--- a/scipost_django/scipost/templates/scipost/index.html
+++ b/scipost_django/scipost/templates/scipost/index.html
@@ -3,6 +3,22 @@
 {% load render_bundle from webpack_loader %}
 {% load static %}
 
+{% block headsup %}
+  {{ block.super }}
+  <style>
+   #sponsor-logos.htmx-added {
+       opacity: 0;
+   }
+   #sponsor-logos.htmx-swapping {
+       opacity: 0;
+   }
+   #sponsor-logos {
+       opacity: 1;
+       transition: opacity 1s;
+   }
+  </style>
+{% endblock %}
+
 {% block body_class %}{{ block.super }} homepage{% endblock %}
 
 {% block meta_description %}{{ block.super }} homepage{% endblock meta_description %}
@@ -17,13 +33,10 @@
           <h2 class="title mb-3">Latest Publications</h2>
           <hr class="sm mb-0 mt-2">
         </div>
-        <ul class="list-group list-group-flush px-3 mb-3">
-          {% for publication in publications %}
-            <li class="list-group-item py-2">
-              {% include 'journals/_publication_li_content.html' with publication=publication %}
-            </li>
-          {% endfor %}
-        </ul>
+	<div hx-get="{% url 'scipost:_index_publications' %}"
+	     hx-trigger="load"
+	>
+	</div>
         <p class="mb-3 px-3"><a href="{% url 'journals:publications' %}">View all Publications</a></p>
       </div><!-- End latest publications -->
     </div>
@@ -35,13 +48,10 @@
           <h2 class="title mb-3">Latest Submissions</h2>
           <hr class="sm mb-0 mt-2">
         </div>
-        <ul class="list-group list-group-flush px-3 mb-3">
-          {% for submission in submissions %}
-            <li class="list-group-item py-2">
-              {% include 'submissions/_submission_card_content_homepage.html' with submission=submission %}
-            </li>
-          {% endfor %}
-        </ul>
+	<div hx-get="{% url 'scipost:_index_submissions' %}"
+	     hx-trigger="load"
+	>
+	</div>
         <p class="mb-3 px-3"><a href="{% url 'submissions:submissions' %}">View all Submissions</a></p>
       </div><!-- End latest submissions -->
     </div>
@@ -57,28 +67,10 @@
 	<hr class="lg">
       {% endif %}
 
-      <!-- News -->
-      <div id="news">
-	<h2 class="title">
-	  News
-	  <button class="btn btn-link btn-sm m-0 mb-1" href="{% url 'scipost:feeds' %}" aria-label="RSS feeds">{% include 'bi/rss-fill.html' %}</button>
-	</h2>
-	<ul class="news-list">
-	  {% for news in news_items %}
-	    <li>
-              <h3><a href="{% url 'news:news' %}#news_{{ news.id }}">{{ news.headline }}</a></h3>
-              <div class="text-muted">{{ news.date|date:'j F Y' }}</div>
-              <p>
-		{{ news.blurb_short }}
-		<br>
-		<br>
-		<a href="{% url 'news:news' %}#news_{{ news.id }}" class="my-1">Read more &rarr;</a>
-              </p>
-	    </li>
-	  {% endfor %}
-	</ul>
-	<a href="{% url 'news:news' %}" class="my-1">See complete News list</a>
-      </div><!-- End news -->
+      <div hx-get="{% url 'scipost:_index_news' %}"
+	   hx-trigger="load"
+      >
+      </div>
 
     </div>
 
@@ -90,7 +82,7 @@
   <div class="container-fluid text-start secondary pt-4 mt-5 border-top border-primary">
     <div class="row">
       <div class="col-md-8">
-        <h1>Sponsors</h1>
+	<h1>Sponsors</h1>
 	<p>
 	  SciPost guarantees free online access to all publications in all its Journals and does not charge any article processing fees for publishing. Sponsors provide operating funds to SciPost through a cost-slashing consortial model.
 	</p>
@@ -102,31 +94,23 @@
 	</p>
       </div>
       <div class="col-md-4">
-        <a href="{% url 'sponsors:sponsors' %}">See all sponsors</a>
+	<a href="{% url 'sponsors:sponsors' %}">See all sponsors</a>
 	<br>
-        <ul class="list list-unstyled">
-          {% for sponsor in current_sponsors %}
-            {% if sponsor.logo %}
-              <li class="p-2"><img class="rounded" src="{{ sponsor.logo.url }}" alt="{{ sponsor.name }} logo"></li>
-            {% endif %}
-          {% endfor %}
-        </ul>
+	<div id="sponsor-logos"
+	     hx-get="{% url 'scipost:_index_sponsors' %}"
+	     hx-trigger="load"
+	     hx-swap="outerHTML swap:1s"
+	>
+	</div>
       </div>
     </div>
 
     <hr>
 
-    <div class="row">
-      <div class="col-md-4">
-        <h1>SciPost participates in</h1>
-      </div>
-      <div class="col-md-8 logos">
-        <a href="//www.crossref.org" target="_blank" rel="noopener"><img src="//assets.crossref.org/logo/crossref-logo-200.svg" width="100" alt="Crossref logo"></a>
-        <a href="//www.doaj.org" target="_blank" rel="noopener"><img src="{% static 'scipost/images/doaj_logo_200.jpg' %}" width="90" alt="DOAJ logo"></a>
-        <a href="//www.clockss.org" target="_blank" rel="noopener"><img src="{% static 'scipost/images/clockss_original_logo_boxed_ai-cropped-90.png' %}" width="80" alt="Clockss logo"></a>
-        <a href="//i4oc.org/" target="_blank" rel="noopener"><img width="100" src="{% static 'scipost/images/I4OC.png' %}" alt="I4OC logo"></a>
-        <a href="//freejournals.org" target="_blank" rel="noopener"><img width="100" src="{% static 'scipost/images/FJN-logo-long.png' %}" alt="FJN logo"></a>
-      </div>
+    <div hx-get="{% url 'scipost:_index_participates_in' %}"
+	 hx-trigger="load"
+    >
     </div>
+
   </div>
 {% endblock %}
diff --git a/scipost_django/scipost/urls.py b/scipost_django/scipost/urls.py
index a748fd02b..f5eece501 100644
--- a/scipost_django/scipost/urls.py
+++ b/scipost_django/scipost/urls.py
@@ -71,6 +71,32 @@ urlpatterns = [
         views.index,
         name='index'
     ),
+    path(
+        '_index_publications',
+        views._index_publications,
+        name='_index_publications'
+    ),
+    path(
+        '_index_submissions',
+        views._index_submissions,
+        name='_index_submissions'
+    ),
+    path(
+        '_index_news.html',
+        views._index_news,
+        name='_index_news'
+    ),
+    path(
+        '_index_participates_in',
+        TemplateView.as_view(template_name='scipost/_index_participates_in.html'),
+        name='_index_participates_in'
+    ),
+    path(
+        '_index_sponsors',
+        views._index_sponsors,
+        name='_index_sponsors'
+    ),
+
     path(
         'files/secure/<path:path>',
         views.protected_serve,
diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py
index 418347755..a0479e0a9 100644
--- a/scipost_django/scipost/views.py
+++ b/scipost_django/scipost/views.py
@@ -163,17 +163,43 @@ class SearchView(SearchView):
 def index(request):
     """Homepage view of SciPost."""
     context = {
-        'news_items': NewsItem.objects.homepage().order_by('-date')[:4],
-        'latest_newsitem': NewsItem.objects.homepage().order_by('-date').first(),
         'submissions': Submission.objects.public().order_by('-submission_date')[:3],
-        # 'journals': Journal.objects.order_by('name'),
         'publications': Publication.objects.published().order_by('-publication_date',
                                                                  '-paper_nr')[:3],
-        'current_sponsors': Organization.objects.current_sponsors().order_by('?')[:2]
     }
     return render(request, 'scipost/index.html', context)
 
 
+def _index_submissions(request):
+    context = {
+        'submissions': Submission.objects.public().order_by('-submission_date')[:3],
+    }
+    return render(request, 'scipost/_index_submissions.html', context)
+
+
+def _index_publications(request):
+    context = {
+        'publications': Publication.objects.published().order_by('-publication_date',
+                                                                 '-paper_nr')[:3],
+    }
+    return render(request, 'scipost/_index_publications.html', context)
+
+
+def _index_news(request):
+    context = {
+        'news_items': NewsItem.objects.homepage().order_by('-date')[:4],
+        'latest_newsitem': NewsItem.objects.homepage().order_by('-date').first(),
+    }
+    return render(request, 'scipost/_index_news.html', context)
+
+
+def _index_sponsors(request):
+    context = {
+        'current_sponsors': Organization.objects.current_sponsors().order_by('?')[:1]
+    }
+    return render(request, 'scipost/_index_sponsors.html', context)
+
+
 def protected_serve(request, path, show_indexes=False):
     """
     Serve media files from outside the public MEDIA_ROOT folder.
diff --git a/scipost_django/submissions/templates/submissions/pool/pool2.html b/scipost_django/submissions/templates/submissions/pool/pool2.html
index bbd7d4a2d..30b6e0935 100644
--- a/scipost_django/submissions/templates/submissions/pool/pool2.html
+++ b/scipost_django/submissions/templates/submissions/pool/pool2.html
@@ -2,10 +2,6 @@
 
 {% load crispy_forms_tags %}
 
-{% block headsup %}
-  <script src="https://unpkg.com/htmx.org@1.6.0" integrity="sha384-G4dtlRlMBrk5fEiRXDsLjriPo8Qk5ZeHVVxS8KhX6D7I9XXJlNqbdvRlp9/glk5D" crossorigin="anonymous"></script>
-{% endblock headsup %}
-
 {% block body_class %}{{ block.super }} pool{% endblock %}
 
 {% block breadcrumb %}
-- 
GitLab