more order in app settings,
authorRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Mon, 27 Aug 2012 13:10:44 +0000 (15:10 +0200)
committerRadek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
Mon, 27 Aug 2012 13:10:57 +0000 (15:10 +0200)
more graphics

22 files changed:
events/__init__.py
events/templatetags/events_tags.py
migdal/__init__.py
migdal/models.py
migdal/settings.py [deleted file]
migdal/templates/migdal/entry/entry_begin.html
migdal/templates/migdal/entry/entry_detail.html
migdal/templates/migdal/entry/entry_list.html
migdal/templates/migdal/entry/info/entry_begin.html
migdal/templates/migdal/last_comments.html
migdal/templatetags/migdal_tags.py
migdal/urls.py
migdal/views.py
prawokultury/helpers.py
prawokultury/settings.d/50-contrib.conf
prawokultury/static/css/base.css
prawokultury/static/css/base.scss
prawokultury/static/css/entry.css
prawokultury/static/css/entry.scss
prawokultury/static/css/sidebar.css
prawokultury/static/css/sidebar.scss
prawokultury/static/js/promobox.js

index e69de29..9de4ba2 100644 (file)
@@ -0,0 +1,8 @@
+from prawokultury.helpers import AppSettings
+
+
+class Settings(AppSettings):
+    BOX_LENGTH = 3
+
+
+app_settings = Settings('EVENTS')
index 00ea5c7..a51bda9 100644 (file)
@@ -3,6 +3,7 @@
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
 from django import template
+from events import app_settings
 from events.models import Event
 
 register = template.Library()
@@ -10,6 +11,6 @@ from datetime import datetime
 
 
 @register.inclusion_tag('events/snippets/events_box.html', takes_context=True)
-def events_box(context, limit=5):
+def events_box(context, limit=app_settings.BOX_LENGTH):
     objects = Event.objects.filter(date__gte=datetime.now())[:limit]
     return {'objects': objects}
index ae94f9e..97496e5 100644 (file)
@@ -3,4 +3,47 @@
 Migdal (מִגְדָּל) is a multilingual blog Django app.
 
 Author: Radek Czajka <radoslaw.czajka@nowoczesnapolska.org.pl>
-"""
\ No newline at end of file
+"""
+from django.conf import settings
+from prawokultury.helpers import AppSettings
+from django.utils.translation import ugettext_lazy as _
+from migdal.helpers import EntryType
+
+
+class Settings(AppSettings):
+    # Types of entries:
+    # (slug, commentable, on main)
+    TYPES = (
+            EntryType('news', _('news'), commentable=True, on_main=True),
+            EntryType('publications', _('publications'), commentable=False, on_main=False),
+            EntryType('info', _('info'), commentable=False, on_main=False),
+        )
+    TYPE_SUBMIT = 'news'
+    TAXONOMIES = (
+        ('topics', _('topics')),
+        ('types', _('types')),
+    )
+    LAST_COMMENTS = 10
+
+    TYPES_DICT = None
+    def _more_TYPES_DICT(self, value):
+        return dict((t.db, t) for t in self.TYPES)
+
+    TYPES_ON_MAIN = None
+    def _more_TYPES_ON_MAIN(self, value):
+        return tuple(t.db for t in self.TYPES if t.on_main)
+
+    OBLIGATORY_LANGUAGES = None
+    def _more_OBLIGATORY_LANGUAGES(self, value):
+        return value or tuple(lang for lang in settings.LANGUAGES
+                        if lang[0] == settings.LANGUAGE_CODE)
+
+    OPTIONAL_LANGUAGES = None
+    def _more_OPTIONAL_LANGUAGES(self, value):
+        return tuple(lang for lang in settings.LANGUAGES
+                        if lang not in self.OBLIGATORY_LANGUAGES)
+
+app_settings = Settings('MIGDAL')
+
+
+
index 83a1865..3e0a8a3 100644 (file)
@@ -6,12 +6,12 @@ from django.db import models
 from django.utils.translation import get_language, ugettext_lazy as _, ugettext
 from markupfield.fields import MarkupField
 from migdal.helpers import add_translatable
