From 655e3172532205cb087f9342853d4cb746326d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-S=C3=A9bastien=20Caux?= <git@jscaux.org> Date: Thu, 28 Oct 2021 09:31:07 +0200 Subject: [PATCH] Rework homepage, introduce portal page --- scipost_django/ontology/context_processors.py | 22 ++- scipost_django/ontology/forms.py | 51 ++++- .../ontology/session_specialty_form.html | 8 + scipost_django/ontology/urls.py | 10 + scipost_django/ontology/views.py | 42 ++++- .../scipost/assets/css/_list_group.scss | 36 ---- .../static/scipost/assets/css/_navbar.scss | 15 ++ .../scipost/templates/scipost/_hx_news.html | 14 ++ ...pates_in.html => _hx_participates_in.html} | 0 ...ublications.html => _hx_publications.html} | 3 + ..._index_sponsors.html => _hx_sponsors.html} | 6 +- ..._submissions.html => _hx_submissions.html} | 3 + .../templates/scipost/_index_news.html | 21 --- .../scipost/templates/scipost/bare_base.html | 4 +- .../scipost/templates/scipost/header.html | 15 +- .../header_with_acad_field_and_spec.html | 22 +++ .../scipost/templates/scipost/index.html | 175 +++++++++++++----- .../scipost/templates/scipost/portal.html | 52 ++++++ scipost_django/scipost/urls.py | 41 ++-- scipost_django/scipost/views.py | 41 ++-- 20 files changed, 420 insertions(+), 161 deletions(-) create mode 100644 scipost_django/ontology/templates/ontology/session_specialty_form.html create mode 100644 scipost_django/scipost/templates/scipost/_hx_news.html rename scipost_django/scipost/templates/scipost/{_index_participates_in.html => _hx_participates_in.html} (100%) rename scipost_django/scipost/templates/scipost/{_index_publications.html => _hx_publications.html} (88%) rename scipost_django/scipost/templates/scipost/{_index_sponsors.html => _hx_sponsors.html} (75%) rename scipost_django/scipost/templates/scipost/{_index_submissions.html => _hx_submissions.html} (80%) delete mode 100644 scipost_django/scipost/templates/scipost/_index_news.html create mode 100644 scipost_django/scipost/templates/scipost/header_with_acad_field_and_spec.html create mode 100644 scipost_django/scipost/templates/scipost/portal.html diff --git a/scipost_django/ontology/context_processors.py b/scipost_django/ontology/context_processors.py index 2b8e0d02f..93cf1d60a 100644 --- a/scipost_django/ontology/context_processors.py +++ b/scipost_django/ontology/context_processors.py @@ -3,7 +3,7 @@ __license__ = "AGPL v3" from .models import Branch, AcademicField, Specialty -from .forms import SessionAcademicFieldForm +from .forms import SessionAcademicFieldForm, SessionSpecialtyForm def ontology_processor(request): @@ -15,13 +15,27 @@ def ontology_processor(request): 'branches': Branch.objects.all(), 'acad_fields': AcademicField.objects.all(), } - initial = {} + initial_acad_field = {} if request.session.get('session_acad_field_slug', None): try: context['session_acad_field'] = AcademicField.objects.get( slug=request.session.get('session_acad_field_slug')) - initial['acad_field_slug'] = request.session.get('session_acad_field_slug') + initial_acad_field['acad_field_slug'] = request.session.get('session_acad_field_slug') except AcademicField.DoesNotExist: context['session_acad_field'] = None - context['session_acad_field_form'] = SessionAcademicFieldForm(initial=initial) + context['session_acad_field_form'] = SessionAcademicFieldForm(initial=initial_acad_field) + initial_specialty = {} + # If AcademicField is set, deal with Specialty + if context['session_acad_field']: + if request.session.get('session_specialty_slug', None): + try: + context['session_specialty'] = Specialty.objects.get( + slug=request.session.get('session_specialty_slug')) + initial_specialty['specialty_slug'] = request.session.get('session_specialty_slug') + except Specialty.DoesNotExist: + context['session_specialty'] = None + context['session_specialty_form'] = SessionSpecialtyForm( + acad_field_slug=request.session['session_acad_field_slug'], + initial=initial_specialty + ) return context diff --git a/scipost_django/ontology/forms.py b/scipost_django/ontology/forms.py index 5ab547dc3..b27e04efc 100644 --- a/scipost_django/ontology/forms.py +++ b/scipost_django/ontology/forms.py @@ -10,7 +10,7 @@ from crispy_bootstrap5.bootstrap5 import FloatingField from dal import autocomplete from .constants import TOPIC_RELATIONS_ASYM -from .models import Branch, AcademicField, Tag, Topic +from .models import Branch, AcademicField, Specialty, Tag, Topic def academic_field_slug_choices(): @@ -20,16 +20,16 @@ def academic_field_slug_choices(): )), ) for branch in Branch.objects.all(): - if branch.name == 'Multidisciplinary': - continue - subchoices = () - for acad_field in branch.academic_fields.all(): - subchoices += ( - (acad_field.slug, acad_field.name), + if branch.name != 'Multidisciplinary' and branch.journals.active().exists(): + subchoices = () + for acad_field in branch.academic_fields.all(): + if acad_field.journals.active().exists(): + subchoices += ( + (acad_field.slug, acad_field.name), + ) + choices += ( + (branch.name, subchoices), ) - choices += ( - (branch.name, subchoices), - ) return choices @@ -49,6 +49,37 @@ class SessionAcademicFieldForm(forms.Form): ) +def specialty_slug_choices(acad_field_slug): + specialties = Specialty.objects.filter( + acad_field__slug=acad_field_slug) if acad_field_slug else Specialty.objects.none() + choices = ( + ('', '--------'), + ) + for specialty in specialties.all(): + choices += ((specialty.slug, str(specialty)),) + return choices + + +class SessionSpecialtyForm(forms.Form): + specialty_slug = forms.ChoiceField( + label='Specialty', + ) + + def __init__(self, *args, **kwargs): + try: + acad_field_slug = kwargs.pop('acad_field_slug') + except KeyError: + acad_field_slug = '' + super().__init__(*args, **kwargs) + self.fields['specialty_slug'].choices = specialty_slug_choices(acad_field_slug) + self.helper = FormHelper(self) + self.helper.disable_csrf = True + self.helper.show_errors = True + self.helper.layout = Layout( + Div(FloatingField('specialty_slug')) + ) + + class SelectTagsForm(forms.Form): tags = forms.ModelMultipleChoiceField( queryset=Tag.objects.all(), diff --git a/scipost_django/ontology/templates/ontology/session_specialty_form.html b/scipost_django/ontology/templates/ontology/session_specialty_form.html new file mode 100644 index 000000000..aeb52e69f --- /dev/null +++ b/scipost_django/ontology/templates/ontology/session_specialty_form.html @@ -0,0 +1,8 @@ +{% load crispy_forms_tags %} +<form id="session_specialty_form" + hx-get="{% url 'ontology:set_session_specialty' %}" + hx-trigger="change" + hx-swap="outerHTML" +> + {% crispy session_specialty_form %} +</form> diff --git a/scipost_django/ontology/urls.py b/scipost_django/ontology/urls.py index 1f504a004..f5f38e6db 100644 --- a/scipost_django/ontology/urls.py +++ b/scipost_django/ontology/urls.py @@ -39,6 +39,16 @@ urlpatterns = [ views.set_session_acad_field, name='set_session_acad_field' ), + path( + '_hx_session_specialty_form', + views._hx_session_specialty_form, + name='_hx_session_specialty_form' + ), + path( + 'set_session_specialty', + views.set_session_specialty, + name='set_session_specialty' + ), path( '', views.ontology, diff --git a/scipost_django/ontology/views.py b/scipost_django/ontology/views.py index 1ca413595..2d981cd3a 100644 --- a/scipost_django/ontology/views.py +++ b/scipost_django/ontology/views.py @@ -17,7 +17,7 @@ from guardian.decorators import permission_required from .models import AcademicField, Specialty, Tag, Topic, RelationAsym from .forms import ( - SessionAcademicFieldForm, + SessionAcademicFieldForm, SessionSpecialtyForm, SelectTagsForm, SelectLinkedTopicForm, AddRelationAsymForm ) @@ -31,6 +31,7 @@ def set_session_acad_field(request): form = SessionAcademicFieldForm(request.GET or None) if form.is_valid(): request.session['session_acad_field_slug'] = form.cleaned_data['acad_field_slug'] + request.session['session_specialty_slug'] = '' try: initial = { 'acad_field_slug': AcademicField.objects.get( @@ -48,6 +49,45 @@ def set_session_acad_field(request): return response +def _hx_session_specialty_form(request): + """Serve the session Specialty choice form.""" + context = { + 'session_specialty_form': SessionSpecialtyForm( + acad_field_slug=request.session.get('session_acad_field_slug', None), + initial={ 'specialty_slug': request.session.get('session_specialty_slug', None)} + ) + } + return render(request, 'ontology/session_specialty_form.html', context) + + +def set_session_specialty(request): + """Set the Specialty to be viewed in the current user session.""" + form = SessionSpecialtyForm( + request.GET or None, + acad_field_slug=request.session.get('session_acad_field_slug', ''), + ) + if form.is_valid(): + request.session['session_specialty_slug'] = form.cleaned_data['specialty_slug'] + try: + initial = { + 'specialty_slug': Specialty.objects.get( + slug=request.session['session_specialty_slug']).slug + } + except (KeyError, Specialty.DoesNotExist): + initial = {} + form = SessionSpecialtyForm( + acad_field_slug=request.session['session_acad_field_slug'], + initial=initial + ) + response = render( + request, + 'ontology/session_specialty_form.html', + context={ 'session_specialty_form': form} + ) + response['HX-Trigger'] = 'session-specialty-set' + return response + + def ontology(request): context = { 'select_linked_topic_form': SelectLinkedTopicForm(), 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 626ea2b2e..c7044c28b 100644 --- a/scipost_django/scipost/static/scipost/assets/css/_list_group.scss +++ b/scipost_django/scipost/static/scipost/assets/css/_list_group.scss @@ -107,42 +107,6 @@ li, } -ul.news-list { - list-style: none; - margin: 0; - padding: 0; - - h3 { - margin: 0.25rem 0; - - a { - color: $scipost-darkblue; - } - } - - li { - margin-right: 0.5rem; - padding: 0.35rem 0; - border-top: 1px solid #bbb; - - &:first-child { - border-top: 0; - } - - p { - max-height: 0; - overflow: hidden; - padding: 0; - margin: 0.5rem 0; - } - - &:first-child p { - max-height: 1000px; - } - } -} - - ul.communications { list-style: none; padding: 0; diff --git a/scipost_django/scipost/static/scipost/assets/css/_navbar.scss b/scipost_django/scipost/static/scipost/assets/css/_navbar.scss index a6d5647f4..52ad00bec 100644 --- a/scipost_django/scipost/static/scipost/assets/css/_navbar.scss +++ b/scipost_django/scipost/static/scipost/assets/css/_navbar.scss @@ -252,3 +252,18 @@ header .nav-item { } } } + +#session_specialty_form { + + div #div_id_specialty_slug { + margin: 0rem !important; + + #id_specialty_slug { + background-color: $scipost-darkblue; + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"); + border: 2px solid $scipost-lightblue; + border-radius: 2px; + color: $white; + } + } +} diff --git a/scipost_django/scipost/templates/scipost/_hx_news.html b/scipost_django/scipost/templates/scipost/_hx_news.html new file mode 100644 index 000000000..03adff8f1 --- /dev/null +++ b/scipost_django/scipost/templates/scipost/_hx_news.html @@ -0,0 +1,14 @@ +<div id="further-news" class="sp-swap" + hx-get="{% url 'scipost:_hx_news' %}" + hx-trigger="every 15s" + hx-swap="outerHTML swap:1s" +> + <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 →</a> + </p> +</div> diff --git a/scipost_django/scipost/templates/scipost/_index_participates_in.html b/scipost_django/scipost/templates/scipost/_hx_participates_in.html similarity index 100% rename from scipost_django/scipost/templates/scipost/_index_participates_in.html rename to scipost_django/scipost/templates/scipost/_hx_participates_in.html diff --git a/scipost_django/scipost/templates/scipost/_index_publications.html b/scipost_django/scipost/templates/scipost/_hx_publications.html similarity index 88% rename from scipost_django/scipost/templates/scipost/_index_publications.html rename to scipost_django/scipost/templates/scipost/_hx_publications.html index 5b19820dd..cb2e9dadb 100644 --- a/scipost_django/scipost/templates/scipost/_index_publications.html +++ b/scipost_django/scipost/templates/scipost/_hx_publications.html @@ -1,5 +1,7 @@ {% load journals_extras %} +<p class="mb-0 px-3 text-muted">{{ session_acad_field }}{% if session_specialty %}: {{ session_specialty }}{% endif %}</p> +<hr> <ul class="list-group list-group-flush px-3 mb-3"> {% for publication in publications %} <li class="list-group-item py-2"> @@ -26,5 +28,6 @@ </div> </div> {% else %} + <hr> <p class="mb-3 px-3"><a href="{% url 'journals:publications' %}">View all Publications</a></p> {% endif %} diff --git a/scipost_django/scipost/templates/scipost/_index_sponsors.html b/scipost_django/scipost/templates/scipost/_hx_sponsors.html similarity index 75% rename from scipost_django/scipost/templates/scipost/_index_sponsors.html rename to scipost_django/scipost/templates/scipost/_hx_sponsors.html index 472c7bfb2..933d0298d 100644 --- a/scipost_django/scipost/templates/scipost/_index_sponsors.html +++ b/scipost_django/scipost/templates/scipost/_hx_sponsors.html @@ -1,7 +1,7 @@ {% load static %} -<div id="sponsor-logos" - hx-get="{% url 'scipost:_index_sponsors' %}" - hx-trigger="every 15s" +<div id="sponsor-logos" class="sp-swap" + hx-get="{% url 'scipost:_hx_sponsors' %}" + hx-trigger="every 16s" hx-swap="outerHTML swap:1s" > <ul class="list list-unstyled"> diff --git a/scipost_django/scipost/templates/scipost/_index_submissions.html b/scipost_django/scipost/templates/scipost/_hx_submissions.html similarity index 80% rename from scipost_django/scipost/templates/scipost/_index_submissions.html rename to scipost_django/scipost/templates/scipost/_hx_submissions.html index 457a6043e..9ba0ef78b 100644 --- a/scipost_django/scipost/templates/scipost/_index_submissions.html +++ b/scipost_django/scipost/templates/scipost/_hx_submissions.html @@ -1,5 +1,7 @@ {% load journals_extras %} +<p class="mb-0 px-3 text-muted">{{ session_acad_field }}{% if session_specialty %}: {{ session_specialty }}{% endif %}</p> +<hr> <ul class="list-group list-group-flush px-3 mb-3"> {% for submission in submissions %} <li class="list-group-item py-2"> @@ -13,5 +15,6 @@ </ul> {% if not session_acad_field or session_acad_field.journals.active|length > 0 %} + <hr> <p class="mb-3 px-3"><a href="{% url 'submissions:submissions' %}">View all Submissions</a></p> {% endif %} diff --git a/scipost_django/scipost/templates/scipost/_index_news.html b/scipost_django/scipost/templates/scipost/_index_news.html deleted file mode 100644 index e47e22fbe..000000000 --- a/scipost_django/scipost/templates/scipost/_index_news.html +++ /dev/null @@ -1,21 +0,0 @@ -<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 →</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/bare_base.html b/scipost_django/scipost/templates/scipost/bare_base.html index 5379d5f12..365b663bc 100644 --- a/scipost_django/scipost/templates/scipost/bare_base.html +++ b/scipost_django/scipost/templates/scipost/bare_base.html @@ -25,7 +25,9 @@ </head> <body class="{% block body_class %}{% endblock %}"> - {% include 'scipost/header.html' %} + {% block header %} + {% include 'scipost/header.html' %} + {% endblock header %} {% include 'scipost/navbar.html' %} {% block breadcrumb %}{% endblock breadcrumb %} diff --git a/scipost_django/scipost/templates/scipost/header.html b/scipost_django/scipost/templates/scipost/header.html index d3eb9719c..a6bc53055 100644 --- a/scipost_django/scipost/templates/scipost/header.html +++ b/scipost_django/scipost/templates/scipost/header.html @@ -8,16 +8,6 @@ <a href="{% url 'scipost:index' %}"><img src="{% static 'scipost/images/logo_scipost_RGB_HTML_groot.png' %}" alt="SciPost logo" width="180" /></a> </div> - <div class="mx-auto my-4 my-lg-auto"> - <form id="session_acad_field_form" - hx-get="{% url 'ontology:set_session_acad_field' %}" - hx-trigger="change" - hx-swap="outerHTML" - > - {% crispy session_acad_field_form %} - </form> - </div> - <div class="ms-auto me-0 my-4 my-lg-auto"> <form id="header-search-form" method="get" action="{% url 'scipost:search' %}"> <div class="form-floating"> @@ -28,7 +18,10 @@ </div> </form> </div> - </div> + + {% block header_sup %} + {% endblock header_sup %} + </div> </header> diff --git a/scipost_django/scipost/templates/scipost/header_with_acad_field_and_spec.html b/scipost_django/scipost/templates/scipost/header_with_acad_field_and_spec.html new file mode 100644 index 000000000..bdf10ec28 --- /dev/null +++ b/scipost_django/scipost/templates/scipost/header_with_acad_field_and_spec.html @@ -0,0 +1,22 @@ +{% extends 'scipost/header.html' %} +{% load crispy_forms_tags %} + +{% block header_sup %} + <div class="d-lg-flex justify-content-between"> + <div class="mx-auto my-4 my-lg-auto"> + <form id="session_acad_field_form" + hx-get="{% url 'ontology:set_session_acad_field' %}" + hx-trigger="change" + hx-swap="outerHTML" + > + {% crispy session_acad_field_form %} + </form> + </div> + <div class="mx-auto my-4 my-lg-auto" + hx-get="{% url 'ontology:_hx_session_specialty_form' %}" + hx-trigger="load, session-acad-field-set from:body" + > + </div> + + </div> +{% endblock header_sup %} diff --git a/scipost_django/scipost/templates/scipost/index.html b/scipost_django/scipost/templates/scipost/index.html index 07e85742a..934de2e8e 100644 --- a/scipost_django/scipost/templates/scipost/index.html +++ b/scipost_django/scipost/templates/scipost/index.html @@ -7,13 +7,13 @@ {% block headsup %} {{ block.super }} <style> - #sponsor-logos.htmx-added { + .sp-swap.htmx-added { opacity: 0; } - #sponsor-logos.htmx-swapping { + .sp-swap.htmx-swapping { opacity: 0; } - #sponsor-logos { + .sp-swap { opacity: 1; transition: opacity 1s; } @@ -27,58 +27,141 @@ {% block content %} - <div class="row"> + <div class="row gx-4"> <div class="col-md-4"> - <!-- Latest publications --> - <div class="card card-publications bg-light px-1 mb-2 scipost-bar"> - <div class="card-body pb-0"> - <h2 class="title mb-3">Latest Publications</h2> - <hr class="sm mb-0 mt-2"> - </div> - <div hx-get="{% url 'scipost:_index_publications' %}" - hx-trigger="load, session-acad-field-set from:body" - > + <h2 class="highlight text-center mt-0">Portals</h2> + <div class="d-flex justify-content-center"> + <div class="btn-group-vertical w-100" role="group"> + {% for branch in branches %} + {% if branch.name != 'Multidisciplinary' and branch.journals.all|length > 0 %} + {% for acad_field in branch.academic_fields.all %} + {% if acad_field.journals.active.all|length > 0 %} + <a type="button" class="btn-primary w-100 m-1 p-2 text-center" href={% url 'scipost:portal' %}?field={{ acad_field.slug }}><strong>{{ acad_field.name }}</strong></a> + {% endif %} + {% endfor %} + {% endif %} + {% endfor %} </div> - </div><!-- End latest publications --> + </div> </div> - <div class="col-md-4"> - <!-- Latest submissions --> - <div class="card card-submissions bg-light px-1 mb-2 scipost-bar"> - <div class="card-body pb-0"> - <h2 class="title mb-3">Latest Submissions</h2> - <hr class="sm mb-0 mt-2"> - </div> - <div hx-get="{% url 'scipost:_index_submissions' %}" - hx-trigger="load, session-acad-field-set from:body" - > + <div class="col-md-8"> + <div class="card"> + <div class="card-header"> + <h1>Genuinely Open Publishing</h1> + </div> + <div class="card-body"> + <p>SciPost is a complete publishing infrastructure serving professional scientists worldwide.</p> + <div class="row g-2"> + <div class="col-lg-6"> + <div class="card"> + <div class="card-header"> + <h3>We implement<br><a href="{% url 'scipost:about' %}#GOA">Genuine Open Access</a></h3> + </div> + <div class="card-body"> + <ul> + <li>Community Ownership</li> + <li>Open Infrastructure</li> + <li>Copyright to Authors</li> + <li>Open Access</li> + <li>Open Citations</li> + <li>Fee Free</li> + <li>Non Profit</li> + <li>Open Finances</li> + <li>Academic Editing</li> + </ul> + </div> + </div> + </div> + <div class="col-lg-6"> + <div class="card mb-2"> + <div class="card-header"> + <h3>Info</h3> + </div> + <div class="card-body"> + <ul> + <li><a href="{% url 'scipost:contact' %}">Contact us</a></li> + <li><a href="{% url 'scipost:about' %}">About SciPost</a></li> + <li><a href="{% url 'scipost:foundation' %}">The Foundation</a></li> + <li><a href="{% url 'careers:jobopenings' %}">Careers@SciPost</a></li> + <li><a href="{% url 'scipost:FAQ' %}">FAQ</a></li> + </ul> + </div> + </div> + + {% if not user.is_authenticated %} + <!-- Register --> + <div class="card border border-danger"> + <div class="card-header"> + <h3>Register</h3> + </div> + <div class="card-body"> + <p class="mb-1">Professional scientists (PhD students and above) can become Contributors to SciPost by filling the <a href="{% url 'scipost:register' %}">registration form</a>.</p> + </div><!-- End Register --> + </div> + {% endif %} + </div> + </div> </div> - </div><!-- End latest submissions --> - </div> - - <div class="col-md-4"> - {% if not user.is_authenticated %} - <!-- Register --> - <div id="register"> - <h2>Register</h2> - <p class="mb-1">Professional scientists (PhD students and above) can become Contributors to SciPost by filling the <a href="{% url 'scipost:register' %}">registration form</a>.</p> - </div><!-- End Register --> - - <hr class="lg"> - {% endif %} - - <div hx-get="{% url 'scipost:_index_news' %}" - hx-trigger="load" - > </div> - </div> - </div> + {% endblock %} {% block content_footer %} + + <div class="container-fluid text-start secondary pt-4 mt-5 border-top border-primary"> + <div class="row"> + <div class="col"> + <h1 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> + </h1> + </div> + <div class="col"> + <a href="{% url 'news:news' %}" class="my-1 float-right">See complete News list</a> + </div> + </div> + + <div class="row g-2"> + <div class="col-md-6"> + <div class="card"> + <div class="card-header"> + <h3>Latest</h3> + </div> + <div class="card-body"> + <h3><a href="{% url 'news:news' %}#news_{{ latest_newsitem.id }}">{{ latest_newsitem.headline }}</a></h3> + <div class="text-muted">{{ latest_newsitem.date|date:'j F Y' }}</div> + <p> + {{ latest_newsitem.blurb_short }} + <br> + <br> + <a href="{% url 'news:news' %}#news_{{ latest_newsitem.id }}" class="my-1">Read more →</a> + </p> + </div> + </div> + </div> + + <div class="col-md-6"> + <div class="card"> + <div class="card-header"> + <h3>Further news</h3> + </div> + <div class="card-body"> + <div id="further-news" class="sp-swap" + hx-get="{% url 'scipost:_hx_news' %}" + hx-trigger="load" + hx-swap="outerHTML swap:1s" + > + </div> + </div> + </div> + </div> + </div> + </div> + <div class="container-fluid text-start secondary pt-4 mt-5 border-top border-primary"> <div class="row"> <div class="col-md-8"> @@ -96,8 +179,8 @@ <div class="col-md-4"> <a href="{% url 'sponsors:sponsors' %}">See all sponsors</a> <br> - <div id="sponsor-logos" - hx-get="{% url 'scipost:_index_sponsors' %}" + <div id="sponsor-logos" class="sp-swap" + hx-get="{% url 'scipost:_hx_sponsors' %}" hx-trigger="load" hx-swap="outerHTML swap:1s" > @@ -107,7 +190,7 @@ <hr> - <div hx-get="{% url 'scipost:_index_participates_in' %}" + <div hx-get="{% url 'scipost:_hx_participates_in' %}" hx-trigger="load" > </div> diff --git a/scipost_django/scipost/templates/scipost/portal.html b/scipost_django/scipost/templates/scipost/portal.html new file mode 100644 index 000000000..1bb714e54 --- /dev/null +++ b/scipost_django/scipost/templates/scipost/portal.html @@ -0,0 +1,52 @@ +{% extends 'scipost/base.html' %} + +{% load render_bundle from webpack_loader %} +{% load static %} + + +{% block body_class %}{{ block.super }} homepage{% endblock %} + +{% block meta_description %}{{ block.super }} homepage{% endblock meta_description %} +{% block pagetitle %}Homepage{% endblock pagetitle %} + +{% block header %} + {% include 'scipost/header_with_acad_field_and_spec.html' %} +{% endblock %} + + +{% block content %} + + <div class="row"> + <div class="col-md-4"> + <!-- Latest publications --> + <div class="card card-publications bg-light px-1 mb-2 scipost-bar"> + <div class="card-body pb-0"> + <h2 class="title mb-3">Latest Publications</h2> + <hr class="sm mb-0 mt-2"> + </div> + <div hx-get="{% url 'scipost:_hx_publications' %}" + hx-trigger="load, session-acad-field-set from:body, session-specialty-set from:body" + > + </div> + </div><!-- End latest publications --> + </div> + + <div class="col-md-4"> + <!-- Latest submissions --> + <div class="card card-submissions bg-light px-1 mb-2 scipost-bar"> + <div class="card-body pb-0"> + <h2 class="title mb-3">Latest Submissions</h2> + <hr class="sm mb-0 mt-2"> + </div> + <div hx-get="{% url 'scipost:_hx_submissions' %}" + hx-trigger="load, session-acad-field-set from:body, session-specialty-set from:body" + > + </div> + </div><!-- End latest submissions --> + </div> + + <div class="col-md-4"> + </div> + + </div> +{% endblock %} diff --git a/scipost_django/scipost/urls.py b/scipost_django/scipost/urls.py index f5eece501..88c8564f9 100644 --- a/scipost_django/scipost/urls.py +++ b/scipost_django/scipost/urls.py @@ -66,35 +66,46 @@ urlpatterns = [ TemplateView.as_view(template_name='search/search.html'), name='search' ), + + # Homepage path( '', views.index, name='index' ), + + # Portal + path( + 'portal', + views.portal, + name='portal' + ), + + # HTMX-delivered fragments path( - '_index_publications', - views._index_publications, - name='_index_publications' + '_hx_publications', + views._hx_publications, + name='_hx_publications' ), path( - '_index_submissions', - views._index_submissions, - name='_index_submissions' + '_hx_submissions', + views._hx_submissions, + name='_hx_submissions' ), path( - '_index_news.html', - views._index_news, - name='_index_news' + '_hx_news.html', + views._hx_news, + name='_hx_news' ), path( - '_index_participates_in', - TemplateView.as_view(template_name='scipost/_index_participates_in.html'), - name='_index_participates_in' + '_hx_participates_in', + TemplateView.as_view(template_name='scipost/_hx_participates_in.html'), + name='_hx_participates_in' ), path( - '_index_sponsors', - views._index_sponsors, - name='_index_sponsors' + '_hx_sponsors', + views._hx_sponsors, + name='_hx_sponsors' ), path( diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py index a99c0d6fc..9c5e969c1 100644 --- a/scipost_django/scipost/views.py +++ b/scipost_django/scipost/views.py @@ -163,48 +163,63 @@ class SearchView(SearchView): def index(request): """Homepage view of SciPost.""" context = { - 'submissions': Submission.objects.public().order_by('-submission_date')[:3], - 'publications': Publication.objects.published().order_by('-publication_date', - '-paper_nr')[:3], + 'latest_newsitem': NewsItem.objects.homepage().order_by('-date').first(), } return render(request, 'scipost/index.html', context) -def _index_submissions(request): +def portal(request): + """ + Academic portal entryway. + """ + if request.GET.get('field', None): + request.session['session_acad_field_slug'] = request.GET.get('field', None) + request.session['session_specialty_slug'] = '' + return render(request, 'scipost/portal.html') + + +def _hx_submissions(request): submissions = Submission.objects.public() session_acad_field_slug = request.session.get('session_acad_field_slug', None) if session_acad_field_slug and session_acad_field_slug != 'all': submissions = submissions.filter(acad_field__slug=session_acad_field_slug) + session_specialty_slug = request.session.get('session_specialty_slug', None) + if session_specialty_slug: + submissions = submissions.filter(specialties__slug=session_specialty_slug) context = { 'submissions': submissions.order_by('-submission_date')[:3], } - return render(request, 'scipost/_index_submissions.html', context) + return render(request, 'scipost/_hx_submissions.html', context) -def _index_publications(request): +def _hx_publications(request): publications = Publication.objects.published() session_acad_field_slug = request.session.get('session_acad_field_slug', None) if session_acad_field_slug and session_acad_field_slug != 'all': publications = publications.filter(acad_field__slug=session_acad_field_slug) + session_specialty_slug = request.session.get('session_specialty_slug', None) + if session_specialty_slug: + publications = publications.filter(specialties__slug=session_specialty_slug) context = { 'publications': publications.order_by('-publication_date', '-paper_nr')[:3], } - return render(request, 'scipost/_index_publications.html', context) + return render(request, 'scipost/_hx_publications.html', context) -def _index_news(request): +def _hx_news(request): + latest_newsitem_id = NewsItem.objects.homepage().order_by('-date').first().id context = { - 'news_items': NewsItem.objects.homepage().order_by('-date')[:4], - 'latest_newsitem': NewsItem.objects.homepage().order_by('-date').first(), + 'news': NewsItem.objects.homepage().exclude( + pk=latest_newsitem_id).order_by('?').first(), } - return render(request, 'scipost/_index_news.html', context) + return render(request, 'scipost/_hx_news.html', context) -def _index_sponsors(request): +def _hx_sponsors(request): context = { 'current_sponsors': Organization.objects.current_sponsors().order_by('?')[:1] } - return render(request, 'scipost/_index_sponsors.html', context) + return render(request, 'scipost/_hx_sponsors.html', context) def protected_serve(request, path, show_indexes=False): -- GitLab