Commits

Bertrand Bordage committed d09018a

Use django-filer and add some slider settings to the plugin.

Comments (0)

Files changed (9)

 
 Features:
 
-- Four default nivo slider theme choices
-- User selection of nivo parameters: nivo theme, animation effect, speed, pause...
-- Auto-discovering of custom nivo themes on static dirs
-- Provides a very simple model for storing images and albums.
+- Easily upload dozens of images thanks to django-filer;
+- HTML description for each image;
+- Four default nivo slider theme choices;
+- User selection of nivo parameters: themes, animation, manual advance, thumbnails, etc;
+- Auto-discovering of custom nivo themes on static dirs.
 
 Requires:
-- easy-thumbnails http://pypi.python.org/pypi/easy-thumbnails/
+- `django-CMS <https://github.com/divio/django-cms>`_ (tested with 2.3)
+- `django-filer <https://github.com/stefanfoulis/django-filer>`_ (tested with 0.9a1)
 
 
 Installation

cmsplugin_nivoslider/cms_plugins.py

 
 class CMSSliderPlugin(CMSPluginBase):
     model = SliderPlugin
-    name = 'Slider Plugin'
+    name = 'Slider'
     render_template = 'nivo/slider.html'
     text_enabled = False
     admin_preview = False
         context.update({
             'object': instance,
             'placeholder': placeholder,
-            'images': instance.album.images.iterator(),
+            'images': instance.images,
             'size': size,
         })
         return context

cmsplugin_nivoslider/migrations/0007_auto__add_field_sliderplugin_manual_advance__add_field_sliderplugin_ar.py

+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'SliderPlugin.manual_advance'
+        db.add_column('cmsplugin_sliderplugin', 'manual_advance',
+                      self.gf('django.db.models.fields.BooleanField')(default=False),
+                      keep_default=False)
+
+        # Adding field 'SliderPlugin.arrows'
+        db.add_column('cmsplugin_sliderplugin', 'arrows',
+                      self.gf('django.db.models.fields.BooleanField')(default=True),
+                      keep_default=False)
+
+        # Adding field 'SliderPlugin.thumbnails'
+        db.add_column('cmsplugin_sliderplugin', 'thumbnails',
+                      self.gf('django.db.models.fields.BooleanField')(default=False),
+                      keep_default=False)
+
+        # Adding field 'SliderPlugin.random_start'
+        db.add_column('cmsplugin_sliderplugin', 'random_start',
+                      self.gf('django.db.models.fields.BooleanField')(default=False),
+                      keep_default=False)
+
+        # Adding field 'SliderPlugin.pause_on_hover'
+        db.add_column('cmsplugin_sliderplugin', 'pause_on_hover',
+                      self.gf('django.db.models.fields.BooleanField')(default=False),
+                      keep_default=False)
+
+
+        # Changing field 'SliderPlugin.album'
+        db.alter_column('cmsplugin_sliderplugin', 'album_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['filer.Folder']))
+
+    def backwards(self, orm):
+        # Deleting field 'SliderPlugin.manual_advance'
+        db.delete_column('cmsplugin_sliderplugin', 'manual_advance')
+
+        # Deleting field 'SliderPlugin.arrows'
+        db.delete_column('cmsplugin_sliderplugin', 'arrows')
+
+        # Deleting field 'SliderPlugin.thumbnails'
+        db.delete_column('cmsplugin_sliderplugin', 'thumbnails')
+
+        # Deleting field 'SliderPlugin.random_start'
+        db.delete_column('cmsplugin_sliderplugin', 'random_start')
+
+        # Deleting field 'SliderPlugin.pause_on_hover'
+        db.delete_column('cmsplugin_sliderplugin', 'pause_on_hover')
+
+
+        # Changing field 'SliderPlugin.album'
+        db.alter_column('cmsplugin_sliderplugin', 'album_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cmsplugin_nivoslider.SliderAlbum']))
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'cms.cmsplugin': {
+            'Meta': {'object_name': 'CMSPlugin'},
+            'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'language': ('django.db.models.fields.CharField', [], {'max_length': '15', 'db_index': 'True'}),
+            'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.CMSPlugin']", 'null': 'True', 'blank': 'True'}),
+            'placeholder': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Placeholder']", 'null': 'True'}),
+            'plugin_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
+            'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'})
+        },
+        'cms.placeholder': {
+            'Meta': {'object_name': 'Placeholder'},
+            'default_width': ('django.db.models.fields.PositiveSmallIntegerField', [], {'null': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'slot': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'})
+        },
+        'cmsplugin_nivoslider.slideralbum': {
+            'Meta': {'object_name': 'SliderAlbum'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['cmsplugin_nivoslider.SliderImage']", 'symmetrical': 'False', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'})
+        },
+        'cmsplugin_nivoslider.sliderimage': {
+            'Meta': {'ordering': "('order', 'name')", 'object_name': 'SliderImage'},
+            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '150', 'blank': 'True'}),
+            'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '100'})
+        },
+        'cmsplugin_nivoslider.sliderplugin': {
+            'Meta': {'object_name': 'SliderPlugin', 'db_table': "'cmsplugin_sliderplugin'", '_ormbases': ['cms.CMSPlugin']},
+            'album': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['filer.Folder']"}),
+            'anim_speed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '500'}),
+            'arrows': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'cmsplugin_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['cms.CMSPlugin']", 'unique': 'True', 'primary_key': 'True'}),
+            'effect': ('django.db.models.fields.CharField', [], {'default': "'random'", 'max_length': '50'}),
+            'height': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
+            'manual_advance': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'pause_on_hover': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'pause_time': ('django.db.models.fields.PositiveIntegerField', [], {'default': '3000'}),
+            'random_start': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'theme': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '50'}),
+            'thumbnails': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'title': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
+            'width': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        },
+        'filer.folder': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('parent', 'name'),)", 'object_name': 'Folder'},
+            'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+            'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'filer_owned_folders'", 'null': 'True', 'to': "orm['auth.User']"}),
+            'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['filer.Folder']"}),
+            'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}),
+            'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'})
+        }
+    }
+
+    complete_apps = ['cmsplugin_nivoslider']