-from migdal import settings
+from migdal import app_settings
 
 
 class Category(models.Model):
     taxonomy = models.CharField(_('taxonomy'), max_length=32,
-                    choices=settings.TAXONOMIES)
+                    choices=app_settings.TAXONOMIES)
 
     class Meta:
         verbose_name = _('category')
@@ -33,7 +33,7 @@ add_translatable(Category, {
 
 class Entry(models.Model):
     type = models.CharField(max_length=16,
-            choices=((t.db, t.slug) for t in settings.TYPES),
+            choices=((t.db, t.slug) for t in app_settings.TYPES),
             db_index=True)
     date = models.DateTimeField(auto_now_add=True, db_index=True)
     author = models.CharField(_('author'), max_length=128)
@@ -53,7 +53,7 @@ class Entry(models.Model):
 
     def save(self, *args, **kwargs):
         # convert blank to null for slug uniqueness check to work
-        for lc, ln in settings.OPTIONAL_LANGUAGES:
+        for lc, ln in app_settings.OPTIONAL_LANGUAGES:
             slug_name = "slug_%s" % lc
             if hasattr(self, slug_name) == u'':
                 setattr(self, slug_name, None)
@@ -64,9 +64,9 @@ class Entry(models.Model):
         return ('migdal_entry_%s' % self.type, [self.slug])
 
     def get_type(self):
-        return dict(settings.TYPES_DICT)[self.type]
+        return dict(app_settings.TYPES_DICT)[self.type]
 
-add_translatable(Entry, languages=settings.OPTIONAL_LANGUAGES, fields={
+add_translatable(Entry, languages=app_settings.OPTIONAL_LANGUAGES, fields={
     'needed': models.CharField(_('needed'), max_length=1, db_index=True, choices=(
                 ('n', _('Unneeded')), ('w', _('Needed')), ('y', _('Done'))),
                 default='n'),
diff --git a/migdal/settings.py b/migdal/settings.py
deleted file mode 100644 (file)
index a2e5b52..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-# -*- coding: utf-8 -*-
-# This file is part of PrawoKultury, licensed under GNU Affero GPLv3 or later.
-# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
-#
-from django.conf import settings
-from django.utils.translation import ugettext_lazy as _
-from migdal.helpers import EntryType
-
-
-def app_setting(global_name, default):
-    try:
-        return getattr(settings, global_name)
-    except AttributeError:
-        return default
-
-# Types of entries:
-# (slug, commentable, on main)
-TYPES = app_setting('MIGDAL_TYPES', (
-            EntryType('news', _('news'), commentable=True, on_main=True),
-            EntryType('publications', _('publications'), commentable=False, on_main=False),
-            EntryType('info', _('info'), commentable=False, on_main=False),
-        ))
-TYPES_DICT = dict((t.db, t) for t in TYPES)
-TYPES_ON_MAIN = tuple(t.db for t in TYPES if t.on_main)
-TYPE_SUBMIT = 'news'
-
-
-LANGUAGES = app_setting('MIGDAL_LANGUAGES', settings.LANGUAGES)
-LANGUAGE_CODE = app_setting('MIGDAL_LANGUAGE_CODE', settings.LANGUAGE_CODE)
-OBLIGATORY_LANGUAGES = app_setting('MIGDAL_OBLIGATORY', tuple(
-    lang for lang in LANGUAGES if lang[0]==LANGUAGE_CODE))
-OPTIONAL_LANGUAGES = tuple(lang for lang in LANGUAGES if lang not in OBLIGATORY_LANGUAGES)
-
-
-TAXONOMIES = (
-    ('topics', _('topics')),
-    ('types', _('types')),
-)
index 1c47e89..b694564 100755 (executable)
@@ -1,8 +1,12 @@
 {% load i18n %}
 {% load gravatar thumbnail %}
 
-<img class="avatar" src="{% gravatar_for_email object.author_email 48 %}"/>
-<h2><a href="{{ object.get_absolute_url }}">{{ object.title }}</a></h2>
+<img class="avatar" src="{% gravatar_for_email object.author_email 64 %}"/>
+{% if detail %}
+    <h1>{{ object.title }}</h1>
+{% else %}
+    <h2><a href="{{ object.get_absolute_url }}">{{ object.title }}</a></h2>
+{% endif %}
 
 <div class="entry-data">
 <div class="date">{{ object.date }}</div>
@@ -22,6 +26,7 @@
 
 <div class="categories">
 {% for category in object.categories.all %}
+    {% if forloop.counter != 1 %}/{% endif %}
     <a href="{{ category.get_absolute_url }}">{{ category }}</a>
 {% endfor %}
 </div>
index 573e139..637ed89 100755 (executable)
 
 {% block "body" %}
 
-<div class="entry entry-short entry-{{ entry.type }}">
+<div class="entry entry-detail entry-{{ entry.type }}">
 <div class="entry-wrapped">
 
-{% entry_begin entry %}
+{% entry_begin entry %}
 <div class="body">
 {{ entry.body }}
 </div>
index e7dd057..3b9e763 100755 (executable)
 {% block "body" %}
 
 {% if category %}
-    {% trans "Category" %}: {{ category }}
-    <h1><a href="{% url 'migdal_category_feed' category.slug %}">RSS</a></h1>
+    <h1>{% trans "Category" %}: {{ category }}
+    <!--a href="{% url 'migdal_category_feed' category.slug %}">RSS</a-->
+    </h1>
 {% elif entry_type %}
-    {{ entry_type|capfirst }}
-    <h1><a href="{% url 'migdal_entry_list_'|add:entry_type.db|add:'_feed' %}">RSS</a></h1>
+    <h1>{{ entry_type|capfirst }}
+    <!--a href="{% url 'migdal_entry_list_'|add:entry_type.db|add:'_feed' %}">RSS</a-->
+    </h1>
 {% endif %}
 
 {% if object_list.promobox and request.page == 1 %}
index 70d34bd..dd8de2b 100755 (executable)
@@ -1,5 +1,11 @@
 {% load i18n %}
-<h2><a href="{{ object.get_absolute_url }}">{{ object.title }}</a></h2>
+
+{% if detail %}
+    <h1>{{ object.title }}</h1>
+{% else %}
+    <h2><a href="{{ object.get_absolute_url }}">{{ object.title }}</a></h2>
+{% endif %}
+
 
 <div class="entry-data">
 {% if request.LANGUAGE_CODE == 'pl' %}
@@ -20,4 +26,6 @@
 {% if object.image %}
     <img class="entry-picture" src="{{ object.image.url }}" />
 {% endif %}
+<div class="lead">
 {{ object.lead }}
+</div>
index 33851fb..2b5945a 100755 (executable)
@@ -4,10 +4,9 @@
   {% for comment in object_list %}
     <li>
     <a href="{{ comment.get_absolute_url }}">
-        <div>
-        <img src="{% gravatar_for_email comment.email 16 %}"/>
-        {{ comment.name }}, {{ comment.submit_date }}</div>
-        {{ comment.comment|textile_restricted_pl|striptags|truncatechars:32 }}
+        <div class="title">{{ comment.content_object.title }}</div>
+        <div class="author">{{ comment.name }}</div>
+        <div class="body">{{ comment.comment|textile_restricted_pl|striptags|truncatechars:32 }}</div>
     </a>
     </li>
   {% endfor %}
index 8b20f83..2ec8081 100644 (file)
@@ -6,15 +6,15 @@ from django_comments_xtd.models import XtdComment
 from django.contrib import comments
 from django.core.urlresolvers import reverse
 from django import template
+from migdal import app_settings
 from migdal.models import Category, Entry
-from migdal import settings
 from django.utils.translation import ugettext_lazy as _
 
 register = template.Library()
 
 
 @register.simple_tag(takes_context=True)
-def entry_begin(context, entry):
+def entry_begin(context, entry, detail=False):
     t = template.loader.select_template((
         'migdal/entry/%s/entry_begin.html' % entry.type,
         'migdal/entry/entry_begin.html',
@@ -22,6 +22,7 @@ def entry_begin(context, entry):
     context = {
         'request': context['request'],
         'object': entry,
+        'detail': detail,
     }
     return t.render(template.Context(context))
 
@@ -63,7 +64,7 @@ def categories(context, taxonomy):
 
 
 @register.inclusion_tag('migdal/last_comments.html')
-def last_comments(limit=10):
+def last_comments(limit=app_settings.LAST_COMMENTS):
     return {'object_list': 
         XtdComment.objects.filter(is_public=True, is_removed=False).order_by('-submit_date')[:limit]}
 
index dec95bd..9215078 100644 (file)
@@ -5,11 +5,11 @@
 from django.conf.urls import patterns, include, url
 from django.utils.translation import ugettext_lazy as _
 from django.utils.translation import string_concat
-from migdal import feeds, settings
+from migdal import feeds, app_settings
 from migdal.helpers import i18n_patterns
 
 pats = []
-for t in settings.TYPES:
+for t in app_settings.TYPES:
     pats += [
         # entry list
         url(string_concat(r'^', t.slug, r'/$'),
index 07eeb50..befa950 100644 (file)
@@ -6,7 +6,7 @@ from django.shortcuts import get_object_or_404, render, redirect
 from migdal import api
 from migdal.forms import get_submit_form
 from migdal.models import Category, Entry
-from migdal.settings import TYPES_DICT, TYPES_ON_MAIN, TYPE_SUBMIT
+from migdal import app_settings
 
 
 def entry_list(request, type_db=None, category_slug=None):
@@ -14,13 +14,13 @@ def entry_list(request, type_db=None, category_slug=None):
     templates = ["migdal/entry/entry_list.html"]
 
     if type_db:
-        if TYPES_ON_MAIN == (type_db,):
+        if app_settings.TYPES_ON_MAIN == (type_db,):
             return redirect('migdal_main')
-        entry_type = TYPES_DICT[type_db]
+        entry_type = app_settings.TYPES_DICT[type_db]
         templates = ["migdal/entry/%s/entry_list.html" % type_db] + templates
-        submit = type_db == TYPE_SUBMIT
+        submit = type_db == app_settings.TYPE_SUBMIT
     else:
-        submit = TYPES_ON_MAIN == (TYPE_SUBMIT,)
+        submit = app_settings.TYPES_ON_MAIN == (app_settings.TYPE_SUBMIT,)
         entry_type = None
 
     if category_slug:
index aa8e3dd..5877e0b 100644 (file)
@@ -2,6 +2,7 @@
 # This file is part of PrawoKultury, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
+from django.conf import settings
 from textile import Textile
 
 
@@ -22,7 +23,6 @@ def textile_restricted_pl(text):
                         text, rel='nofollow')
 
 
-
 class LazyUGettextLazy():
     """You can use it to internationalize strings in settings.
 
@@ -40,3 +40,27 @@ class LazyUGettextLazy():
             LazyUGettextLazy._ = staticmethod(ugettext_lazy)
             LazyUGettextLazy.real = True
         return unicode(self._(self.text))
+
+
+class AppSettings(object):
+    """Allows specyfying custom settings for an app, with default values.
+
+    Just subclass, set some properties and instantiate with a prefix.
+    Getting a SETTING from an instance will check for prefix_SETTING
+    in project settings if set, else take the default. The value will be
+    then filtered through _more_SETTING method, if there is one.
+
+    """
+    def __init__(self, prefix):
+        self._prefix = prefix
+
+    def __getattribute__(self, name):
+        if name.startswith('_'):
+            return object.__getattribute__(self, name)
+        value = getattr(settings,
+                         "%s_%s" % (self._prefix, name),
+                         object.__getattribute__(self, name))
+        more = "_more_%s" % name
+        if hasattr(self, more):
+            value = getattr(self, more)(value)
+        return value
index ba1ebd1..12d387e 100755 (executable)
@@ -10,3 +10,5 @@ COMMENTS_XTD_LIST_URL_ACTIVE = True
 #COMMENTS_XTD_LIST_PAGINATE_BY = 10
 
 THUMBNAIL_QUALITY = 95
+
+GRAVATAR_DEFAULT_IMAGE = 'http://localhost:8000/static/img/avatar.png'
index f2d3236..db64390 100644 (file)
@@ -2,9 +2,10 @@
 body {
   font-family: 'Lato', sans-serif;
   font-size: .625em;
-  background: #edece7;
+  background-color: #edece7;
   background-image: url("/static/img/bg.png");
   background-repeat: no-repeat;
+  color: #363a3b;
   margin-top: 0;
   background-position: 50% 0; }
 
@@ -13,3 +14,8 @@ a {
 
 a:hover {
   text-decoration: underline; }
+
+h1 {
+  margin: 0;
+  color: #01519a;
+  font-size: 2em; }
index cbe589b..54a73fa 100755 (executable)
@@ -3,9 +3,10 @@
 body {
     font-family: 'Lato', sans-serif;
     font-size: .625em;
-    background: #edece7;
+    background-color: #edece7;
     background-image: url('/static/img/bg.png');
     background-repeat: no-repeat;
+    color: #363a3b;
     margin-top: 0;
     background-position: 50% 0;
 }
@@ -16,3 +17,10 @@ a {
 a:hover {
     text-decoration: underline;
 }
+
+
+h1 {
+    margin: 0;
+    color: #01519a;
+    font-size: 2em;
+}
index cf23152..bb7d7a0 100644 (file)
@@ -1,18 +1,21 @@
 .avatar {
   float: left;
-  margin-left: -7.5em;
-  margin-top: .8em; }
+  margin-left: -8em;
+  margin-top: 0em; }
 
 .entry-short {
   border-top: 1px solid #8b8b87; }
+  .entry-short .entry-wrapped {
+    padding-top: .7em; }
 
 .entry-wrapped {
-  margin-left: 8em;
-  padding-top: .7em; }
-  .entry-wrapped h2 {
+  margin-left: 8em; }
+  .entry-wrapped h1, .entry-wrapped h2 {
     margin: 0;
-    font-size: 1.2em;
-    color: #01519a; }
+    color: #01519a;
+    font-size: 1.2em; }
+    .entry-wrapped h1 a, .entry-wrapped h2 a {
+      color: #01519a; }
   .entry-wrapped .entry-data {
     font-size: 1.1em;
     margin-top: 1.4em;
       content: url("/static/img/read-more.png");
       margin-left: .7em; }
 
+.entry-info .entry-wrapped {
+  margin-left: 0; }
+  .entry-info .entry-wrapped h1 {
+    font-size: 2em; }
+
 .entry-picture {
   float: left;
   margin-right: 1.5em; }
index 4c54530..dcfbe93 100755 (executable)
@@ -1,21 +1,28 @@
 .avatar {
     float: left;
-    margin-left: -7.5em;
-    margin-top: .8em;
+    margin-left: -8em;
+    margin-top: 0em;
 }
 
 .entry-short {
     border-top: 1px solid #8b8b87;
+
+    .entry-wrapped {
+        padding-top: .7em;
+    }
 }
 
 .entry-wrapped {
     margin-left: 8em;
-    padding-top: .7em;
 
-    h2 {
+    h1, h2 {
         margin: 0;
-        font-size: 1.2em;
         color: #01519a;
+        font-size: 1.2em;
+
+        a {
+            color: #01519a;
+        }
     }
 
     .entry-data {
     }
 }
 
+.entry-info .entry-wrapped {
+    margin-left: 0;
+    h1 {
+        font-size: 2em;
+    }
+}
 
 .entry-picture {
     float: left;
index 9c245f5..71c43ea 100644 (file)
@@ -4,10 +4,10 @@
   padding-bottom: .9em;
   clear: both; }
   .sidebar-box h3 {
-    font-size: 1.3em;
+    font-size: 1.4em;
     font-weight: normal;
     margin-top: 0;
-    margin-bottom: 1.2em; }
+    margin-bottom: 1.1em; }
   .sidebar-box .more {
     text-align: right; }
   .sidebar-box .event-list {
   color: #31ada3; }
 #sidebar-box-categories .category-taxonomy-types a {
   color: #ff6100; }
+
+#latest-comments {
+  list-style: none;
+  padding: 0;
+  margin: 0; }
+  #latest-comments a {
+    display: block;
+    color: #363a3b; }
+  #latest-comments li {
+    margin-bottom: 1.5em; }
+  #latest-comments li:after {
+    content: url("/static/img/dot.png");
+    display: block;
+    margin: 1.5em 1.5em 0 0;
+    text-align: center; }
+  #latest-comments li:last-child {
+    margin-bottom: 0; }
+  #latest-comments li:last-child:after {
+    display: none; }
+  #latest-comments .title {
+    font-size: 1.1em;
+    font-weight: bold; }
+  #latest-comments .author {
+    color: #acacac;
+    font-size: 1.1em; }
+  #latest-comments .body {
+    margin-top: 1.3em;
+    font-size: 1.1em; }
index bac9f31..187db6b 100755 (executable)
@@ -5,10 +5,10 @@
     clear: both;
 
     h3 {
-        font-size: 1.3em;
+        font-size: 1.4em;
         font-weight: normal;
         margin-top: 0;
-        margin-bottom: 1.2em;
+        margin-bottom: 1.1em;
     }
 
     .more {
         color: #ff6100;
     }
 }
+
+
+#latest-comments {
+    list-style: none;
+    padding: 0;
+    margin: 0;
+
+    a {
+        display: block;
+        color: #363a3b;
+    }
+
+    li {
+        margin-bottom: 1.5em;
+    }
+    li:after {
+        content: url("/static/img/dot.png");
+        display: block;
+        margin: 1.5em 1.5em 0 0;
+        text-align:center;
+    }
+
+    li:last-child {
+        margin-bottom: 0;
+    }
+    li:last-child:after {
+        display: none;
+    }
+
+    .title {
+        font-size: 1.1em;
+        font-weight: bold;
+    }
+    .author {
+        color: #acacac;
+        font-size: 1.1em;
+    }
+    .body {
+        margin-top: 1.3em;
+        font-size: 1.1em;
+    }
+}
\ No newline at end of file
index 91128ca..760c10b 100644 (file)
@@ -17,24 +17,29 @@ var change_slide = function(slide_no) {
 };
 
 
-$switchers.each(function(i, e) {
-    $(e).click(function(e) {
-        e.preventDefault();
-        change_slide(i);
-    });
-});
-
-
 var timeout = null;
 var cycle_slide = function() {
     var current = $slides.filter('.active').index();
     change_slide((current + 1) % $slides.length);
 }
+
+
 var reset_timeout = function() {
     clearTimeout(timeout);
     timeout = setTimeout(cycle_slide, 5000);
 };
-timeout = setTimeout(cycle_slide, 3000);
+
+
+if ($slides.length > 1) {
+    $switchers.each(function(i, e) {
+        $(e).click(function(e) {
+            e.preventDefault();
+            change_slide(i);
+        });
+    });
+
+    timeout = setTimeout(cycle_slide, 3000);
+}
 
 
 });
\ No newline at end of file