-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add app for a custom welcome page (#402)
* Add welcomepage app * Fix typo * Welcome page only visible when any message exists * Add tests
- Loading branch information
1 parent
6ea47fe
commit 0139795
Showing
18 changed files
with
310 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Welcome page with custom message which is the default page if the app is enabled. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
from django.apps import AppConfig | ||
|
||
|
||
class WelcomePageAppConfig(AppConfig): | ||
default_auto_field = 'django.db.models.AutoField' | ||
name = "oioioi.welcomepage" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from django import forms | ||
from django.conf import settings | ||
from django.forms import modelformset_factory | ||
|
||
from oioioi.welcomepage.models import WelcomePageMessage | ||
|
||
|
||
class WelcomePageMessageForm(forms.ModelForm): | ||
class Meta(object): | ||
model = WelcomePageMessage | ||
fields = ['content', 'language'] | ||
|
||
language = forms.ChoiceField( | ||
label="Language", | ||
choices=settings.LANGUAGES, | ||
widget=forms.HiddenInput(), | ||
) | ||
|
||
content = forms.CharField( | ||
label="Content", | ||
widget=forms.Textarea(attrs={ | ||
'rows': 10, | ||
'style': 'white-space: pre;', | ||
'class': 'monospace', | ||
}), | ||
) | ||
|
||
WelcomePageMessageFormset = modelformset_factory( | ||
WelcomePageMessage, | ||
form=WelcomePageMessageForm, | ||
extra=len(settings.LANGUAGES), | ||
min_num=1, | ||
max_num=len(settings.LANGUAGES), | ||
validate_min=True, | ||
validate_max=True, | ||
can_delete=True, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Generated by Django 4.2.16 on 2024-09-06 09:47 | ||
|
||
from django.db import migrations, models | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
initial = True | ||
|
||
dependencies = [ | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name='WelcomePageMessage', | ||
fields=[ | ||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||
('content', models.TextField(blank=True, verbose_name='message')), | ||
('language', models.CharField(max_length=6, verbose_name='language code')), | ||
], | ||
options={ | ||
'verbose_name': 'welcome page message', | ||
'verbose_name_plural': 'welcome page messages', | ||
}, | ||
), | ||
] |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
from django.db import models | ||
from django.utils.safestring import mark_safe | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
|
||
class WelcomePageMessage(models.Model): | ||
content = models.TextField(verbose_name=_("message"), blank=True) | ||
language = models.CharField(max_length=6, verbose_name=_("language code")) | ||
|
||
class Meta: | ||
verbose_name = _("welcome page message") | ||
verbose_name_plural = _("welcome page messages") | ||
|
||
def render_content(self): | ||
return mark_safe(self.content) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
$('textarea').on('keydown', function (e) { | ||
if (e.key === 'Tab') { | ||
e.preventDefault(); | ||
const start = this.selectionStart; | ||
const end = this.selectionEnd; | ||
this.value = this.value.substring(0, start) + '\t' + this.value.substring(end); | ||
this.selectionStart = this.selectionEnd = start + 1; | ||
} | ||
}); |
31 changes: 31 additions & 0 deletions
31
oioioi/welcomepage/templates/welcomepage/welcome-page-edit.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{% extends "base-with-menu.html" %} | ||
{% load i18n static %} | ||
|
||
{% block title %}Edit welcome page content{% endblock %} | ||
|
||
{% block main-content %} | ||
<h2>Edit welcome page content</h2> | ||
<form style="max-width: initial;" method="POST"> | ||
{% csrf_token %} | ||
{% include "ingredients/translation-formset.html" %} | ||
<div class="form-group"> | ||
<a href="{% url 'delete_welcome_page' %}" class="btn btn-danger"> | ||
{% trans "Delete all messages" %} | ||
</a> | ||
</div> | ||
|
||
<div class="form-group"> | ||
<button type="submit" class="btn btn-primary"> | ||
{% trans "Save" %} | ||
</button> | ||
</div> | ||
|
||
</form> | ||
|
||
<script type="text/javascript" src="{% static 'welcomepage/textfield-tab.js' %}"></script> | ||
<script> | ||
new TranslationFormset({ | ||
requiredFieldsSelector: '[id*="content"]' | ||
}); | ||
</script> | ||
{% endblock %} |
20 changes: 20 additions & 0 deletions
20
oioioi/welcomepage/templates/welcomepage/welcome-page.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{% extends "simple-centered.html" %} | ||
{% load i18n %} | ||
|
||
{% block title %}{{ title }}{% endblock %} | ||
|
||
{% block content %} | ||
|
||
{{ welcome_page_msg.render_content }} | ||
|
||
<div class="text-center"> | ||
{% if show_edit_button %} | ||
<div class="form-group"> | ||
<a href="{% url 'edit_welcome_page' %}" class="btn btn-primary mt-3"> | ||
{% trans "Edit message" %} | ||
</a> | ||
</div> | ||
{% endif %} | ||
</div> | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
from oioioi.base.main_page import unregister_main_page_view | ||
from oioioi.base.tests import TestCase | ||
from django.urls import reverse | ||
|
||
from oioioi.welcomepage.models import WelcomePageMessage | ||
|
||
|
||
class TestWelcomePage(TestCase): | ||
fixtures = ['test_users'] | ||
|
||
def test_button_visibility(self): | ||
WelcomePageMessage.objects.create(language='en', content='Welcome to OIOIOI!') | ||
|
||
self.assertTrue(self.client.login(username='test_admin')) | ||
response = self.client.get(reverse('welcome_page')) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertContains(response, 'Edit message') | ||
|
||
self.assertTrue(self.client.login(username='test_user')) | ||
response = self.client.get(reverse('welcome_page')) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertNotContains(response, 'Edit message') | ||
|
||
response = self.client.get(reverse('edit_welcome_page')) | ||
self.assertEqual(response.status_code, 403) | ||
|
||
def test_no_message(self): | ||
self.assertTrue(self.client.login(username='test_user')) | ||
response = self.client.get(reverse('welcome_page')) | ||
self.assertEqual(response.status_code, 403) | ||
|
||
def test_message(self): | ||
self.assertTrue(self.client.login(username='test_user')) | ||
msgs = { | ||
'pl': 'Witaj na OIOIOI!', | ||
'en': 'Welcome to OIOIOI!' | ||
} | ||
for lang, msg in msgs.items(): | ||
WelcomePageMessage.objects.create(language=lang, content=msg) | ||
|
||
for lang, msg in msgs.items(): | ||
self.client.cookies['lang'] = lang | ||
response = self.client.get(reverse('welcome_page')) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertContains(response, msg) | ||
|
||
def test_one_language(self): | ||
self.assertTrue(self.client.login(username='test_user')) | ||
msg = 'Welcome to OIOIOI!' | ||
WelcomePageMessage.objects.create(language='en', content=msg) | ||
|
||
self.client.cookies['lang'] = 'en' | ||
response = self.client.get(reverse('welcome_page')) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertContains(response, msg) | ||
|
||
self.client.cookies['lang'] = 'pl' | ||
response = self.client.get(reverse('welcome_page')) | ||
self.assertEqual(response.status_code, 200) | ||
self.assertContains(response, msg) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from django.urls import re_path | ||
|
||
from oioioi.welcomepage import views | ||
|
||
app_name = 'welcomepage' | ||
|
||
noncontest_patterns = [ | ||
re_path(r'^welcome/$', views.welcome_page_view, name='welcome_page'), | ||
re_path(r'^edit_welcome_page/$', views.edit_welcome_page_view, name='edit_welcome_page'), | ||
re_path(r'^delete_welcome_page/$', views.delete_welcome_page_view, name='delete_welcome_page'), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from oioioi.base.permissions import make_request_condition | ||
from oioioi.welcomepage.models import WelcomePageMessage | ||
|
||
|
||
@make_request_condition | ||
def any_welcome_messages(request): | ||
return WelcomePageMessage.objects.exists() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
from django.urls import reverse | ||
from django.conf import settings | ||
from django.shortcuts import redirect | ||
from django.template.response import TemplateResponse | ||
from django.utils.translation import gettext_lazy as _ | ||
from django.utils.translation import get_language_from_request | ||
|
||
from oioioi.base.admin import system_admin_menu_registry | ||
from oioioi.base.main_page import register_main_page_view | ||
from oioioi.base.permissions import enforce_condition, is_superuser | ||
from oioioi.welcomepage.forms import WelcomePageMessageFormset | ||
from oioioi.welcomepage.models import WelcomePageMessage | ||
from oioioi.welcomepage.utils import any_welcome_messages | ||
|
||
|
||
@register_main_page_view(order=110, condition=any_welcome_messages) | ||
@enforce_condition(any_welcome_messages) | ||
def welcome_page_view(request): | ||
current_language = get_language_from_request(request) | ||
try: | ||
welcome_page_msg = WelcomePageMessage.objects.get(language=current_language) | ||
except WelcomePageMessage.DoesNotExist: | ||
welcome_page_msg = WelcomePageMessage.objects.first() | ||
return TemplateResponse( | ||
request, | ||
'welcomepage/welcome-page.html', | ||
{ | ||
'title': _('Welcome to %(site_name)s') % {'site_name': settings.SITE_NAME}, | ||
'welcome_page_msg': welcome_page_msg, | ||
'show_edit_button': is_superuser(request), | ||
}, | ||
) | ||
|
||
|
||
system_admin_menu_registry.register( | ||
'welcome_page', | ||
_("Edit welcome page"), | ||
lambda request: reverse('edit_welcome_page'), | ||
order=80, | ||
) | ||
@enforce_condition(is_superuser) | ||
def edit_welcome_page_view(request): | ||
if request.method == 'POST': | ||
formset = WelcomePageMessageFormset(request.POST) | ||
if formset.is_valid(): | ||
instances = formset.save(commit=False) | ||
for instance in instances: | ||
instance.save() | ||
for instance in formset.deleted_objects: | ||
instance.delete() | ||
return redirect('welcome_page') | ||
else: | ||
current_language = get_language_from_request(request) | ||
instances = WelcomePageMessage.objects.all() | ||
languages = [lang_short for lang_short, _ in settings.LANGUAGES] | ||
for instance in instances: | ||
languages.remove(instance.language) | ||
formset = WelcomePageMessageFormset( | ||
initial=[ | ||
{'language': lang, 'DELETE': lang != current_language} | ||
for lang in languages | ||
], | ||
queryset=instances, | ||
) | ||
return TemplateResponse( | ||
request, | ||
'welcomepage/welcome-page-edit.html', | ||
{ | ||
'formset': formset | ||
}, | ||
) | ||
|
||
|
||
@enforce_condition(is_superuser) | ||
def delete_welcome_page_view(request): | ||
WelcomePageMessage.objects.all().delete() | ||
return redirect(reverse('index')) |