From: Marek Stępniowski
Date: Fri, 9 Oct 2009 15:09:14 +0000 (+0200)
Subject: Dodanie aplikacji sponsors do zarządzania logami sponsorów w stopce.
X-Git-Url: https://git.mdrn.pl/wolnelektury.git/commitdiff_plain/0d0fa7a4cd45b477e40740a8d971ec814bc6a4a9?ds=sidebyside;hp=-c
Dodanie aplikacji sponsors do zarządzania logami sponsorów w stopce.
---
0d0fa7a4cd45b477e40740a8d971ec814bc6a4a9
diff --git a/apps/sponsors/__init__.py b/apps/sponsors/__init__.py
new file mode 100644
index 000000000..f39d8b488
--- /dev/null
+++ b/apps/sponsors/__init__.py
@@ -0,0 +1,3 @@
+# -*- encoding: utf-8 -*-
+__author__ = u'Marek StÄpniowski, '
+__version__ = '0.1'
diff --git a/apps/sponsors/admin.py b/apps/sponsors/admin.py
new file mode 100644
index 000000000..c66a08653
--- /dev/null
+++ b/apps/sponsors/admin.py
@@ -0,0 +1,21 @@
+from django.db import models
+from django.contrib import admin
+
+from sponsors.models import Sponsor, SponsorGroup
+from sponsors.widgets import OrderedSelectMultiple
+
+class SponsorGroupAdmin(admin.ModelAdmin):
+ formfield_overrides = {
+ models.CommaSeparatedIntegerField: {'widget': OrderedSelectMultiple},
+ }
+ list_display = ('name',)
+ search_fields = ('name',)
+ ordering = ('name',)
+
+class SponsorAdmin(admin.ModelAdmin):
+ list_display = ('name',)
+ search_fields = ('name',)
+ ordering = ('name',)
+
+admin.site.register(SponsorGroup, SponsorGroupAdmin)
+admin.site.register(Sponsor, SponsorAdmin)
diff --git a/apps/sponsors/models.py b/apps/sponsors/models.py
new file mode 100644
index 000000000..ffad8e774
--- /dev/null
+++ b/apps/sponsors/models.py
@@ -0,0 +1,35 @@
+from django.db import models
+from django.utils.translation import ugettext_lazy as _
+
+
+class Sponsor(models.Model):
+ name = models.CharField(_('name'), max_length=120)
+ _description = models.CharField(_('description'), blank=True, max_length=255)
+ logo = models.ImageField(_('logo'), upload_to='sponsors/sponsor/logo')
+ url = models.URLField(_('url'), blank=True, verify_exists=False)
+
+ def __unicode__(self):
+ return self.name
+
+ def description(self):
+ if len(self._description):
+ return self._description
+ else:
+ return self.name
+
+
+class SponsorGroup(models.Model):
+ name = models.CharField(_('name'), max_length=120)
+ order = models.IntegerField(_('order'), default=0)
+ column_width = models.PositiveIntegerField(_('column width'))
+ sponsor_ids = models.CommaSeparatedIntegerField(_('sponsors'), max_length=255)
+
+ def sponsors(self):
+ ids = [int(pk) for pk in self.sponsor_ids.split(',')]
+ result = Sponsor.objects.in_bulk(ids)
+ return [result[pk] for pk in ids]
+ sponsors.changes_data = False
+
+ def __unicode__(self):
+ return self.name
+
diff --git a/apps/sponsors/static/css/sponsors.css b/apps/sponsors/static/css/sponsors.css
new file mode 100644
index 000000000..f3d7ed977
--- /dev/null
+++ b/apps/sponsors/static/css/sponsors.css
@@ -0,0 +1,4 @@
+.sponsor-group {
+ float: left;
+ overflow: hidden;
+}
diff --git a/apps/sponsors/static/js/ordered_select_multiple.js b/apps/sponsors/static/js/ordered_select_multiple.js
new file mode 100644
index 000000000..e4fd74daa
--- /dev/null
+++ b/apps/sponsors/static/js/ordered_select_multiple.js
@@ -0,0 +1,63 @@
+(function($) {
+ $.fn.orderedSelectMultiple = function(options) {
+ var settings = {
+ choices: []
+ };
+ $.extend(settings, options);
+
+ var input = $(this).hide();
+ var values = input.val().split(',');
+
+ var container = $('').insertAfter($(this));
+ var choicesList = $('
').appendTo(container).css({
+ width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+ });
+ var valuesList = $('
').appendTo(container).css({
+ width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+ });
+ var choiceIds = [];
+ $.each(settings.choices, function() {
+ choiceIds.push('' + this.id);
+ });
+
+ function createItem(hash) {
+ return $('' + hash.name + '').css({
+ backgroundColor: '#cff',
+ display: 'block',
+ border: '1px solid #cdd',
+ padding: 2,
+ margin: 0
+ }).data('obj-id', hash.id);
+ }
+
+ $.each(settings.choices, function() {
+ if ($.inArray('' + this.id, values) == -1) {
+ choicesList.append(createItem(this));
+ }
+ });
+
+ $.each(values, function() {
+ var index = $.inArray('' + this, choiceIds); // Why this[0]?
+ if (index != -1) {
+ valuesList.append(createItem(settings.choices[index]));
+ }
+ });
+
+ choicesList.sortable({
+ connectWith: '.connectedSortable'
+ }).disableSelection();
+
+ valuesList.sortable({
+ connectWith: '.connectedSortable',
+ update: function() {
+ values = [];
+ $('li', valuesList).each(function(index) {
+ values.push($(this).data('obj-id'));
+ console.log($(this).data('obj-id'));
+ });
+ console.log('update', values.join(','), input);
+ input.val(values.join(','));
+ }
+ }).disableSelection();
+ };
+})(jQuery);
diff --git a/apps/sponsors/templates/sponsors/sponsors.html b/apps/sponsors/templates/sponsors/sponsors.html
new file mode 100644
index 000000000..d5decae71
--- /dev/null
+++ b/apps/sponsors/templates/sponsors/sponsors.html
@@ -0,0 +1,11 @@
+
diff --git a/apps/sponsors/templatetags/__init__.py b/apps/sponsors/templatetags/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/sponsors/templatetags/sponsor_tags.py b/apps/sponsors/templatetags/sponsor_tags.py
new file mode 100644
index 000000000..87289e8d5
--- /dev/null
+++ b/apps/sponsors/templatetags/sponsor_tags.py
@@ -0,0 +1,12 @@
+from django import template
+
+from sponsors import models
+
+
+register = template.Library()
+
+
+def sponsors():
+ return {'sponsor_groups': models.SponsorGroup.objects.all()}
+
+compressed_js = register.inclusion_tag('sponsors/sponsors.html')(sponsors)
diff --git a/apps/sponsors/widgets.py b/apps/sponsors/widgets.py
new file mode 100644
index 000000000..2ed579370
--- /dev/null
+++ b/apps/sponsors/widgets.py
@@ -0,0 +1,30 @@
+from django import forms
+from django.conf import settings
+from django.utils.safestring import mark_safe
+from django.utils.translation import ugettext_lazy as _
+
+from sponsors import models
+
+
+class OrderedSelectMultiple(forms.TextInput):
+ """
+ A SelectMultiple with a JavaScript interface.
+ """
+ class Media:
+ js = (
+ 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js',
+ 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js',
+ settings.MEDIA_URL + 'js/ordered_select_multiple.js',
+ )
+
+ def render(self, name, value, attrs=None, choices=()):
+ output = [super(OrderedSelectMultiple, self).render(name, value, attrs)]
+ choices = [(unicode(obj), obj.pk) for obj in models.Sponsor.objects.all()]
+ choices_js = ', '.join('{name: "%s", id: %d}' % choice for choice in choices)
+ output.append(u'\n' %
+ (name, choices_js))
+ return mark_safe(u''.join(output))
+
diff --git a/wolnelektury/media/css/sponsors.css b/wolnelektury/media/css/sponsors.css
new file mode 100644
index 000000000..f5497c135
--- /dev/null
+++ b/wolnelektury/media/css/sponsors.css
@@ -0,0 +1,8 @@
+.sponsor-group {
+ float: left;
+ overflow: hidden;
+}
+
+.sponsor-logo {
+ float: left;
+}
\ No newline at end of file
diff --git a/wolnelektury/media/js/ordered_select_multiple.js b/wolnelektury/media/js/ordered_select_multiple.js
new file mode 100644
index 000000000..e4fd74daa
--- /dev/null
+++ b/wolnelektury/media/js/ordered_select_multiple.js
@@ -0,0 +1,63 @@
+(function($) {
+ $.fn.orderedSelectMultiple = function(options) {
+ var settings = {
+ choices: []
+ };
+ $.extend(settings, options);
+
+ var input = $(this).hide();
+ var values = input.val().split(',');
+
+ var container = $('').insertAfter($(this));
+ var choicesList = $('
').appendTo(container).css({
+ width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+ });
+ var valuesList = $('
').appendTo(container).css({
+ width: 200, float: 'left', minHeight: 200, backgroundColor: '#eee', margin: 0, padding: 0
+ });
+ var choiceIds = [];
+ $.each(settings.choices, function() {
+ choiceIds.push('' + this.id);
+ });
+
+ function createItem(hash) {
+ return $('' + hash.name + '').css({
+ backgroundColor: '#cff',
+ display: 'block',
+ border: '1px solid #cdd',
+ padding: 2,
+ margin: 0
+ }).data('obj-id', hash.id);
+ }
+
+ $.each(settings.choices, function() {
+ if ($.inArray('' + this.id, values) == -1) {
+ choicesList.append(createItem(this));
+ }
+ });
+
+ $.each(values, function() {
+ var index = $.inArray('' + this, choiceIds); // Why this[0]?
+ if (index != -1) {
+ valuesList.append(createItem(settings.choices[index]));
+ }
+ });
+
+ choicesList.sortable({
+ connectWith: '.connectedSortable'
+ }).disableSelection();
+
+ valuesList.sortable({
+ connectWith: '.connectedSortable',
+ update: function() {
+ values = [];
+ $('li', valuesList).each(function(index) {
+ values.push($(this).data('obj-id'));
+ console.log($(this).data('obj-id'));
+ });
+ console.log('update', values.join(','), input);
+ input.val(values.join(','));
+ }
+ }).disableSelection();
+ };
+})(jQuery);
diff --git a/wolnelektury/settings.py b/wolnelektury/settings.py
index bdbc9923b..9e9f6a545 100644
--- a/wolnelektury/settings.py
+++ b/wolnelektury/settings.py
@@ -96,6 +96,7 @@ INSTALLED_APPS = [
# external
'south',
+ 'sponsors',
'newtagging',
'pagination',
'chunks',
@@ -108,7 +109,7 @@ CACHE_BACKEND = 'locmem:///?max_entries=3000'
# CSS and JavaScript file groups
COMPRESS_CSS = {
'all': {
- 'source_filenames': ('css/master.css', 'css/jquery.autocomplete.css', 'css/master.plain.css',),
+ 'source_filenames': ('css/master.css', 'css/jquery.autocomplete.css', 'css/master.plain.css', 'css/sponsors.css',),
'output_filename': 'css/all.min.css',
},
'book': {
diff --git a/wolnelektury/templates/base.html b/wolnelektury/templates/base.html
index 4e7a6fabd..ec75d63d4 100644
--- a/wolnelektury/templates/base.html
+++ b/wolnelektury/templates/base.html
@@ -1,4 +1,4 @@
-{% load chunks compressed catalogue_tags %}
+{% load chunks compressed catalogue_tags sponsor_tags %}
@@ -55,11 +55,8 @@
Fundacja Nowoczesna Polska, 00-514 Warszawa, ul. MarszaÅkowska 84/92 lok. 125, tel/fax: (22) 621-30-17,
e-mail: fundacja@nowoczesnapolska.org.pl
-
-
-
-
+ {% sponsors %}