diff --git a/combo/data/migrations/0049_sitesettings.py b/combo/data/migrations/0049_sitesettings.py
new file mode 100644
index 00000000..f6577d15
--- /dev/null
+++ b/combo/data/migrations/0049_sitesettings.py
@@ -0,0 +1,38 @@
+# Generated by Django 2.2.19 on 2021-08-25 14:12
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('data', '0048_page_edit_roles'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='SiteSettings',
+ fields=[
+ (
+ 'id',
+ models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
+ ),
+ (
+ 'initial_login_page_path',
+ models.CharField(
+ max_length=100,
+ verbose_name='Initial login page path',
+ help_text='Page to redirect to the first time user logs in.',
+ ),
+ ),
+ (
+ 'welcome_page_path',
+ models.CharField(
+ max_length=100,
+ verbose_name='Welcome page path',
+ help_text='Page to redirect to on the first visit, to suggest user to log in.',
+ ),
+ ),
+ ],
+ ),
+ ]
diff --git a/combo/data/migrations/0050_populate_site_settings.py b/combo/data/migrations/0050_populate_site_settings.py
new file mode 100644
index 00000000..70d099c7
--- /dev/null
+++ b/combo/data/migrations/0050_populate_site_settings.py
@@ -0,0 +1,25 @@
+# Generated by Django 2.2.19 on 2021-08-31 10:10
+
+from django.conf import settings
+from django.db import migrations
+
+
+def create_site_settings(apps, schema_editor):
+ SiteSettings = apps.get_model('data', 'SiteSettings')
+ site_settings = SiteSettings.objects.create()
+ if hasattr(settings, 'COMBO_INITIAL_LOGIN_PAGE_PATH'):
+ site_settings.initial_login_page_path = settings.COMBO_INITIAL_LOGIN_PAGE_PATH or ''
+ if hasattr(settings, 'COMBO_WELCOME_PAGE_PATH'):
+ site_settings.welcome_page_path = settings.COMBO_WELCOME_PAGE_PATH or ''
+ site_settings.save()
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('data', '0049_sitesettings'),
+ ]
+
+ operations = [
+ migrations.RunPython(create_site_settings),
+ ]
diff --git a/combo/data/models.py b/combo/data/models.py
index b2457526..ae6b9b3c 100644
--- a/combo/data/models.py
+++ b/combo/data/models.py
@@ -2204,3 +2204,16 @@ def cell_maintain_page_cell_cache(sender, instance=None, **kwargs):
page.save(update_fields=['last_update_timestamp'])
return
page.build_cell_cache()
+
+
+class SiteSettings(models.Model):
+ initial_login_page_path = models.CharField(
+ _('Initial login page path'),
+ help_text=_('Page to redirect to the first time user logs in.'),
+ max_length=100,
+ )
+ welcome_page_path = models.CharField(
+ _('Welcome page path'),
+ help_text=_('Page to redirect to on the first visit, to suggest user to log in.'),
+ max_length=100,
+ )
diff --git a/combo/manager/forms.py b/combo/manager/forms.py
index f06a30ee..b5f173ef 100644
--- a/combo/manager/forms.py
+++ b/combo/manager/forms.py
@@ -24,7 +24,7 @@ from django.template import Template, TemplateSyntaxError
from django.template.loader import TemplateDoesNotExist, get_template
from django.utils.translation import ugettext_lazy as _
-from combo.data.models import Page, ParentContentCell, compile_sub_slug
+from combo.data.models import Page, ParentContentCell, SiteSettings, compile_sub_slug
from .fields import ImageIncludingSvgField
@@ -317,3 +317,9 @@ class SiteExportForm(forms.Form):
assets = forms.BooleanField(label=_('Assets'), required=False, initial=True)
asset_files = forms.BooleanField(label=_('Assets Files'), required=False, initial=False)
payment = forms.BooleanField(label=_('Online Payment'), required=False, initial=True)
+
+
+class SiteSettingsForm(forms.ModelForm):
+ class Meta:
+ model = SiteSettings
+ fields = '__all__'
diff --git a/combo/manager/templates/combo/manager_home.html b/combo/manager/templates/combo/manager_home.html
index 7dcb1026..12f95547 100644
--- a/combo/manager/templates/combo/manager_home.html
+++ b/combo/manager/templates/combo/manager_home.html
@@ -15,6 +15,7 @@
{% trans 'Export Site' %}
{% trans 'Import Site' %}
{% trans 'Anomaly report' %}
+{% trans 'Site Settings' %}
{% for extra_action in extra_actions %}
{{ extra_action.text }}
{% endfor %}
diff --git a/combo/manager/templates/combo/site_settings.html b/combo/manager/templates/combo/site_settings.html
new file mode 100644
index 00000000..0e3bedb8
--- /dev/null
+++ b/combo/manager/templates/combo/site_settings.html
@@ -0,0 +1,18 @@
+{% extends "combo/manager_base.html" %}
+{% load i18n %}
+
+{% block appbar %}
+{% trans "Site Settings" %}
+{% endblock %}
+
+{% block content %}
+
+
+{% endblock %}
diff --git a/combo/manager/urls.py b/combo/manager/urls.py
index 5b68248c..430ce556 100644
--- a/combo/manager/urls.py
+++ b/combo/manager/urls.py
@@ -29,6 +29,7 @@ urlpatterns = [
url(r'^menu.json$', views.menu_json),
url(r'^site-export$', staff_required(views.site_export), name='combo-manager-site-export'),
url(r'^site-import$', staff_required(views.site_import), name='combo-manager-site-import'),
+ url(r'^site-settings$', views.site_settings, name='combo-manager-site-settings'),
url(
r'^cells/invalid-report/$',
staff_required(views.invalid_cell_report),
diff --git a/combo/manager/views.py b/combo/manager/views.py
index dd44575b..1c1a4a88 100644
--- a/combo/manager/views.py
+++ b/combo/manager/views.py
@@ -46,7 +46,7 @@ from django.views.generic import (
from combo import plugins
from combo.data.library import get_cell_class
-from combo.data.models import CellBase, LinkListCell, Page, PageSnapshot, ParentContentCell
+from combo.data.models import CellBase, LinkListCell, Page, PageSnapshot, ParentContentCell, SiteSettings
from combo.data.utils import (
ImportSiteError,
MissingSubSlug,
@@ -75,6 +75,7 @@ from .forms import (
PageVisibilityForm,
SiteExportForm,
SiteImportForm,
+ SiteSettingsForm,
)
@@ -995,3 +996,15 @@ class LinkListOrder(ManagedPageMixin, View):
link_list_order = LinkListOrder.as_view()
+
+
+class SiteSettingsView(UpdateView):
+ form_class = SiteSettingsForm
+ template_name = 'combo/site_settings.html'
+ success_url = reverse_lazy('combo-manager-homepage')
+
+ def get_object(self):
+ return SiteSettings.objects.get()
+
+
+site_settings = SiteSettingsView.as_view()
diff --git a/combo/public/views.py b/combo/public/views.py
index 8e581e42..ec7d8eb3 100644
--- a/combo/public/views.py
+++ b/combo/public/views.py
@@ -54,6 +54,7 @@ from combo.data.models import (
ParentContentCell,
PostException,
Redirect,
+ SiteSettings,
TextCell,
)
from combo.data.utils import MissingSubSlug, get_page_from_url_parts
@@ -459,9 +460,10 @@ def page(request):
if not parts:
parts = ['index']
+ site_settings = SiteSettings.objects.get()
if (
parts == ['index']
- and settings.COMBO_INITIAL_LOGIN_PAGE_PATH
+ and site_settings.initial_login_page_path
and (request.user and not request.user.is_anonymous)
):
profile, dummy = Profile.objects.get_or_create(user=request.user)
@@ -469,17 +471,17 @@ def page(request):
# first connection of user, record that and redirect to welcome URL
profile.initial_login_view_timestamp = timezone.now()
profile.save()
- return HttpResponseRedirect(settings.COMBO_INITIAL_LOGIN_PAGE_PATH)
+ return HttpResponseRedirect(site_settings.initial_login_page_path)
if (
parts == ['index']
- and settings.COMBO_WELCOME_PAGE_PATH
+ and site_settings.welcome_page_path
and (not request.user or request.user.is_anonymous)
):
if not request.session.setdefault('visited', False):
# first visit, the user is not logged in.
request.session['visited'] = True
- return HttpResponseRedirect(settings.COMBO_WELCOME_PAGE_PATH)
+ return HttpResponseRedirect(site_settings.welcome_page_path)
try:
page = get_page_from_url_parts(parts, request)
diff --git a/combo/settings.py b/combo/settings.py
index 952850a0..312c1227 100644
--- a/combo/settings.py
+++ b/combo/settings.py
@@ -267,12 +267,6 @@ LINGO_NO_ONLINE_PAYMENT_REASONS = {}
JSON_CELL_TYPES = {}
-# page to redirect the first time the user logs in.
-COMBO_INITIAL_LOGIN_PAGE_PATH = None
-
-# page to redirect on the first visit, to suggest user to log in.
-COMBO_WELCOME_PAGE_PATH = None
-
# dashboard support
COMBO_DASHBOARD_ENABLED = False
diff --git a/tests/test_manager.py b/tests/test_manager.py
index 7c4d1642..8c2d08ed 100644
--- a/tests/test_manager.py
+++ b/tests/test_manager.py
@@ -41,6 +41,7 @@ from combo.data.models import (
Page,
PageSnapshot,
ParentContentCell,
+ SiteSettings,
TextCell,
ValidityInfo,
)
@@ -2633,3 +2634,17 @@ def test_redirect_to_page_edit(app, admin_user):
resp = app.get('/manage/pages/users/xxx/', status=302)
assert resp.location == '/manage/pages/%s/' % page3.pk
+
+
+def test_site_settings(app, admin_user):
+ app = login(app)
+
+ resp = app.get('/manage/')
+ resp = resp.click('Site Settings')
+ resp.form['welcome_page_path'] = '/welcome/'
+ resp.form['initial_login_page_path'] = '/initial-login/'
+ resp.form.submit()
+
+ site_settings = SiteSettings.objects.get()
+ assert site_settings.welcome_page_path == '/welcome/'
+ assert site_settings.initial_login_page_path == '/initial-login/'
diff --git a/tests/test_public.py b/tests/test_public.py
index 72e1ff29..8ddd5bf4 100644
--- a/tests/test_public.py
+++ b/tests/test_public.py
@@ -33,6 +33,7 @@ from combo.data.models import (
Page,
ParentContentCell,
Redirect,
+ SiteSettings,
TextCell,
)
@@ -647,16 +648,19 @@ def test_initial_login_page(app, admin_user):
page = Page(title='Initial Login', slug='initial-login', template_name='standard', public=False)
page.save()
- with override_settings(COMBO_INITIAL_LOGIN_PAGE_PATH='/initial-login/'):
- resp = app.get('/', status=200)
+ site_settings = SiteSettings.objects.get()
+ site_settings.initial_login_page_path = '/initial-login/'
+ site_settings.save()
- # first visit
- app = login(app)
- resp = app.get('/', status=302)
- assert urllib.parse.urlparse(resp.location).path == '/initial-login/'
+ resp = app.get('/', status=200)
- # visit again
- resp = app.get('/', status=200)
+ # first visit
+ app = login(app)
+ resp = app.get('/', status=302)
+ assert urllib.parse.urlparse(resp.location).path == '/initial-login/'
+
+ # visit again
+ resp = app.get('/', status=200)
def test_welcome_page(app, admin_user):
@@ -666,20 +670,23 @@ def test_welcome_page(app, admin_user):
page = Page(title='Welcome', slug='welcome', template_name='standard')
page.save()
- with override_settings(COMBO_WELCOME_PAGE_PATH='/welcome/'):
- app.cookiejar.clear()
- resp = app.get('/', status=302)
- assert urllib.parse.urlparse(resp.location).path == '/welcome/'
+ site_settings = SiteSettings.objects.get()
+ site_settings.welcome_page_path = '/welcome/'
+ site_settings.save()
- resp = app.get('/', status=200)
+ app.cookiejar.clear()
+ resp = app.get('/', status=302)
+ assert urllib.parse.urlparse(resp.location).path == '/welcome/'
- app.cookiejar.clear()
- resp = app.get('/', status=302)
- assert urllib.parse.urlparse(resp.location).path == '/welcome/'
+ resp = app.get('/', status=200)
- app.cookiejar.clear()
- app = login(app)
- resp = app.get('/', status=200)
+ app.cookiejar.clear()
+ resp = app.get('/', status=302)
+ assert urllib.parse.urlparse(resp.location).path == '/welcome/'
+
+ app.cookiejar.clear()
+ app = login(app)
+ resp = app.get('/', status=200)
def test_post_cell(app):
diff --git a/tests/test_wcs.py b/tests/test_wcs.py
index 2e5eeeb1..c6cdb6a6 100644
--- a/tests/test_wcs.py
+++ b/tests/test_wcs.py
@@ -2506,7 +2506,7 @@ def test_view_page_with_wcs_cells_num_queries(app, admin_user):
app.get('/') # load once to populate caches
with CaptureQueriesContext(connection) as ctx:
app.get('/')
- assert len(ctx.captured_queries) == 61
+ assert len(ctx.captured_queries) == 62
def test_hourly():