cmsplugin_nivoslider/models.py

 # -*- coding:utf-8 -*-
 # author: bcabezas@apsl.net
 
-from django.db import models
+from django.db.models import Model, BooleanField, PositiveIntegerField, \
+                             CharField, TextField, ImageField, ManyToManyField
 
 from cms.models import CMSPlugin
+from filer.fields.folder import FilerFolderField
 from easy_thumbnails.files import get_thumbnailer
 from django.contrib.staticfiles.finders import find as staticfiles_find
 import os
 
 
-class SliderImage(models.Model):
+class SliderImage(Model):
     """Image class that user django-filer"""
-    name = models.CharField(max_length=150, blank=True)
-    description = models.TextField(blank=True)
-    image = models.ImageField(upload_to="nivoslider")
-    order = models.PositiveIntegerField(default=100)
+    name = CharField(max_length=150, blank=True)
+    description = TextField(blank=True)
+    image = ImageField(upload_to="nivoslider")
+    order = PositiveIntegerField(default=100)
 
     class Meta:
         verbose_name = u'Image'
     thumb.short_description = 'Image'
 
 
-class SliderAlbum(models.Model):
+class SliderAlbum(Model):
     """Image gallery for slider"""
-    name = models.CharField(max_length=150)
-    images = models.ManyToManyField(SliderImage, blank=True)
+    name = CharField(max_length=150)
+    images = ManyToManyField(SliderImage, blank=True)
 
     class Meta:
         verbose_name = u'Slider Album'
 
 
 class SliderPlugin(CMSPlugin):
-    title = models.CharField('title', max_length=255, null=True, blank=True)
-    album = models.ForeignKey(SliderAlbum)
-    theme = models.CharField(choices=THEME_CHOICES, max_length=50,
-                             default="default")
-    effect = models.CharField(choices=EFFECT_CHOICES, max_length=50,
-                              default="random")
-    anim_speed = models.PositiveIntegerField(default=500,
-                                             help_text="Animation Speed (ms)")
-    pause_time = models.PositiveIntegerField(default=3000,
-                                             help_text="Pause time (ms)")
-    width = models.PositiveIntegerField(null=True, blank=True,
-                                        help_text="Width of the plugin (px)")
-    height = models.PositiveIntegerField(null=True, blank=True,
-                                         help_text="Height of the plugin (px)")
+    title = CharField('title', max_length=255, null=True, blank=True)
+    album = FilerFolderField()
+    theme = CharField(choices=THEME_CHOICES, max_length=50, default="default")
+    effect = CharField(choices=EFFECT_CHOICES, max_length=50, default="random")
+    manual_advance = BooleanField()
+    anim_speed = PositiveIntegerField(default=500,
+                                      help_text="Animation Speed (ms)")
+    pause_time = PositiveIntegerField(default=3000, help_text="Pause time (ms)")
+    width = PositiveIntegerField(null=True, blank=True,
+                                 help_text="Width of the plugin (px)")
+    height = PositiveIntegerField(null=True, blank=True,
+                                  help_text="Height of the plugin (px)")
+    arrows = BooleanField(default=True, help_text='Arrow buttons for '
+                                                  'navigation')
+    thumbnails = BooleanField(help_text='Thumbnails for navigation '
+                                        '[only works with the default theme!]')
+    random_start = BooleanField()
+    pause_on_hover = BooleanField('pause on mouse hover')
 
     def __unicode__(self):
         if self.title:
             return self.title
