Commit 8a275a9e authored by Kostas Papadimitriou's avatar Kostas Papadimitriou
Browse files

Page notification messages improvements

- New template tag {% display_messages %} which handles messages
  display, both for django.contrib.messages and ASTAKOS_*_MESSAGES.
- Apply messages block class from python code (instead of js).
- Changed format of ASTAKOS_*_MESSAGES to list of tuples, to allow
  multiple messages of the same level to exist in a page.
- Fixed link colors for info/warning messages
parent 7f774a86
Changelog
---------
v0.7.1
^^^^^^
- ASTAKOS_*_MESSAGES settings changed from dict to tuple lists
- Theme changes (new colors, new font)
v0.7.0
^^^^^^
- Rename management commands
......
......@@ -57,8 +57,21 @@ def media(request):
return {'IM_STATIC_URL' : IM_STATIC_URL}
def custom_messages(request):
global GLOBAL_MESSAGES, SIGNUP_MESSAGES, LOGIN_MESSAGES, PROFILE_MESSAGES
# keep backwards compatibility with dict settings
if type(GLOBAL_MESSAGES) == dict:
GLOBAL_MESSAGES = GLOBAL_MESSAGES.items()
if type(SIGNUP_MESSAGES) == dict:
SIGNUP_MESSAGES = SIGNUP_MESSAGES.items()
if type(LOGIN_MESSAGES) == dict:
LOGIN_MESSAGES = LOGIN_MESSAGES.items()
if type(PROFILE_MESSAGES) == dict:
PROFILE_MESSAGES = PROFILE_MESSAGES.items()
EXTRA_MESSAGES_SET = bool(GLOBAL_MESSAGES or SIGNUP_MESSAGES or \
LOGIN_MESSAGES or PROFILE_MESSAGES)
return {
'GLOBAL_MESSAGES' : GLOBAL_MESSAGES,
'SIGNUP_MESSAGES' : SIGNUP_MESSAGES,
......
......@@ -50,7 +50,7 @@ SITENAME = getattr(settings, 'ASTAKOS_SITENAME', 'GRNET Cloud')
# Set recaptcha keys
RECAPTCHA_PUBLIC_KEY = getattr(settings, 'ASTAKOS_RECAPTCHA_PUBLIC_KEY', '')
RECAPTCHA_PRIVATE_KEY = getattr(settings, 'ASTAKOS_RECAPTCHA_PRIVATE_KEY', '')
RECAPTCHA_OPTIONS = getattr(settings, 'ASTAKOS_RECAPTCHA_OPTIONS',
RECAPTCHA_OPTIONS = getattr(settings, 'ASTAKOS_RECAPTCHA_OPTIONS',
{'theme' : 'custom', 'custom_theme_widget': 'okeanos_recaptcha'})
RECAPTCHA_USE_SSL = getattr(settings, 'ASTAKOS_RECAPTCHA_USE_SSL', True)
RECAPTCHA_ENABLED = getattr(settings, 'ASTAKOS_RECAPTCHA_ENABLED', True)
......@@ -69,19 +69,19 @@ RE_USER_EMAIL_PATTERNS = getattr(settings, 'ASTAKOS_RE_USER_EMAIL_PATTERNS', [])
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of login page'}
LOGIN_MESSAGES = getattr(settings, 'ASTAKOS_LOGIN_MESSAGES', {})
LOGIN_MESSAGES = getattr(settings, 'ASTAKOS_LOGIN_MESSAGES', [])
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of signup page'}
SIGNUP_MESSAGES = getattr(settings, 'ASTAKOS_SIGNUP_MESSAGES', {})
SIGNUP_MESSAGES = getattr(settings, 'ASTAKOS_SIGNUP_MESSAGES', [])
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of profile page'}
PROFILE_MESSAGES = getattr(settings, 'ASTAKOS_PROFILE_MESSAGES', {})
PROFILE_MESSAGES = getattr(settings, 'ASTAKOS_PROFILE_MESSAGES', [])
# Messages to display on all pages
# e.g. {'warning': 'This warning message will be displayed on the top of every page'}
GLOBAL_MESSAGES = getattr(settings, 'ASTAKOS_GLOBAL_MESSAGES', {})
GLOBAL_MESSAGES = getattr(settings, 'ASTAKOS_GLOBAL_MESSAGES', [])
# messages to display as extra actions in account forms
# e.g. {'https://cms.okeanos.grnet.gr/': 'Back to ~okeanos'}
......
......@@ -30,6 +30,12 @@ img.right { margin:0 0 1em 1em; float:right;}
.top-msg +.mainlogo { margin-top:-73px;}
.top-msg .close { position:absolute; bottom:20px; right:20px; font-size:1.3em; font-weight:bold; border:0 none; color:#fff; text-decoration:none;}
.top-msg .close:hover { color:#000;}
.top-msg.success { background-color:#77C596; color: #fff}
.top-msg.error { background-color:#EF4F54; color: #fff}
.top-msg.warning { background-color:#F6921E; color: #fff}
.top-msg.info { background-color:#C3C3B9; color: #fff}
.top-msg.warning a { color: #3582AC}
.top-msg.info a { color: #222}
/* container */
.container .wrapper { padding-bottom:100px;}
......@@ -280,4 +286,4 @@ dl.alt-style dt:nth-child(2n) { background:black; }
.widjets li { width:50%; float:left; list-style:none outside; margin:30px 0; }
.widjets li div { border:1px dashed #000; padding:20px 20px 70px; width:60%; margin:0 auto; position:relative; }
.widjets li div img { max-width:100%; }
.widjets li .btn { text-align:center; position:absolute; bottom:0; left:0; right:0; }
\ No newline at end of file
.widjets li .btn { text-align:center; position:absolute; bottom:0; left:0; right:0; }
......@@ -114,34 +114,10 @@ $(document).ready(function() {
$('.top-msg .success').parents('.top-msg').css(
{
backgroundColor: '#77C596',
color: '#fff'
}
);
$('.top-msg .error').parents('.top-msg').css(
{
backgroundColor: '#EF4F54',
color: '#fff'
}
);
$('.top-msg .warning').parents('.top-msg').css(
{
backgroundColor: '#F6921E',
color: '#fff'
}
);
$('.top-msg .info').parents('.top-msg').css(
{
backgroundColor: '#C3C3B9',
color: '#fff'
}
);
$('.top-msg .success').parents('.top-msg').addClass('success');
$('.top-msg .error').parents('.top-msg').addClass('error');
$('.top-msg .warning').parents('.top-msg').addClass('warning');
$('.top-msg .info').parents('.top-msg').addClass('info');
// clouds homepage animation
$('#animation a').hover(
......
{% extends "im/base.html" %}
{% block extra_messages %}
{% if not messages %}
{% for msg_type, msg in GLOBAL_MESSAGES.items %}
<div class="{{ msg_type }}">{{ msg|safe }}</div>
{% endfor %}
{% for msg_type, msg in PROFILE_MESSAGES.items %}
<div class="{{ msg_type }}">{{ msg|safe }}</div>
{% endfor %}
{% endif %}
{% endblock %}
{% load filters %}
{% block page.title %}Profile{% endblock %}
......
<!doctype html>
{% load astakos_tags %}<!doctype html>
<head>
{% block starthead %}{% endblock starthead %}
<meta charset="UTF-8">
......@@ -74,20 +74,12 @@
<body>
<div class="container">
<div class="wrapper">
{% if messages or EXTRA_MESSAGES_SET %}
<div class="top-msg active">
{% block extra_messages %}{% endblock %}
{% for message in messages %}
<div{% if message.tags %}
class="msg {{ message.tags }}"{% endif %}>
{{ message|safe }}</div>
{% endfor %}
<a href="#" title="close" class="close">X</a>
</div>
{% endif %}
<div class="wrapper">
{% display_messages %}
<div class="mainlogo">
<a href="/im/">
<a href="{% url astakos.im.views.index %}">
<img src="{{ IM_STATIC_URL }}images/accounts-logo.png" alt="accounts" />
</a>
</div>
......
{% extends 'im/base_two_cols.html'%}
{% block extra_messages %}
{% if not messages %}
{% for msg_type, msg in GLOBAL_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% for msg_type, msg in LOGIN_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% endif %}
{% endblock %}
{% block signup_class %}hidden{% endblock %}
{% block page.title %}{% endblock %}
......
{% extends 'im/base_two_cols.html' %}
{% block extra_messages %}
{% if not messages %}
{% for msg_type, msg in GLOBAL_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% for msg_type, msg in SIGNUP_MESSAGES.items %}
<li class="{{ msg_type }}">{{ msg|safe }}</li>
{% endfor %}
{% endif %}
{% endblock %}
{% block page.title %}
Signup
{% endblock %}
......
from django import template
from django.core.urlresolvers import reverse, resolve
from django.conf import settings
register = template.Library()
MESSAGES_VIEWS_MAP = getattr(settings, 'ASTAKOS_MESSAGES_VIEWS_MAP', {
'astakos.im.views.index': 'LOGIN_MESSAGES',
'astakos.im.views.logout': 'LOGIN_MESSAGES',
'astakos.im.views.login': 'LOGIN_MESSAGES',
'astakos.im.views.signup': 'SIGNUP_MESSAGES',
'astakos.im.views.edit_profile': 'PROFILE_MESSAGES',
'astakos.im.views.change_password': 'PROFILE_MESSAGES',
'astakos.im.views.invite': 'PROFILE_MESSAGES',
'astakos.im.views.feedback': 'PROFILE_MESSAGES',
})
@register.tag(name='display_messages')
def display_messages(parser, token):
return MessagesNode()
class DummyMessage(object):
def __init__(self, type, msg):
self.message = msg
self.tags = type
def __repr__(self):
return "%s: %s" % (self.tags, self.message)
class MessagesNode(template.Node):
def get_view_messages(self, context):
messages = list(context['GLOBAL_MESSAGES'])
try:
view = resolve(context['request'].get_full_path())[0]
view_name = "%s.%s" % (view.__module__, view.func_name)
messages += context[MESSAGES_VIEWS_MAP.get(view_name)]
return messages
except Exception, e:
return messages
def render(self, context):
if self not in context.render_context:
messages = list(context['messages'])
if context['EXTRA_MESSAGES_SET']:
view_messages = self.get_view_messages(context)
for msg_object in view_messages:
messages.append(DummyMessage(msg_object[0], msg_object[1]))
if not messages:
return ""
cls = messages[-1].tags
content = '<div class="top-msg active %s">' % cls
for msg in messages:
content += '<div class="msg %s">%s</div>' % (msg.tags, msg.message)
content += '<a href="#" title="close" class="close">X</a>'
content += '</div>'
context.render_context[self] = content
return context.render_context[self]
......@@ -68,24 +68,24 @@
#ASTAKOS_RE_USER_EMAIL_PATTERNS = []
# Messages to display on login page header
# e.g. {'warning': 'This warning message will be displayed on the top of login page'}
#ASTAKOS_LOGIN_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of login page')]
#ASTAKOS_LOGIN_MESSAGES = []
# Messages to display on signup page header
# e.g. {'warning': 'This warning message will be displayed on the top of signup page'}
#ASTAKOS_SIGNUP_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of signup page')]
#ASTAKOS_SIGNUP_MESSAGES = []
# Messages to display on profile page header
# e.g. {'warning': 'This warning message will be displayed on the top of profile pages'}
#ASTAKOS_PROFILE_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of profile pages')]
#ASTAKOS_PROFILE_MESSAGES = []
# Messages to display on global page header
# e.g. {'warning': 'This warning message will be displayed on the top of all pages'}
#ASTAKOS_GLOBAL_MESSAGES = {}
# e.g. [('warning', 'This warning message will be displayed on the top of all pages')]
#ASTAKOS_GLOBAL_MESSAGES = []
# messages to display as extra actions in account forms
# e.g. {'https://cms.okeanos.grnet.gr/': 'Back to ~okeanos'}
#ASTAKOS_PROFILE_EXTRA_LINKS = {}
#ASTAKOS_PROFILE_EXTRA_LINKS = []
# The number of unsuccessful login requests per minute allowed for a specific email
#ASTAKOS_RATELIMIT_RETRIES_ALLOWED = 3
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment