From 0d0fa7a4cd45b477e40740a8d971ec814bc6a4a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20St=C4=99pniowski?= Date: Fri, 9 Oct 2009 17:09:14 +0200 Subject: [PATCH 1/1] =?utf8?q?Dodanie=20aplikacji=20sponsors=20do=20zarz?= =?utf8?q?=C4=85dzania=20logami=20sponsor=C3=B3w=20w=20stopce.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- apps/sponsors/__init__.py | 3 + apps/sponsors/admin.py | 21 +++++++ apps/sponsors/models.py | 35 +++++++++++ apps/sponsors/static/css/sponsors.css | 4 ++ .../static/js/ordered_select_multiple.js | 63 +++++++++++++++++++ .../sponsors/templates/sponsors/sponsors.html | 11 ++++ apps/sponsors/templatetags/__init__.py | 0 apps/sponsors/templatetags/sponsor_tags.py | 12 ++++ apps/sponsors/widgets.py | 30 +++++++++ wolnelektury/media/css/sponsors.css | 8 +++ .../media/js/ordered_select_multiple.js | 63 +++++++++++++++++++ wolnelektury/settings.py | 3 +- wolnelektury/templates/base.html | 7 +-- 13 files changed, 254 insertions(+), 6 deletions(-) create mode 100644 apps/sponsors/__init__.py create mode 100644 apps/sponsors/admin.py create mode 100644 apps/sponsors/models.py create mode 100644 apps/sponsors/static/css/sponsors.css create mode 100644 apps/sponsors/static/js/ordered_select_multiple.js create mode 100644 apps/sponsors/templates/sponsors/sponsors.html create mode 100644 apps/sponsors/templatetags/__init__.py create mode 100644 apps/sponsors/templatetags/sponsor_tags.py create mode 100644 apps/sponsors/widgets.py create mode 100644 wolnelektury/media/css/sponsors.css create mode 100644 wolnelektury/media/js/ordered_select_multiple.js 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 $('
    1. ' + hash.name + '
    2. ').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 @@ +
      +{% for group in sponsor_groups %} + +{% endfor %} +
      +
      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 $('
        1. ' + hash.name + '
        2. ').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

          -

          - Partnerzy serwisu -{% chunk 'footer-map' %} -

          + {% sponsors %}
          -- 2.20.1