-        return self.album.name
+        return unicode(self.album)
 
-    search_fields = ('title', 'album__name',)
+    @property
+    def images(self):
+        if not hasattr(self, '__images'):
+            self.__images = filter(lambda f: f.file_type == 'Image',
+                                   self.album.files)
+        return self.__images
+
+    search_fields = ('title', 'album__title',)

cmsplugin_nivoslider/static/nivo/themes/bar/bar.css

 }
 .theme-bar .nivo-controlNav.nivo-thumbs-enabled img {
 	display: block;
-	width: 120px;
+	width: 64px;
 	height: auto;
 }

cmsplugin_nivoslider/static/nivo/themes/dark/dark.css

 }
 .theme-dark .nivo-controlNav.nivo-thumbs-enabled img {
 	display: block;
-	width: 120px;
+	width: 64px;
 	height: auto;
 }

cmsplugin_nivoslider/static/nivo/themes/default/default.css

 }
 .theme-default .nivo-controlNav.nivo-thumbs-enabled img {
 	display: block;
-	width: 120px;
+	width: 64px;
 	height: auto;
 }

cmsplugin_nivoslider/static/nivo/themes/light/light.css

 }
 .theme-light .nivo-controlNav.nivo-thumbs-enabled img {
 	display: block;
-	width: 120px;
+	width: 64px;
 	height: auto;
 }

cmsplugin_nivoslider/templates/nivo/slider.html

-{% load i18n sekizai_tags thumbnail  %}
+{% load i18n sekizai_tags %}
 
 
 {% addtoblock "css" %}
                 effect: '{{object.effect}}',
                 animSpeed: {{object.anim_speed}},
                 pauseTime: {{object.pause_time}},
+                directionNav: {{object.arrows|lower}},
+                controlNavThumbs: {{object.thumbnails|lower}},
+                pauseOnHover: {{object.pause_on_hover|lower}},
+                manualAdvance: {{object.manual_advance|lower}},
                 prevText: '{% trans 'prev'|capfirst %}',
-                nextText: '{% trans 'next'|capfirst %}'
+                nextText: '{% trans 'next'|capfirst %}',
+                randomStart: {{object.random_start|lower}}
             });
         });
     </script>
 {% endaddtoblock %}
 
-<div class="slider-wrapper theme-{{object.theme}}">
-    <div id="nivoslider{{object.pk}}" class="nivoSlider"
-        style="
-            {% if object.width %}
-                width:{{object.width}}px;
-            {% endif %}
+<div    class="slider-wrapper theme-{{object.theme}}"
+        {% if object.width %}
+            style="width: {{object.width}}px;"
+        {% endif %}>
+    <div    id="nivoslider{{object.pk}}" class="nivoSlider"
+            title="{{object.title|default:''}}"
             {% if object.height %}
-                height:{{object.height}}px;
-            {% endif %}">
+                style="height: {{object.height}}px;"
+            {% endif %}>
         {% for img in images %}
-            <img
-                {% if size %}
-                    src="{% thumbnail img.image size crop %}"
-                {% else %}
-                    src="{{img.image.url}}"
-                {% endif %}
-                alt="{{img.name}}" title="{{img.description}}" />
+            <img    src="{{img.image.url}}"
+                    data-thumb="{{ img.image.icons.64 }}"
+                    alt="{{img.name|default:''}}"
+                    title="{{img.description|default:''}}" />
         {% endfor %}
     </div>
 </div>