From 7fa8ecdff3430fba8463cf1175a7346618a35926 Mon Sep 17 00:00:00 2001 From: Kostas Papadimitriou Date: Mon, 26 Mar 2012 15:27:04 +0300 Subject: [PATCH] Resources application initial commit --- cloudcms/cms.py | 2 + .../migrate/page/0007_auto__add_resourceslist.py | 232 +++++ cloudcms/models.py | 1 + cloudcms/static/cloudcms/css/styles.css | 269 +++++- .../cloudcms/images/resource_down_arrow-active.png | Bin 0 -> 521 bytes .../static/cloudcms/images/resource_down_arrow.png | Bin 0 -> 522 bytes cloudcms/static/cloudcms/js/underscore.js | 999 ++++++++++++++++++++ cloudcms/static/cloudcms/less/resources.less | 127 +++ cloudcms/static/cloudcms/less/styles.less | 54 +- cloudcms/static/cloudcms/less/xtra.less | 23 +- cloudcms/synnefo_settings.py | 3 +- cloudcms/templates/cms/base.html | 8 +- cloudcms/templates/content/template/resources.html | 76 -- cloudcmsresources/admin.py | 34 + cloudcmsresources/migrations/0001_initial.py | 60 ++ ..._auto__add_resourcetranslation__add_resource.py | 95 ++ ...ield_resourcecategorytranslation_description.py | 74 ++ ...ield_resourcecategorytranslation_description.py | 74 ++ ...o__chg_field_resourcetranslation_description.py | 74 ++ ...ublished_on__add_field_resource_is_published.py | 82 ++ cloudcmsresources/models.py | 176 ++++ .../static/cloudcmsresources/js/resources_list.js | 111 +++ .../templates/content/resources_list.html | 55 ++ 23 files changed, 2461 insertions(+), 168 deletions(-) create mode 100644 cloudcms/migrate/page/0007_auto__add_resourceslist.py create mode 100644 cloudcms/static/cloudcms/images/resource_down_arrow-active.png create mode 100644 cloudcms/static/cloudcms/images/resource_down_arrow.png create mode 100644 cloudcms/static/cloudcms/js/underscore.js create mode 100644 cloudcms/static/cloudcms/less/resources.less delete mode 100644 cloudcms/templates/content/template/resources.html create mode 100644 cloudcmsresources/__init__.py create mode 100644 cloudcmsresources/admin.py create mode 100644 cloudcmsresources/migrations/0001_initial.py create mode 100644 cloudcmsresources/migrations/0002_auto__add_resourcetranslation__add_resource.py create mode 100644 cloudcmsresources/migrations/0003_auto__chg_field_resourcecategorytranslation_description.py create mode 100644 cloudcmsresources/migrations/0004_auto__chg_field_resourcecategorytranslation_description.py create mode 100644 cloudcmsresources/migrations/0005_auto__chg_field_resourcetranslation_description.py create mode 100644 cloudcmsresources/migrations/0006_auto__add_field_resource_published_on__add_field_resource_is_published.py create mode 100644 cloudcmsresources/migrations/__init__.py create mode 100644 cloudcmsresources/models.py create mode 100644 cloudcmsresources/static/cloudcmsresources/js/resources_list.js create mode 100644 cloudcmsresources/templates/content/resources_list.html create mode 100644 cloudcmsresources/urls.py create mode 100644 cloudcmsresources/views.py diff --git a/cloudcms/cms.py b/cloudcms/cms.py index 4cf9d5f..4ba1a67 100644 --- a/cloudcms/cms.py +++ b/cloudcms/cms.py @@ -55,6 +55,7 @@ from feincms.content.video.models import VideoContent from feincms.content.richtext.models import RichTextContent from cloudcmsblog.models import Entry, LatestEntries +from cloudcmsresources.models import ResourcesList from cloudcms.content import * Page.register_extensions( @@ -143,6 +144,7 @@ Page.create_content_type(ApplicationContent, APPLICATIONS=( # cloudcms specific content registration Page.create_content_type(LoginForm) Page.create_content_type(AboutBlock) +Page.create_content_type(ResourcesList) # Feincms specific registrations for our blog entry model diff --git a/cloudcms/migrate/page/0007_auto__add_resourceslist.py b/cloudcms/migrate/page/0007_auto__add_resourceslist.py new file mode 100644 index 0000000..e3978db --- /dev/null +++ b/cloudcms/migrate/page/0007_auto__add_resourceslist.py @@ -0,0 +1,232 @@ +# encoding: 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 model 'ResourcesList' + db.create_table('page_page_resourceslist', ( + ('ordering', self.gf('django.db.models.fields.IntegerField')(default=0)), + ('filter_title', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('region', self.gf('django.db.models.fields.CharField')(max_length=255)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='resourceslist_set', to=orm['page.Page'])), + )) + db.send_create_signal('page', ['ResourcesList']) + + + def backwards(self, orm): + + # Deleting model 'ResourcesList' + db.delete_table('page_page_resourceslist') + + + models = { + 'medialibrary.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'medialibrary.mediafile': { + 'Meta': {'object_name': 'MediaFile'}, + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), + 'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) + }, + 'page.aboutblock': { + 'Meta': {'object_name': 'AboutBlock', 'db_table': "'page_page_aboutblock'"}, + 'color': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']", 'null': 'True', 'blank': 'True'}), + 'image_position': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'offset_left': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'offset_top': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'aboutblock_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'page.applicationcontent': { + 'Meta': {'object_name': 'ApplicationContent', 'db_table': "'page_page_applicationcontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parameters': ('feincms.contrib.fields.JSONField', [], {'null': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'applicationcontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'urlconf_path': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'page.imagecontent': { + 'Meta': {'object_name': 'ImageContent', 'db_table': "'page_page_imagecontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'imagecontent_set'", 'to': "orm['page.Page']"}), + 'position': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '10'}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'page.latestentries': { + 'Meta': {'object_name': 'LatestEntries', 'db_table': "'page_page_latestentries'"}, + 'display_text': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'limit': ('django.db.models.fields.PositiveIntegerField', [], {'default': '3'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'latestentries_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'page.loginform': { + 'Meta': {'object_name': 'LoginForm', 'db_table': "'page_page_loginform'"}, + 'action_url': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'bottom_content': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'display_forgot_password': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'logged_in_content': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'next_url': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'loginform_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'page.mediafilecontent': { + 'Meta': {'object_name': 'MediaFileContent', 'db_table': "'page_page_mediafilecontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mediafile': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'related_name': "'+'", 'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'mediafilecontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'type': ('django.db.models.fields.CharField', [], {'default': "'lightbox'", 'max_length': '20'}) + }, + 'page.page': { + 'Meta': {'object_name': 'Page'}, + '_cached_url': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'db_index': 'True', 'blank': 'True'}), + '_content_title': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + '_page_title': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), + 'active': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'creation_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'in_navigation': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'language': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'meta_description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'meta_keywords': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'modification_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), + 'navigation_extension': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'override_url': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['page.Page']"}), + 'publication_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime(2012, 3, 20, 17, 40)'}), + 'publication_end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'redirect_to': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}), + 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'default': '1', 'to': "orm['sites.Site']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'symlinked_page': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'page_page_symlinks'", 'null': 'True', 'to': "orm['page.Page']"}), + 'template_key': ('django.db.models.fields.CharField', [], {'default': "'basic'", 'max_length': '255'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}), + 'translation_of': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'translations'", 'null': 'True', 'to': "orm['page.Page']"}), + 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) + }, + 'page.rawcontent': { + 'Meta': {'object_name': 'RawContent', 'db_table': "'page_page_rawcontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rawcontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'page.resourceslist': { + 'Meta': {'object_name': 'ResourcesList', 'db_table': "'page_page_resourceslist'"}, + 'filter_title': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'resourceslist_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'page.richtextcontent': { + 'Meta': {'object_name': 'RichTextContent', 'db_table': "'page_page_richtextcontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'richtextcontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'text': ('django.db.models.fields.TextField', [], {'blank': 'True'}) + }, + 'page.sectioncontent': { + 'Meta': {'object_name': 'SectionContent', 'db_table': "'page_page_sectioncontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mediafile': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'page_sectioncontent_set'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'sectioncontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'richtext': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'default': "'block'", 'max_length': '10'}) + }, + 'page.templatecontent': { + 'Meta': {'object_name': 'TemplateContent', 'db_table': "'page_page_templatecontent'"}, + 'filename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'templatecontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'page.twitterfeed': { + 'Meta': {'object_name': 'TwitterFeed', 'db_table': "'page_page_twitterfeed'"}, + 'account': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'avatar': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'extra_params': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'limit': ('django.db.models.fields.PositiveIntegerField', [], {'default': '10'}), + 'nots': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'twitterfeed_set'", 'to': "orm['page.Page']"}), + 'query': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'replies': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'retweets': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'tag': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}) + }, + 'page.videocontent': { + 'Meta': {'object_name': 'VideoContent', 'db_table': "'page_page_videocontent'"}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videocontent_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'video': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'page.videosection': { + 'Meta': {'object_name': 'VideoSection', 'db_table': "'page_page_videosection'"}, + 'alt_text': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'extra_url_params': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_image_for_video_section'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), + 'image_hover': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'blank': 'True', 'related_name': "'as_hover_for_video_section'", 'null': 'True', 'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.IntegerField', [], {'default': '0'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'videosection_set'", 'to': "orm['page.Page']"}), + 'region': ('django.db.models.fields.CharField', [], {'max_length': '255'}), + 'section_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'video_height': ('django.db.models.fields.PositiveIntegerField', [], {'default': '550'}), + 'video_link': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'video_title': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'video_width': ('django.db.models.fields.PositiveIntegerField', [], {'default': '700'}) + }, + 'sites.site': { + 'Meta': {'object_name': 'Site', 'db_table': "'django_site'"}, + 'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + } + } + + complete_apps = ['page'] diff --git a/cloudcms/models.py b/cloudcms/models.py index 372a7c1..0115b36 100644 --- a/cloudcms/models.py +++ b/cloudcms/models.py @@ -70,6 +70,7 @@ class Application(models.Model): def __unicode__(self): return self.title + # hook for feincms configuration, is this appropriate place ??? who knows from cloudcms.cms import * diff --git a/cloudcms/static/cloudcms/css/styles.css b/cloudcms/static/cloudcms/css/styles.css index bcf5830..1a1e853 100644 --- a/cloudcms/static/cloudcms/css/styles.css +++ b/cloudcms/static/cloudcms/css/styles.css @@ -208,6 +208,25 @@ textarea { .button:hover { background-color: #f89a1c; } +.button.back { + text-decoration: none; + bottom: 0; + float: right; + z-index: 500; +} +.button.back.right { + right: 0; +} +.buttons-list { + z-index: 300; + position: relative; +} +.buttons-list .button { + margin-left: 10px; +} +.buttons-list.fixpos { + margin-top: -42px; +} a.button { text-align: center !important; color: #fff !important; @@ -451,6 +470,25 @@ table .headerSortUp.purple, table .headerSortDown.purple { .button:hover { background-color: #f89a1c; } +.button.back { + text-decoration: none; + bottom: 0; + float: right; + z-index: 500; +} +.button.back.right { + right: 0; +} +.buttons-list { + z-index: 300; + position: relative; +} +.buttons-list .button { + margin-left: 10px; +} +.buttons-list.fixpos { + margin-top: -42px; +} a.button { text-align: center !important; color: #fff !important; @@ -598,6 +636,147 @@ a.button:hover { #cboxClose:hover { background-position: bottom center; } +.resources .categories ul { + zoom: 1; +} +.resources .categories ul:before, .resources .categories ul:after { + display: table; + content: ""; + zoom: 1; +} +.resources .categories ul:after { + clear: both; +} +.resources .categories ul li { + float: left; +} +.resources .categories .title { + margin-bottom: 7.333333333333333px; +} +.resources .categories ul li a { + text-decoration: none; + color: #000; + margin-right: 22px; +} +.resources .categories ul li a:hover, .resources .categories ul li a.selected { + color: #000 !important; +} +.resources .categories ul li a.inactive { + opacity: 0.4; +} +.resources .list { + font-size: 0.9em; + line-height: 1em; + margin-top: 58.666666666666664px; + position: relative; +} +.resources .list .resource-wrapper.first .resource { + margin-left: 0; +} +.resources .list .resource-wrapper { + position: relative; + width: 200px; + margin-left: 22px; + margin-bottom: 22px; + width: 251px; + float: left; + overflow: hidden; + height: 249.33333333333331px; +} +.resources .list .resource-wrapper.first { + margin-left: 0; +} +.resources .list .resource-wrapper.hidden { + display: none; +} +.resources .list .resource { + border: 1px solid #000; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + *behavior: url(boxsizing.htc); + padding: 29.333333333333332px; + height: 249.33333333333331px; + overflow: hidden; +} +.resources .list .resource .date { + color: #808080; + margin-bottom: 3px; +} +.resources .list .resource .description { + font-size: 1.1em; + position: absolute; + height: 210px; + -webkit-transition: top 0.35s ease-in-out; + -moz-transition: top 0.35s ease-in-out; + transition: top 0.35s ease-in-out; + -webkit-transition: top 0.35s ease-in-out; + -moz-transition: top 0.35s ease-in-out; + transition: top 0.35s ease-in-out; + top: -210px; + width: 100%; + margin-left: -29.333333333333332px; + padding: 29.333333333333332px; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + *behavior: url(boxsizing.htc); + color: #fff; +} +.resources .list .resource .title { + line-height: 1.4em; +} +.resources .list .resource .category { + margin-top: 29.333333333333332px; + color: #808080; +} +.resources .list .resource .category a { + color: #808080; +} +.resources .list .resource .download { + bottom: 0; + position: absolute; + font-size: 1.1em; + width: 100%; + text-align: middle; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + box-sizing: border-box; + *behavior: url(boxsizing.htc); + cursor: pointer; +} +.resources .list .resource .download a { + display: block; + color: #000000; + text-decoration: none; + padding: 5px; + padding-left: 14.666666666666666px; +} +.resources .list .resource .download a:hover, .resources .list .resource .download a .hovered { + color: #ff5d00; +} +.resources .list .resource .download a:hover .download-image, .resources .list .resource .download a .hovered .download-image { + background-image: url("../images/resource_down_arrow-active.png"); +} +.resources .list .resource .download a .download-image { + display: block; + width: 30px; + height: 30px; + float: left; + margin-top: -7px; + margin-right: 10px; + background-image: url("../images/resource_down_arrow.png"); + background-position: 50% 50%; + background-repeat: no-repeat; +} +.resources .list .resource .download img { + margin-right: 10px; + vertical-align: middle; +} +.resources .list .resource:hover .description, .resources .list .resource .hover .description { + top: 0; + display: block; +} .border-box { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -1185,9 +1364,27 @@ form input.submit, form input[type="submit"] { form input.submit:hover, form input[type="submit"]:hover { background-color: #f89a1c; } +form input.submit.back, form input[type="submit"].back { + text-decoration: none; + bottom: 0; + float: right; + z-index: 500; +} +form input.submit.back.right, form input[type="submit"].back.right { + right: 0; +} form input.submit:hover, form input[type="submit"]:hover { background-color: #f89a1c; } +form input.submit.back, form input[type="submit"].back { + text-decoration: none; + bottom: 0; + float: right; + z-index: 500; +} +form input.submit.back.right, form input[type="submit"].back.right { + right: 0; +} form textarea { height: 200px; width: 350px !important; @@ -1263,9 +1460,16 @@ div.form-stacked { color: #ffffff; } .messages li.warning { - background-color: #ffc40d; + background-color: #AF6906; color: #000000; } +.messages .warning { + color: #ffffff !important; +} +.messages .warning a { + color: inherit; + font-weight: bold; +} .service-desc { margin-top: 4em; } @@ -1300,10 +1504,12 @@ table tr.consumed td.consumed { .footer { zoom: 1; color: #b3b3b3; - -webkit-transition: color 0.15s linear; - transition: color 0.15s linear; - -webkit-transition: color 0.15s linear; - transition: color 0.15s linear; + -webkit-transition: color 0.15s ease-in-out; + -moz-transition: color 0.15s ease-in-out; + transition: color 0.15s ease-in-out; + -webkit-transition: color 0.15s ease-in-out; + -moz-transition: color 0.15s ease-in-out; + transition: color 0.15s ease-in-out; } .footer:before, .footer:after { display: table; @@ -1314,10 +1520,12 @@ table tr.consumed td.consumed { clear: both; } .footer a { - -webkit-transition: color 0.15s linear; - transition: color 0.15s linear; - -webkit-transition: color 0.15s linear; - transition: color 0.15s linear; + -webkit-transition: color 0.15s ease-in-out; + -moz-transition: color 0.15s ease-in-out; + transition: color 0.15s ease-in-out; + -webkit-transition: color 0.15s ease-in-out; + -moz-transition: color 0.15s ease-in-out; + transition: color 0.15s ease-in-out; } .footer:hover { color: #808080 !important; @@ -1558,46 +1766,6 @@ table tr.consumed td.consumed { .initial_hidden { display: none; } -/*resources styles*/ -.resources .categories ul { - zoom: 1; -} -.resources .categories ul:before, .resources .categories ul:after { - display: table; - content: ""; - zoom: 1; -} -.resources .categories ul:after { - clear: both; -} -.resources .categories ul li { - float: left; -} -.resources .categories .title { - margin-bottom: 7.333333333333333px; -} -.resources .categories ul li a { - text-decoration: none; - color: #faaf40; - margin-right: 22px; -} -.resources .list { - margin-top: 58.666666666666664px; -} -.resources .list .resource { - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; - box-sizing: border-box; - *behavior: url(boxsizing.htc); - width: 33%; - padding: 29.333333333333332px; - float: left; - border: 1px solid #faaf40; - height: 176px; -} -.resources .list .resource .description { - display: none; -} /* recaptcha */ #recaptcha_widget_div { margin-top: 10px; @@ -1608,6 +1776,9 @@ table tr.consumed td.consumed { margin-bottom: 10px; display: block !important; } +#recaptcha_widget_div th, #recaptcha_widget_div td { + line-height: 1; +} .checkbox-widget.checked { background-color: #f00; background-image: url("../images/checkbox.png"); diff --git a/cloudcms/static/cloudcms/images/resource_down_arrow-active.png b/cloudcms/static/cloudcms/images/resource_down_arrow-active.png new file mode 100644 index 0000000000000000000000000000000000000000..2c2e77c0f2572b0f097a1fbc55d21bb9434594d4 GIT binary patch literal 521 zcmV+k0`~ohP)P000^Y1^@s6LVfqm00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyY| z2?7H@6b#S+000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0004GNklc+2L{Mz(#Rm|35qt>2!UwQY1g*4O zv5BG^BugYWleouX2q{D}39bnGH#6tJ%*UC3Zc0Rih-L8u`h}3UCP)}DimpmM1b%i}c zT7x%SsFidaOXxm8?i%V@C1h5-yKmJOkN%m|6O!-K7*L3${bw}j(qV1W1RM(GI(FZqWv~|1lq)~-t9V$gAJwrLr=S2k4^N^bSa*DW- zC#w!5wEx%xFfk2d8L%wqcRNDNmaF&#@jgAF74Q1)QvV-`zX^EigP)P000^Y1^@s6LVfqm00001b5ch_0Itp) z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2iyY> z5G4RYK5yj!000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0004HNklqdV(II2hgkZ0xmp(M<{|_Xc1|}wqV}u zWL(TN#ig-9u}-|yS6BuSEXA(my~e!o8@Oebj_-Kdg8uh#pyzp9EEbRPmm!}u9*-%dq-mPG-EP|Rv>{3< z9*;*_mc`X-)nsoJO&_f!Ng$ 2; + if (obj == null) obj = []; + if (nativeReduce && obj.reduce === nativeReduce) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator); + } + each(obj, function(value, index, list) { + if (!initial) { + memo = value; + initial = true; + } else { + memo = iterator.call(context, memo, value, index, list); + } + }); + if (!initial) throw new TypeError('Reduce of empty array with no initial value'); + return memo; + }; + + // The right-associative version of reduce, also known as `foldr`. + // Delegates to **ECMAScript 5**'s native `reduceRight` if available. + _.reduceRight = _.foldr = function(obj, iterator, memo, context) { + var initial = arguments.length > 2; + if (obj == null) obj = []; + if (nativeReduceRight && obj.reduceRight === nativeReduceRight) { + if (context) iterator = _.bind(iterator, context); + return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator); + } + var reversed = _.toArray(obj).reverse(); + if (context && !initial) iterator = _.bind(iterator, context); + return initial ? _.reduce(reversed, iterator, memo, context) : _.reduce(reversed, iterator); + }; + + // Return the first value which passes a truth test. Aliased as `detect`. + _.find = _.detect = function(obj, iterator, context) { + var result; + any(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) { + result = value; + return true; + } + }); + return result; + }; + + // Return all the elements that pass a truth test. + // Delegates to **ECMAScript 5**'s native `filter` if available. + // Aliased as `select`. + _.filter = _.select = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + each(obj, function(value, index, list) { + if (iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Return all the elements for which a truth test fails. + _.reject = function(obj, iterator, context) { + var results = []; + if (obj == null) return results; + each(obj, function(value, index, list) { + if (!iterator.call(context, value, index, list)) results[results.length] = value; + }); + return results; + }; + + // Determine whether all of the elements match a truth test. + // Delegates to **ECMAScript 5**'s native `every` if available. + // Aliased as `all`. + _.every = _.all = function(obj, iterator, context) { + var result = true; + if (obj == null) return result; + if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + each(obj, function(value, index, list) { + if (!(result = result && iterator.call(context, value, index, list))) return breaker; + }); + return result; + }; + + // Determine if at least one element in the object matches a truth test. + // Delegates to **ECMAScript 5**'s native `some` if available. + // Aliased as `any`. + var any = _.some = _.any = function(obj, iterator, context) { + iterator || (iterator = _.identity); + var result = false; + if (obj == null) return result; + if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + each(obj, function(value, index, list) { + if (result || (result = iterator.call(context, value, index, list))) return breaker; + }); + return !!result; + }; + + // Determine if a given value is included in the array or object using `===`. + // Aliased as `contains`. + _.include = _.contains = function(obj, target) { + var found = false; + if (obj == null) return found; + if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1; + found = any(obj, function(value) { + return value === target; + }); + return found; + }; + + // Invoke a method (with arguments) on every item in a collection. + _.invoke = function(obj, method) { + var args = slice.call(arguments, 2); + return _.map(obj, function(value) { + return (_.isFunction(method) ? method || value : value[method]).apply(value, args); + }); + }; + + // Convenience version of a common use case of `map`: fetching a property. + _.pluck = function(obj, key) { + return _.map(obj, function(value){ return value[key]; }); + }; + + // Return the maximum element or (element-based computation). + _.max = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.max.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return -Infinity; + var result = {computed : -Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed >= result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Return the minimum element (or element-based computation). + _.min = function(obj, iterator, context) { + if (!iterator && _.isArray(obj)) return Math.min.apply(Math, obj); + if (!iterator && _.isEmpty(obj)) return Infinity; + var result = {computed : Infinity}; + each(obj, function(value, index, list) { + var computed = iterator ? iterator.call(context, value, index, list) : value; + computed < result.computed && (result = {value : value, computed : computed}); + }); + return result.value; + }; + + // Shuffle an array. + _.shuffle = function(obj) { + var shuffled = [], rand; + each(obj, function(value, index, list) { + if (index == 0) { + shuffled[0] = value; + } else { + rand = Math.floor(Math.random() * (index + 1)); + shuffled[index] = shuffled[rand]; + shuffled[rand] = value; + } + }); + return shuffled; + }; + + // Sort the object's values by a criterion produced by an iterator. + _.sortBy = function(obj, iterator, context) { + return _.pluck(_.map(obj, function(value, index, list) { + return { + value : value, + criteria : iterator.call(context, value, index, list) + }; + }).sort(function(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }), 'value'); + }; + + // Groups the object's values by a criterion. Pass either a string attribute + // to group by, or a function that returns the criterion. + _.groupBy = function(obj, val) { + var result = {}; + var iterator = _.isFunction(val) ? val : function(obj) { return obj[val]; }; + each(obj, function(value, index) { + var key = iterator(value, index); + (result[key] || (result[key] = [])).push(value); + }); + return result; + }; + + // Use a comparator function to figure out at what index an object should + // be inserted so as to maintain order. Uses binary search. + _.sortedIndex = function(array, obj, iterator) { + iterator || (iterator = _.identity); + var low = 0, high = array.length; + while (low < high) { + var mid = (low + high) >> 1; + iterator(array[mid]) < iterator(obj) ? low = mid + 1 : high = mid; + } + return low; + }; + + // Safely convert anything iterable into a real, live array. + _.toArray = function(iterable) { + if (!iterable) return []; + if (iterable.toArray) return iterable.toArray(); + if (_.isArray(iterable)) return slice.call(iterable); + if (_.isArguments(iterable)) return slice.call(iterable); + return _.values(iterable); + }; + + // Return the number of elements in an object. + _.size = function(obj) { + return _.toArray(obj).length; + }; + + // Array Functions + // --------------- + + // Get the first element of an array. Passing **n** will return the first N + // values in the array. Aliased as `head`. The **guard** check allows it to work + // with `_.map`. + _.first = _.head = function(array, n, guard) { + return (n != null) && !guard ? slice.call(array, 0, n) : array[0]; + }; + + // Returns everything but the last entry of the array. Especcialy useful on + // the arguments object. Passing **n** will return all the values in + // the array, excluding the last N. The **guard** check allows it to work with + // `_.map`. + _.initial = function(array, n, guard) { + return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n)); + }; + + // Get the last element of an array. Passing **n** will return the last N + // values in the array. The **guard** check allows it to work with `_.map`. + _.last = function(array, n, guard) { + if ((n != null) && !guard) { + return slice.call(array, Math.max(array.length - n, 0)); + } else { + return array[array.length - 1]; + } + }; + + // Returns everything but the first entry of the array. Aliased as `tail`. + // Especially useful on the arguments object. Passing an **index** will return + // the rest of the values in the array from that index onward. The **guard** + // check allows it to work with `_.map`. + _.rest = _.tail = function(array, index, guard) { + return slice.call(array, (index == null) || guard ? 1 : index); + }; + + // Trim out all falsy values from an array. + _.compact = function(array) { + return _.filter(array, function(value){ return !!value; }); + }; + + // Return a completely flattened version of an array. + _.flatten = function(array, shallow) { + return _.reduce(array, function(memo, value) { + if (_.isArray(value)) return memo.concat(shallow ? value : _.flatten(value)); + memo[memo.length] = value; + return memo; + }, []); + }; + + // Return a version of the array that does not contain the specified value(s). + _.without = function(array) { + return _.difference(array, slice.call(arguments, 1)); + }; + + // Produce a duplicate-free version of the array. If the array has already + // been sorted, you have the option of using a faster algorithm. + // Aliased as `unique`. + _.uniq = _.unique = function(array, isSorted, iterator) { + var initial = iterator ? _.map(array, iterator) : array; + var result = []; + _.reduce(initial, function(memo, el, i) { + if (0 == i || (isSorted === true ? _.last(memo) != el : !_.include(memo, el))) { + memo[memo.length] = el; + result[result.length] = array[i]; + } + return memo; + }, []); + return result; + }; + + // Produce an array that contains the union: each distinct element from all of + // the passed-in arrays. + _.union = function() { + return _.uniq(_.flatten(arguments, true)); + }; + + // Produce an array that contains every item shared between all the + // passed-in arrays. (Aliased as "intersect" for back-compat.) + _.intersection = _.intersect = function(array) { + var rest = slice.call(arguments, 1); + return _.filter(_.uniq(array), function(item) { + return _.every(rest, function(other) { + return _.indexOf(other, item) >= 0; + }); + }); + }; + + // Take the difference between one array and a number of other arrays. + // Only the elements present in just the first array will remain. + _.difference = function(array) { + var rest = _.flatten(slice.call(arguments, 1)); + return _.filter(array, function(value){ return !_.include(rest, value); }); + }; + + // Zip together multiple lists into a single array -- elements that share + // an index go together. + _.zip = function() { + var args = slice.call(arguments); + var length = _.max(_.pluck(args, 'length')); + var results = new Array(length); + for (var i = 0; i < length; i++) results[i] = _.pluck(args, "" + i); + return results; + }; + + // If the browser doesn't supply us with indexOf (I'm looking at you, **MSIE**), + // we need this function. Return the position of the first occurrence of an + // item in an array, or -1 if the item is not included in the array. + // Delegates to **ECMAScript 5**'s native `indexOf` if available. + // If the array is large and already in sort order, pass `true` + // for **isSorted** to use binary search. + _.indexOf = function(array, item, isSorted) { + if (array == null) return -1; + var i, l; + if (isSorted) { + i = _.sortedIndex(array, item); + return array[i] === item ? i : -1; + } + if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item); + for (i = 0, l = array.length; i < l; i++) if (i in array && array[i] === item) return i; + return -1; + }; + + // Delegates to **ECMAScript 5**'s native `lastIndexOf` if available. + _.lastIndexOf = function(array, item) { + if (array == null) return -1; + if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) return array.lastIndexOf(item); + var i = array.length; + while (i--) if (i in array && array[i] === item) return i; + return -1; + }; + + // Generate an integer Array containing an arithmetic progression. A port of + // the native Python `range()` function. See + // [the Python documentation](http://docs.python.org/library/functions.html#range). + _.range = function(start, stop, step) { + if (arguments.length <= 1) { + stop = start || 0; + start = 0; + } + step = arguments[2] || 1; + + var len = Math.max(Math.ceil((stop - start) / step), 0); + var idx = 0; + var range = new Array(len); + + while(idx < len) { + range[idx++] = start; + start += step; + } + + return range; + }; + + // Function (ahem) Functions + // ------------------ + + // Reusable constructor function for prototype setting. + var ctor = function(){}; + + // Create a function bound to a given object (assigning `this`, and arguments, + // optionally). Binding with arguments is also known as `curry`. + // Delegates to **ECMAScript 5**'s native `Function.bind` if available. + // We check for `func.bind` first, to fail fast when `func` is undefined. + _.bind = function bind(func, context) { + var bound, args; + if (func.bind === nativeBind && nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); + if (!_.isFunction(func)) throw new TypeError; + args = slice.call(arguments, 2); + return bound = function() { + if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments))); + ctor.prototype = func.prototype; + var self = new ctor; + var result = func.apply(self, args.concat(slice.call(arguments))); + if (Object(result) === result) return result; + return self; + }; + }; + + // Bind all of an object's methods to that object. Useful for ensuring that + // all callbacks defined on an object belong to it. + _.bindAll = function(obj) { + var funcs = slice.call(arguments, 1); + if (funcs.length == 0) funcs = _.functions(obj); + each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); + return obj; + }; + + // Memoize an expensive function by storing its results. + _.memoize = function(func, hasher) { + var memo = {}; + hasher || (hasher = _.identity); + return function() { + var key = hasher.apply(this, arguments); + return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments)); + }; + }; + + // Delays a function for the given number of milliseconds, and then calls + // it with the arguments supplied. + _.delay = function(func, wait) { + var args = slice.call(arguments, 2); + return setTimeout(function(){ return func.apply(func, args); }, wait); + }; + + // Defers a function, scheduling it to run after the current call stack has + // cleared. + _.defer = function(func) { + return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1))); + }; + + // Returns a function, that, when invoked, will only be triggered at most once + // during a given window of time. + _.throttle = function(func, wait) { + var context, args, timeout, throttling, more; + var whenDone = _.debounce(function(){ more = throttling = false; }, wait); + return function() { + context = this; args = arguments; + var later = function() { + timeout = null; + if (more) func.apply(context, args); + whenDone(); + }; + if (!timeout) timeout = setTimeout(later, wait); + if (throttling) { + more = true; + } else { + func.apply(context, args); + } + whenDone(); + throttling = true; + }; + }; + + // Returns a function, that, as long as it continues to be invoked, will not + // be triggered. The function will be called after it stops being called for + // N milliseconds. + _.debounce = function(func, wait) { + var timeout; + return function() { + var context = this, args = arguments; + var later = function() { + timeout = null; + func.apply(context, args); + }; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + }; + }; + + // Returns a function that will be executed at most one time, no matter how + // often you call it. Useful for lazy initialization. + _.once = function(func) { + var ran = false, memo; + return function() { + if (ran) return memo; + ran = true; + return memo = func.apply(this, arguments); + }; + }; + + // Returns the first function passed as an argument to the second, + // allowing you to adjust arguments, run code before and after, and + // conditionally execute the original function. + _.wrap = function(func, wrapper) { + return function() { + var args = [func].concat(slice.call(arguments, 0)); + return wrapper.apply(this, args); + }; + }; + + // Returns a function that is the composition of a list of functions, each + // consuming the return value of the function that follows. + _.compose = function() { + var funcs = arguments; + return function() { + var args = arguments; + for (var i = funcs.length - 1; i >= 0; i--) { + args = [funcs[i].apply(this, args)]; + } + return args[0]; + }; + }; + + // Returns a function that will only be executed after being called N times. + _.after = function(times, func) { + if (times <= 0) return func(); + return function() { + if (--times < 1) { return func.apply(this, arguments); } + }; + }; + + // Object Functions + // ---------------- + + // Retrieve the names of an object's properties. + // Delegates to **ECMAScript 5**'s native `Object.keys` + _.keys = nativeKeys || function(obj) { + if (obj !== Object(obj)) throw new TypeError('Invalid object'); + var keys = []; + for (var key in obj) if (_.has(obj, key)) keys[keys.length] = key; + return keys; + }; + + // Retrieve the values of an object's properties. + _.values = function(obj) { + return _.map(obj, _.identity); + }; + + // Return a sorted list of the function names available on the object. + // Aliased as `methods` + _.functions = _.methods = function(obj) { + var names = []; + for (var key in obj) { + if (_.isFunction(obj[key])) names.push(key); + } + return names.sort(); + }; + + // Extend a given object with all the properties in passed-in object(s). + _.extend = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Fill in a given object with default properties. + _.defaults = function(obj) { + each(slice.call(arguments, 1), function(source) { + for (var prop in source) { + if (obj[prop] == null) obj[prop] = source[prop]; + } + }); + return obj; + }; + + // Create a (shallow-cloned) duplicate of an object. + _.clone = function(obj) { + if (!_.isObject(obj)) return obj; + return _.isArray(obj) ? obj.slice() : _.extend({}, obj); + }; + + // Invokes interceptor with the obj, and then returns obj. + // The primary purpose of this method is to "tap into" a method chain, in + // order to perform operations on intermediate results within the chain. + _.tap = function(obj, interceptor) { + interceptor(obj); + return obj; + }; + + // Internal recursive comparison function. + function eq(a, b, stack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the Harmony `egal` proposal: http://wiki.ecmascript.org/doku.php?id=harmony:egal. + if (a === b) return a !== 0 || 1 / a == 1 / b; + // A strict comparison is necessary because `null == undefined`. + if (a == null || b == null) return a === b; + // Unwrap any wrapped objects. + if (a._chain) a = a._wrapped; + if (b._chain) b = b._wrapped; + // Invoke a custom `isEqual` method if one is provided. + if (a.isEqual && _.isFunction(a.isEqual)) return a.isEqual(b); + if (b.isEqual && _.isFunction(b.isEqual)) return b.isEqual(a); + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className != toString.call(b)) return false; + switch (className) { + // Strings, numbers, dates, and booleans are compared by value. + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return a == String(b); + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for + // other numeric values. + return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b); + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a == +b; + // RegExps are compared by their source patterns and flags. + case '[object RegExp]': + return a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase; + } + if (typeof a != 'object' || typeof b != 'object') return false; + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + var length = stack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (stack[length] == a) return true; + } + // Add the first object to the stack of traversed objects. + stack.push(a); + var size = 0, result = true; + // Recursively compare objects and arrays. + if (className == '[object Array]') { + // Compare array lengths to determine if a deep comparison is necessary. + size = a.length; + result = size == b.length; + if (result) { + // Deep compare the contents, ignoring non-numeric properties. + while (size--) { + // Ensure commutative equality for sparse arrays. + if (!(result = size in a == size in b && eq(a[size], b[size], stack))) break; + } + } + } else { + // Objects with different constructors are not equivalent. + if ('constructor' in a != 'constructor' in b || a.constructor != b.constructor) return false; + // Deep compare objects. + for (var key in a) { + if (_.has(a, key)) { + // Count the expected number of properties. + size++; + // Deep compare each member. + if (!(result = _.has(b, key) && eq(a[key], b[key], stack))) break; + } + } + // Ensure that both objects contain the same number of properties. + if (result) { + for (key in b) { + if (_.has(b, key) && !(size--)) break; + } + result = !size; + } + } + // Remove the first object from the stack of traversed objects. + stack.pop(); + return result; + } + + // Perform a deep comparison to check if two objects are equal. + _.isEqual = function(a, b) { + return eq(a, b, []); + }; + + // Is a given array, string, or object empty? + // An "empty" object has no enumerable own-properties. + _.isEmpty = function(obj) { + if (_.isArray(obj) || _.isString(obj)) return obj.length === 0; + for (var key in obj) if (_.has(obj, key)) return false; + return true; + }; + + // Is a given value a DOM element? + _.isElement = function(obj) { + return !!(obj && obj.nodeType == 1); + }; + + // Is a given value an array? + // Delegates to ECMA5's native Array.isArray + _.isArray = nativeIsArray || function(obj) { + return toString.call(obj) == '[object Array]'; + }; + + // Is a given variable an object? + _.isObject = function(obj) { + return obj === Object(obj); + }; + + // Is a given variable an arguments object? + _.isArguments = function(obj) { + return toString.call(obj) == '[object Arguments]'; + }; + if (!_.isArguments(arguments)) { + _.isArguments = function(obj) { + return !!(obj && _.has(obj, 'callee')); + }; + } + + // Is a given value a function? + _.isFunction = function(obj) { + return toString.call(obj) == '[object Function]'; + }; + + // Is a given value a string? + _.isString = function(obj) { + return toString.call(obj) == '[object String]'; + }; + + // Is a given value a number? + _.isNumber = function(obj) { + return toString.call(obj) == '[object Number]'; + }; + + // Is the given value `NaN`? + _.isNaN = function(obj) { + // `NaN` is the only value for which `===` is not reflexive. + return obj !== obj; + }; + + // Is a given value a boolean? + _.isBoolean = function(obj) { + return obj === true || obj === false || toString.call(obj) == '[object Boolean]'; + }; + + // Is a given value a date? + _.isDate = function(obj) { + return toString.call(obj) == '[object Date]'; + }; + + // Is the given value a regular expression? + _.isRegExp = function(obj) { + return toString.call(obj) == '[object RegExp]'; + }; + + // Is a given value equal to null? + _.isNull = function(obj) { + return obj === null; + }; + + // Is a given variable undefined? + _.isUndefined = function(obj) { + return obj === void 0; + }; + + // Has own property? + _.has = function(obj, key) { + return hasOwnProperty.call(obj, key); + }; + + // Utility Functions + // ----------------- + + // Run Underscore.js in *noConflict* mode, returning the `_` variable to its + // previous owner. Returns a reference to the Underscore object. + _.noConflict = function() { + root._ = previousUnderscore; + return this; + }; + + // Keep the identity function around for default iterators. + _.identity = function(value) { + return value; + }; + + // Run a function **n** times. + _.times = function (n, iterator, context) { + for (var i = 0; i < n; i++) iterator.call(context, i); + }; + + // Escape a string for HTML interpolation. + _.escape = function(string) { + return (''+string).replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g,'/'); + }; + + // Add your own custom functions to the Underscore object, ensuring that + // they're correctly added to the OOP wrapper as well. + _.mixin = function(obj) { + each(_.functions(obj), function(name){ + addToWrapper(name, _[name] = obj[name]); + }); + }; + + // Generate a unique integer id (unique within the entire client session). + // Useful for temporary DOM ids. + var idCounter = 0; + _.uniqueId = function(prefix) { + var id = idCounter++; + return prefix ? prefix + id : id; + }; + + // By default, Underscore uses ERB-style template delimiters, change the + // following template settings to use alternative delimiters. + _.templateSettings = { + evaluate : /<%([\s\S]+?)%>/g, + interpolate : /<%=([\s\S]+?)%>/g, + escape : /<%-([\s\S]+?)%>/g + }; + + // When customizing `templateSettings`, if you don't want to define an + // interpolation, evaluation or escaping regex, we need one that is + // guaranteed not to match. + var noMatch = /.^/; + + // Within an interpolation, evaluation, or escaping, remove HTML escaping + // that had been previously added. + var unescape = function(code) { + return code.replace(/\\\\/g, '\\').replace(/\\'/g, "'"); + }; + + // JavaScript micro-templating, similar to John Resig's implementation. + // Underscore templating handles arbitrary delimiters, preserves whitespace, + // and correctly escapes quotes within interpolated code. + _.template = function(str, data) { + var c = _.templateSettings; + var tmpl = 'var __p=[],print=function(){__p.push.apply(__p,arguments);};' + + 'with(obj||{}){__p.push(\'' + + str.replace(/\\/g, '\\\\') + .replace(/'/g, "\\'") + .replace(c.escape || noMatch, function(match, code) { + return "',_.escape(" + unescape(code) + "),'"; + }) + .replace(c.interpolate || noMatch, function(match, code) { + return "'," + unescape(code) + ",'"; + }) + .replace(c.evaluate || noMatch, function(match, code) { + return "');" + unescape(code).replace(/[\r\n\t]/g, ' ') + ";__p.push('"; + }) + .replace(/\r/g, '\\r') + .replace(/\n/g, '\\n') + .replace(/\t/g, '\\t') + + "');}return __p.join('');"; + var func = new Function('obj', '_', tmpl); + if (data) return func(data, _); + return function(data) { + return func.call(this, data, _); + }; + }; + + // Add a "chain" function, which will delegate to the wrapper. + _.chain = function(obj) { + return _(obj).chain(); + }; + + // The OOP Wrapper + // --------------- + + // If Underscore is called as a function, it returns a wrapped object that + // can be used OO-style. This wrapper holds altered versions of all the + // underscore functions. Wrapped objects may be chained. + var wrapper = function(obj) { this._wrapped = obj; }; + + // Expose `wrapper.prototype` as `_.prototype` + _.prototype = wrapper.prototype; + + // Helper function to continue chaining intermediate results. + var result = function(obj, chain) { + return chain ? _(obj).chain() : obj; + }; + + // A method to easily add functions to the OOP wrapper. + var addToWrapper = function(name, func) { + wrapper.prototype[name] = function() { + var args = slice.call(arguments); + unshift.call(args, this._wrapped); + return result(func.apply(_, args), this._chain); + }; + }; + + // Add all of the Underscore functions to the wrapper object. + _.mixin(_); + + // Add all mutator Array functions to the wrapper. + each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + var wrapped = this._wrapped; + method.apply(wrapped, arguments); + var length = wrapped.length; + if ((name == 'shift' || name == 'splice') && length === 0) delete wrapped[0]; + return result(wrapped, this._chain); + }; + }); + + // Add all accessor Array functions to the wrapper. + each(['concat', 'join', 'slice'], function(name) { + var method = ArrayProto[name]; + wrapper.prototype[name] = function() { + return result(method.apply(this._wrapped, arguments), this._chain); + }; + }); + + // Start chaining a wrapped Underscore object. + wrapper.prototype.chain = function() { + this._chain = true; + return this; + }; + + // Extracts the result from a wrapped and chained object. + wrapper.prototype.value = function() { + return this._wrapped; + }; + +}).call(this); diff --git a/cloudcms/static/cloudcms/less/resources.less b/cloudcms/static/cloudcms/less/resources.less new file mode 100644 index 0000000..90e194d --- /dev/null +++ b/cloudcms/static/cloudcms/less/resources.less @@ -0,0 +1,127 @@ +@resCol: #ff5d00; +@resCol2: #4085A6; + +.resources { + + .categories { + ul { .clearfix() } + ul li { float: left; } + .title { + margin-bottom: @verticalSpacing/2; + } + + ul li a { + text-decoration: none; + color: #000; + margin-right: @gridGutterWidth; + + &:hover, &.selected { + color: #000 !important; + } + + &.inactive { + opacity: 0.4; + } + } + } + + .list { + + font-size: 0.9em; + line-height: 1em; + margin-top: 4*@verticalSpacing; + position: relative; + + .resource-wrapper.first .resource { margin-left: 0; } + .resource-wrapper { + position: relative; + width: 200px; + margin-left: @gridGutterWidth; + margin-bottom: @gridGutterWidth; + &.first { margin-left: 0 } + &.hidden { display: none } + width: @gridColumnWidth*4 + 11; + float: left; + overflow: hidden; + height: 17*@verticalSpacing; + } + + .resource { + border: 1px solid #000; + .border-box(); + padding: 2*@verticalSpacing; + height: 17*@verticalSpacing; + overflow: hidden; + + .date { + color: @gray; + margin-bottom: 3px; + } + + .description { + font-size: 1.1em; + position: absolute; + height: 210px; + .transit(top, 0.35s); + top: -210px; + width: 100%; + margin-left: -2*@verticalSpacing; + padding: 2*@verticalSpacing; + .border-box(); + color: #fff; + } + + .title { + line-height: 1.4em; + } + + .category { + margin-top: 2*@verticalSpacing; + color: @gray; + a { color: @gray } + } + .download { + a { + display: block; + color: @black; + text-decoration: none; + padding: 5px; + padding-left: @verticalSpacing; + + &:hover, .hovered { + color: @resCol; + .download-image { + background-image: url("../images/resource_down_arrow-active.png"); + } + } + + .download-image { + display: block; + width: 30px; + height: 30px; + float: left; + margin-top: -7px; + margin-right: 10px; + background-image: url("../images/resource_down_arrow.png"); + background-position: 50% 50%; + background-repeat: no-repeat; + } + } + bottom: 0; + position: absolute; + font-size: 1.1em; + width: 100%; + text-align: middle; + .border-box(); + cursor: pointer; + img { margin-right: 10px; vertical-align: middle} + } + + &:hover, .hover { + .description { top:0; display: block } + } + } + } + +} + diff --git a/cloudcms/static/cloudcms/less/styles.less b/cloudcms/static/cloudcms/less/styles.less index e49a3bb..3289d94 100644 --- a/cloudcms/static/cloudcms/less/styles.less +++ b/cloudcms/static/cloudcms/less/styles.less @@ -3,6 +3,7 @@ @import "../less/tables.less"; @import "../less/xtra.less"; @import "../less/colorbox.less"; +@import "../less/resources.less"; // mixins @@ -551,7 +552,15 @@ div.form-stacked { &.success { background-color: @green; color: @white } &.error { background-color: @red; color: @white } - &.warning { background-color: @yellow; color: @black } + &.warning { background-color: #AF6906; color: @black } + } + + .warning { + color: @white !important; + a { + color: inherit; + font-weight: bold; + } } } @@ -756,45 +765,6 @@ table { display: none; } -/*resources styles*/ - -@resCol: #FAAF40; -.resources { - - .categories { - ul { .clearfix() } - ul li { float: left; } - .title { - margin-bottom: @verticalSpacing/2; - } - - ul li a { - text-decoration: none; - color: @resCol; - margin-right: @gridGutterWidth; - } - } - - .list { - - margin-top: 4*@verticalSpacing; - - .resource { - .border-box(); - width: 33%; - padding: 2*@verticalSpacing; - float: left; - border: 1px solid @resCol; - height: 12*@verticalSpacing; - - .description { - display: none; - } - } - } - -} - /* recaptcha */ #recaptcha_widget_div { @@ -806,6 +776,10 @@ table { margin-bottom: 10px; display: block !important; } + + th, td { + line-height: 1; + } } .checkbox-widget.checked { diff --git a/cloudcms/static/cloudcms/less/xtra.less b/cloudcms/static/cloudcms/less/xtra.less index 26ed822..d586d1e 100644 --- a/cloudcms/static/cloudcms/less/xtra.less +++ b/cloudcms/static/cloudcms/less/xtra.less @@ -24,6 +24,26 @@ &:hover { background-color: @linkColor; } + + &.back { + text-decoration: none; + bottom: 0; + float: right; + &.right { right: 0} + z-index: 500; + } +} + +.buttons-list { + z-index: 300; + position: relative; + .button { + margin-left: 10px; + } + + &.fixpos { + margin-top: -42px; + } } // specific styles for A buttons @@ -39,8 +59,9 @@ a.button { } -.transit(@type:color, @time:.15s, @easing:linear) { +.transit(@type:color, @time:.15s, @easing:ease-in-out) { -webkit-transition: @type @time @easing; + -moz-transition: @type @time @easing; transition: @type @time @easing; } diff --git a/cloudcms/synnefo_settings.py b/cloudcms/synnefo_settings.py index fbf2a73..66a7e9e 100644 --- a/cloudcms/synnefo_settings.py +++ b/cloudcms/synnefo_settings.py @@ -35,7 +35,7 @@ cloudcms_apps = [ 'cloudcms', 'cloudcmsblog', - #'cloudcmsfiles', + 'cloudcmsresources', 'pagination', 'django.contrib.auth', @@ -63,6 +63,7 @@ cloudcms_middlewares = [ ] cloudcms_staticfiles = { 'cloudcms': '', + 'cloudcmsresources': '', 'feincms': '', 'django.contrib.admin': ('media', 'admin_media'), } diff --git a/cloudcms/templates/cms/base.html b/cloudcms/templates/cms/base.html index 1210aeb..5a4d125 100644 --- a/cloudcms/templates/cms/base.html +++ b/cloudcms/templates/cms/base.html @@ -42,6 +42,7 @@ {% block headjs %} + @@ -65,12 +66,17 @@ {% block endhead %}{% endblock endhead %} + + {% if APP.extra_styles %} {% endif %} - + diff --git a/cloudcms/templates/content/template/resources.html b/cloudcms/templates/content/template/resources.html deleted file mode 100644 index 75b83b6..0000000 --- a/cloudcms/templates/content/template/resources.html +++ /dev/null @@ -1,76 +0,0 @@ -
- - - -
-
-
- -
01.02.12
-
Internal techincal presentation on okeanos at - GRNET
-
filed under PRESENTATION
-
-
-

In the early days of computing, programs were serial, that is, a - program consisted of a sequence of instructions, where each - instruction executed one after the other. It ran from start to - finish on a single processor.

-
-
- - DOWNLOAD PDF -
-
- -
-
- -
01.02.12
-
Internal techincal presentation on okeanos at - GRNET
-
filed under PRESENTATION
-
-
-

In the early days of computing, programs were serial, that is, a - program consisted of a sequence of instructions, where each - instruction executed one after the other. It ran from start to - finish on a single processor.

-
-
- - DOWNLOAD PDF -
-
- -
-
- -
01.02.12
-
Internal techincal presentation on okeanos at - GRNET
-
filed under PRESENTATION
-
-
-

In the early days of computing, programs were serial, that is, a - program consisted of a sequence of instructions, where each - instruction executed one after the other. It ran from start to - finish on a single processor.

-
-
- - DOWNLOAD PDF -
-
-
-
diff --git a/cloudcmsresources/__init__.py b/cloudcmsresources/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cloudcmsresources/admin.py b/cloudcmsresources/admin.py new file mode 100644 index 0000000..e3603c2 --- /dev/null +++ b/cloudcmsresources/admin.py @@ -0,0 +1,34 @@ +from django.contrib import admin +from django.utils.translation import ugettext_lazy as _ +from cloudcmsresources.models import ResourceCategory, \ + ResourceCategoryTranslation, Resource, ResourceTranslation +from feincms.translations import admin_translationinline, short_language_code +from feincms.admin import item_editor + +CategoryTranslationInline = admin_translationinline(ResourceCategoryTranslation, + prepopulated_fields={'slug': ('title',)}) +ResourceTranslationInline = admin_translationinline(ResourceTranslation, + prepopulated_fields={'slug': ('title',)}) + +class ResourceCategoryAdmin(admin.ModelAdmin): + inlines = [CategoryTranslationInline] + list_display = ['__unicode__', 'entries'] + search_fields = ['translations__title'] + + def entries(self, obj): + if 'translations' in getattr(ResourceCategory, '_feincms_extensions', ()): + return ResourceCategory.objects.filter(translations=obj, language=short_language_code()).count() + return ResourceCategory.objects.filter(translations=obj) + + entries.short_description = _('Blog entries in category') + +class ResourceAdmin(admin.ModelAdmin): + inlines = [ResourceTranslationInline] + list_display = ['__unicode__', 'category', 'is_published', 'published_on'] + list_editable = ['published_on'] + raw_id_fields = ['media_file'] + + +admin.site.register(Resource, ResourceAdmin) +admin.site.register(ResourceCategory, ResourceCategoryAdmin) + diff --git a/cloudcmsresources/migrations/0001_initial.py b/cloudcmsresources/migrations/0001_initial.py new file mode 100644 index 0000000..a674035 --- /dev/null +++ b/cloudcmsresources/migrations/0001_initial.py @@ -0,0 +1,60 @@ +# encoding: 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 model 'ResourceCategory' + db.create_table('cloudcmsresources_resourcecategory', ( + ('ordering', self.gf('django.db.models.fields.SmallIntegerField')(default=0)), + ('color', self.gf('django.db.models.fields.CharField')(default='#FAAF40', max_length=255)), + ('display_on_menu', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + )) + db.send_create_signal('cloudcmsresources', ['ResourceCategory']) + + # Adding model 'ResourceCategoryTranslation' + db.create_table('cloudcmsresources_resourcecategorytranslation', ( + ('description', self.gf('django.db.models.fields.CharField')(max_length=250, blank=True)), + ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', to=orm['cloudcmsresources.ResourceCategory'])), + ('title', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('language_code', self.gf('django.db.models.fields.CharField')(default='en', max_length=10)), + ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, db_index=True)), + )) + db.send_create_signal('cloudcmsresources', ['ResourceCategoryTranslation']) + + + def backwards(self, orm): + + # Deleting model 'ResourceCategory' + db.delete_table('cloudcmsresources_resourcecategory') + + # Deleting model 'ResourceCategoryTranslation' + db.delete_table('cloudcmsresources_resourcecategorytranslation') + + + models = { + 'cloudcmsresources.resourcecategory': { + 'Meta': {'object_name': 'ResourceCategory'}, + 'color': ('django.db.models.fields.CharField', [], {'default': "'#FAAF40'", 'max_length': '255'}), + 'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategorytranslation': { + 'Meta': {'object_name': 'ResourceCategoryTranslation'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['cloudcmsresources'] diff --git a/cloudcmsresources/migrations/0002_auto__add_resourcetranslation__add_resource.py b/cloudcmsresources/migrations/0002_auto__add_resourcetranslation__add_resource.py new file mode 100644 index 0000000..3a60c4a --- /dev/null +++ b/cloudcmsresources/migrations/0002_auto__add_resourcetranslation__add_resource.py @@ -0,0 +1,95 @@ +# encoding: 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 model 'ResourceTranslation' + db.create_table('cloudcmsresources_resourcetranslation', ( + ('description', self.gf('django.db.models.fields.CharField')(max_length=250, blank=True)), + ('parent', self.gf('django.db.models.fields.related.ForeignKey')(related_name='translations', to=orm['cloudcmsresources.Resource'])), + ('title', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('language_code', self.gf('django.db.models.fields.CharField')(default='en', max_length=10)), + ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50, db_index=True)), + )) + db.send_create_signal('cloudcmsresources', ['ResourceTranslation']) + + # Adding model 'Resource' + db.create_table('cloudcmsresources_resource', ( + ('ordering', self.gf('django.db.models.fields.SmallIntegerField')(default=0)), + ('category', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['cloudcmsresources.ResourceCategory'])), + ('filetype', self.gf('django.db.models.fields.CharField')(default='PDF', max_length=255, null=True, blank=True)), + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('media_file', self.gf('feincms.module.medialibrary.fields.MediaFileForeignKey')(to=orm['medialibrary.MediaFile'])), + )) + db.send_create_signal('cloudcmsresources', ['Resource']) + + + def backwards(self, orm): + + # Deleting model 'ResourceTranslation' + db.delete_table('cloudcmsresources_resourcetranslation') + + # Deleting model 'Resource' + db.delete_table('cloudcmsresources_resource') + + + models = { + 'cloudcmsresources.resource': { + 'Meta': {'object_name': 'Resource'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'filetype': ('django.db.models.fields.CharField', [], {'default': "'PDF'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'media_file': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategory': { + 'Meta': {'object_name': 'ResourceCategory'}, + 'color': ('django.db.models.fields.CharField', [], {'default': "'#FAAF40'", 'max_length': '255'}), + 'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategorytranslation': { + 'Meta': {'object_name': 'ResourceCategoryTranslation'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'cloudcmsresources.resourcetranslation': { + 'Meta': {'object_name': 'ResourceTranslation'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.Resource']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'medialibrary.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'medialibrary.mediafile': { + 'Meta': {'object_name': 'MediaFile'}, + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), + 'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) + } + } + + complete_apps = ['cloudcmsresources'] diff --git a/cloudcmsresources/migrations/0003_auto__chg_field_resourcecategorytranslation_description.py b/cloudcmsresources/migrations/0003_auto__chg_field_resourcecategorytranslation_description.py new file mode 100644 index 0000000..6b58117 --- /dev/null +++ b/cloudcmsresources/migrations/0003_auto__chg_field_resourcecategorytranslation_description.py @@ -0,0 +1,74 @@ +# encoding: 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): + + # Changing field 'ResourceCategoryTranslation.description' + db.alter_column('cloudcmsresources_resourcecategorytranslation', 'description', self.gf('django.db.models.fields.TextField')(max_length=250, blank=True)) + + + def backwards(self, orm): + + # Changing field 'ResourceCategoryTranslation.description' + db.alter_column('cloudcmsresources_resourcecategorytranslation', 'description', self.gf('django.db.models.fields.CharField')(max_length=250, blank=True)) + + + models = { + 'cloudcmsresources.resource': { + 'Meta': {'object_name': 'Resource'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'filetype': ('django.db.models.fields.CharField', [], {'default': "'PDF'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'media_file': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategory': { + 'Meta': {'object_name': 'ResourceCategory'}, + 'color': ('django.db.models.fields.CharField', [], {'default': "'#FAAF40'", 'max_length': '255'}), + 'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategorytranslation': { + 'Meta': {'object_name': 'ResourceCategoryTranslation'}, + 'description': ('django.db.models.fields.TextField', [], {'max_length': '250', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'cloudcmsresources.resourcetranslation': { + 'Meta': {'object_name': 'ResourceTranslation'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.Resource']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'medialibrary.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'medialibrary.mediafile': { + 'Meta': {'object_name': 'MediaFile'}, + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), + 'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) + } + } + + complete_apps = ['cloudcmsresources'] diff --git a/cloudcmsresources/migrations/0004_auto__chg_field_resourcecategorytranslation_description.py b/cloudcmsresources/migrations/0004_auto__chg_field_resourcecategorytranslation_description.py new file mode 100644 index 0000000..251fa3f --- /dev/null +++ b/cloudcmsresources/migrations/0004_auto__chg_field_resourcecategorytranslation_description.py @@ -0,0 +1,74 @@ +# encoding: 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): + + # Changing field 'ResourceCategoryTranslation.description' + db.alter_column('cloudcmsresources_resourcecategorytranslation', 'description', self.gf('django.db.models.fields.TextField')(blank=True)) + + + def backwards(self, orm): + + # Changing field 'ResourceCategoryTranslation.description' + db.alter_column('cloudcmsresources_resourcecategorytranslation', 'description', self.gf('django.db.models.fields.TextField')(max_length=250, blank=True)) + + + models = { + 'cloudcmsresources.resource': { + 'Meta': {'object_name': 'Resource'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'filetype': ('django.db.models.fields.CharField', [], {'default': "'PDF'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'media_file': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategory': { + 'Meta': {'object_name': 'ResourceCategory'}, + 'color': ('django.db.models.fields.CharField', [], {'default': "'#FAAF40'", 'max_length': '255'}), + 'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategorytranslation': { + 'Meta': {'object_name': 'ResourceCategoryTranslation'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'cloudcmsresources.resourcetranslation': { + 'Meta': {'object_name': 'ResourceTranslation'}, + 'description': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.Resource']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'medialibrary.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'medialibrary.mediafile': { + 'Meta': {'object_name': 'MediaFile'}, + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), + 'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) + } + } + + complete_apps = ['cloudcmsresources'] diff --git a/cloudcmsresources/migrations/0005_auto__chg_field_resourcetranslation_description.py b/cloudcmsresources/migrations/0005_auto__chg_field_resourcetranslation_description.py new file mode 100644 index 0000000..2c7c198 --- /dev/null +++ b/cloudcmsresources/migrations/0005_auto__chg_field_resourcetranslation_description.py @@ -0,0 +1,74 @@ +# encoding: 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): + + # Changing field 'ResourceTranslation.description' + db.alter_column('cloudcmsresources_resourcetranslation', 'description', self.gf('django.db.models.fields.TextField')(blank=True)) + + + def backwards(self, orm): + + # Changing field 'ResourceTranslation.description' + db.alter_column('cloudcmsresources_resourcetranslation', 'description', self.gf('django.db.models.fields.CharField')(max_length=250, blank=True)) + + + models = { + 'cloudcmsresources.resource': { + 'Meta': {'object_name': 'Resource'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'filetype': ('django.db.models.fields.CharField', [], {'default': "'PDF'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'media_file': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategory': { + 'Meta': {'object_name': 'ResourceCategory'}, + 'color': ('django.db.models.fields.CharField', [], {'default': "'#FAAF40'", 'max_length': '255'}), + 'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategorytranslation': { + 'Meta': {'object_name': 'ResourceCategoryTranslation'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'cloudcmsresources.resourcetranslation': { + 'Meta': {'object_name': 'ResourceTranslation'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.Resource']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'medialibrary.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'medialibrary.mediafile': { + 'Meta': {'object_name': 'MediaFile'}, + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), + 'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) + } + } + + complete_apps = ['cloudcmsresources'] diff --git a/cloudcmsresources/migrations/0006_auto__add_field_resource_published_on__add_field_resource_is_published.py b/cloudcmsresources/migrations/0006_auto__add_field_resource_published_on__add_field_resource_is_published.py new file mode 100644 index 0000000..273e153 --- /dev/null +++ b/cloudcmsresources/migrations/0006_auto__add_field_resource_published_on__add_field_resource_is_published.py @@ -0,0 +1,82 @@ +# encoding: 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 'Resource.published_on' + db.add_column('cloudcmsresources_resource', 'published_on', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now), keep_default=False) + + # Adding field 'Resource.is_published' + db.add_column('cloudcmsresources_resource', 'is_published', self.gf('django.db.models.fields.BooleanField')(default=True, blank=True), keep_default=False) + + + def backwards(self, orm): + + # Deleting field 'Resource.published_on' + db.delete_column('cloudcmsresources_resource', 'published_on') + + # Deleting field 'Resource.is_published' + db.delete_column('cloudcmsresources_resource', 'is_published') + + + models = { + 'cloudcmsresources.resource': { + 'Meta': {'object_name': 'Resource'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'filetype': ('django.db.models.fields.CharField', [], {'default': "'PDF'", 'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_published': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'media_file': ('feincms.module.medialibrary.fields.MediaFileForeignKey', [], {'to': "orm['medialibrary.MediaFile']"}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}), + 'published_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}) + }, + 'cloudcmsresources.resourcecategory': { + 'Meta': {'object_name': 'ResourceCategory'}, + 'color': ('django.db.models.fields.CharField', [], {'default': "'#FAAF40'", 'max_length': '255'}), + 'display_on_menu': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'ordering': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}) + }, + 'cloudcmsresources.resourcecategorytranslation': { + 'Meta': {'object_name': 'ResourceCategoryTranslation'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.ResourceCategory']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'cloudcmsresources.resourcetranslation': { + 'Meta': {'object_name': 'ResourceTranslation'}, + 'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'language_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '10'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'translations'", 'to': "orm['cloudcmsresources.Resource']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'medialibrary.category': { + 'Meta': {'object_name': 'Category'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['medialibrary.Category']"}), + 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '150', 'db_index': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'medialibrary.mediafile': { + 'Meta': {'object_name': 'MediaFile'}, + 'categories': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['medialibrary.Category']", 'null': 'True', 'blank': 'True'}), + 'copyright': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}), + 'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'file': ('django.db.models.fields.files.FileField', [], {'max_length': '255'}), + 'file_size': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '12'}) + } + } + + complete_apps = ['cloudcmsresources'] diff --git a/cloudcmsresources/migrations/__init__.py b/cloudcmsresources/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cloudcmsresources/models.py b/cloudcmsresources/models.py new file mode 100644 index 0000000..a668047 --- /dev/null +++ b/cloudcmsresources/models.py @@ -0,0 +1,176 @@ +from datetime import datetime + +from django.db import models +from django.conf import settings +from django.contrib.auth.models import User +from django.utils.translation import ugettext_lazy as _, ugettext, ungettext +from django.template.loader import render_to_string +from django.core import urlresolvers +from django import forms + +from feincms import translations +from feincms.models import Base +from feincms.module.page.models import Page +from feincms.content.richtext.models import RichTextContent +from feincms.content.section.models import SectionContent +from feincms.content.application.models import reverse +from feincms.module.medialibrary.fields import MediaFileForeignKey +from feincms.module.medialibrary.models import MediaFile +from feincms.module.page.extensions.navigation import NavigationExtension +from feincms.module.page.extensions.navigation import PagePretender +from feincms.content.application.models import ApplicationContent + +from cloudcms.models import Application +from cloudcms.cms_utils import get_app_page + +from feincms import translations +from feincms.models import Base +from feincms.module.page.models import Page +from feincms.content.richtext.models import RichTextContent +from feincms.content.section.models import SectionContent +from feincms.content.application.models import reverse +from feincms.module.medialibrary.fields import MediaFileForeignKey +from feincms.module.medialibrary.models import MediaFile +from feincms.module.page.extensions.navigation import NavigationExtension +from feincms.module.page.extensions.navigation import PagePretender +from feincms.content.application.models import ApplicationContent + +from cloudcms.models import Application +from cloudcms.cms_utils import get_app_page + +# monkeypatch django reverse (feincms 1.5+ solves this issue) +urlresolvers.reverse = reverse + + +class ResourceCategory(models.Model, translations.TranslatedObjectMixin): + ordering = models.SmallIntegerField(_('ordering'), default=0) + display_on_menu = models.BooleanField(default=True) + color = models.CharField(max_length=255, default="#FAAF40") + + class Meta: + verbose_name = _('Resource category') + verbose_name_plural = _('Resource categories') + ordering = ['-ordering',] + + objects = translations.TranslatedObjectManager() + + def get_css_class(self): + return "resource-cat-%d" % self.pk + + def get_css_def(self): + return """ + .%(cls)s.resource { border-color: %(color)s !important;} + .%(cls)s.resource .title { color: %(color)s !important;} + .%(cls)s.resource .description { background-color: %(color)s !important;} + .%(cls)s.filter-item a { color: %(color)s !important;} + """ % dict(cls=self.get_css_class(), color=self.get_color()) + + def get_color(self): + return "#" + self.color.lstrip("#") + + def __unicode__(self): + trans = translations.TranslatedObjectMixin.__unicode__(self) + return trans or _('Unnamed resource category') + + +class ResourceCategoryTranslation(translations.Translation(ResourceCategory)): + """ + Category translation + """ + title = models.CharField(_('category title'), max_length=100) + slug = models.SlugField(_('slug'), unique=True) + description = models.TextField(_('description'), blank=True) + + class Meta: + verbose_name = _('Resource category translation') + verbose_name_plural = _('Resource category translations') + ordering = ['title'] + + def __unicode__(self): + return self.title + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + + super(ResourceCategoryTranslation, self).save(*args, **kwargs) + + +class Resource(models.Model, translations.TranslatedObjectMixin): + is_published = models.BooleanField(default=True) + published_on = models.DateTimeField(default=datetime.now) + + ordering = models.SmallIntegerField(_('ordering'), default=0) + category = models.ForeignKey(ResourceCategory) + media_file = MediaFileForeignKey(MediaFile, null=False, blank=False) + filetype = models.CharField(max_length=255, null=True, blank=True, + default="PDF") + + class Meta: + verbose_name = _('Resource') + verbose_name_plural = _('Resources') + ordering = ['-ordering',] + + objects = translations.TranslatedObjectManager() + + def __unicode__(self): + trans = translations.TranslatedObjectMixin.__unicode__(self) + return trans or _('Unnamed resource') + + def get_filetype(self): + return self.filetype + + def get_html_id(self): + return "resource-obj-%d" % self.pk + + +class ResourceTranslation(translations.Translation(Resource)): + """ + Category translation + """ + title = models.CharField(_('resource title'), max_length=100) + slug = models.SlugField(_('slug'), unique=True) + description = models.TextField(_('description'), blank=True) + + class Meta: + verbose_name = _('Resource translation') + verbose_name_plural = _('Resource translations') + ordering = ['title'] + + def __unicode__(self): + return self.title + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = slugify(self.title) + + super(ResourceTranslation, self).save(*args, **kwargs) + + + + +# Feincms content abstract models +class ResourcesList(models.Model): + filter_title = models.CharField(max_length=255) + + class Meta: + abstract = True + verbose_name = _('Resources list') + verbose_name_plural = _('Resources lists') + + @property + def media(self): + return forms.Media(js=( + settings.MEDIA_URL + 'cloudcmsresources/js/resources_list.js', + )) + + def render(self, **kwargs): + resources = Resource.objects.filter(published_on__lte=datetime.now(), + is_published=True).order_by('-published_on') + + categories = ResourceCategory.objects.filter(display_on_menu=True) + + context = {'resources': resources, 'categories': categories, + 'content': self, 'MEDIA_URL': settings.MEDIA_URL} + return render_to_string(['content/resources_list.html'], context) + diff --git a/cloudcmsresources/static/cloudcmsresources/js/resources_list.js b/cloudcmsresources/static/cloudcmsresources/js/resources_list.js new file mode 100644 index 0000000..15fc672 --- /dev/null +++ b/cloudcmsresources/static/cloudcmsresources/js/resources_list.js @@ -0,0 +1,111 @@ +// Array Remove - By John Resig (MIT Licensed) +Array.prototype.remove = function(from, to) { + var rest = this.slice((to || from) + 1 || this.length); + this.length = from < 0 ? this.length + from : from; + return this.push.apply(this, rest); +}; + +function ResourcesModule(el, conf) { + + var defaults = {'page_limit': 5}; + this.conf = $.extend(defaults, conf); + + this.el = el; + + this.selected_category = window.location.hash.replace("#",""); + if (!this.selected_category) { this.selected_category = undefined }; + + this.categories = this.el.find(".categories ul li"); + this.orig_categories = this.categories.clone(); + + //this.update_page_objects(); + + this.grid_height = 251; + this.grid_width = 251; + this.grid_gap = 22; + + var self = this; + $(window).bind('hashchange', function() { + //self.selected_category = window.location.hash.substring(1); + //self.update_page_objects(); + }) +} + +ResourcesModule.prototype.switch = function(hide, show) { + var hide = $(hide), show = $(show); + var toparent = hide.parent(); + var newshow = show.clone(); + toparent.append(newshow); + hide.animate({top:"-249px"}) + newshow.animate({ + top:"-249px" + }, + { + complete:function(){ + console.log("complete"); + hide.remove(); + newshow.css({top:0}); + } + }) +} + + +ResourcesModule.prototype.resources = function() { + this._resources = this.el.find(".resource-wrapper"); + return this._resources; +} + +ResourcesModule.prototype.hide = function(q) { + q.fadeOut(300); +} + +ResourcesModule.prototype.animate_els = function(els) { + $(el).css({ position:'absolute' }); + var left = i % 3 == 0 ? 0 : (i % 3) * (self.grid_width) + ((i % 3)-1) * self.grid_gap; + + var row = Math.floor(i/3); + var top = row * (self.grid_gap + self.grid_height); + + $(el).animate({left: left}, { complete: function(){ + $(el).animate({top: top}, {complete: function(){ + + self.el.height((self.grid_height + self.grid_gap) * (Math.floor(to_show.length/3) + 1)); + + }}); + }}); + $(el).removeClass("first"); + + if (i % 3 == 0) { + $(el).addClass("first"); + } + $(el).removeClass("hidden"); + $(el).show(); +} + +ResourcesModule.prototype.update_page_objects = function() { + var to_show = this.resources().filter("[data-category="+this.selected_category+"]"); + var to_hide = this.resources().filter("[data-category!="+this.selected_category+"]"); + + if (!this.selected_category) { to_show = this.resources(); } + _.each(to_hide, function(el){ + $(el).fadeOut(100); + }); + + var delay = this.selected_category ? 40 : 0; + var self = this; + window.setTimeout(function(){ + _.each(to_show, function(el, i) { + var new_main_height = (self.grid_height + self.grid_gap) * (Math.floor(to_show.length/3) + 1); + if (self.el.height() < new_main_height) { + self.el.height(new_main_height); + } + }) + self.animate_els(to_show); + }, delay) +} + +$(document).ready(function(){ + var rm = new ResourcesModule($("#resources-list"), {}, []); + window.rm = rm; +}) + diff --git a/cloudcmsresources/templates/content/resources_list.html b/cloudcmsresources/templates/content/resources_list.html new file mode 100644 index 0000000..a17a388 --- /dev/null +++ b/cloudcmsresources/templates/content/resources_list.html @@ -0,0 +1,55 @@ +{% load i18n %} +
+ + + +
+

{{ content.filter_title }}

+ +
+ +
+ {% for r in resources %} +
+
+
+ +
{{ r.published_on|date:"d.m.Y" }}
+
{{ r.translation.title }}
+
{% trans "filed under" %} {{ r.category.translation.title }}
+
+
+

{{ r.translation.description }}

+
+ +
+
+ {% endfor %} +
+
+ + +
+ diff --git a/cloudcmsresources/urls.py b/cloudcmsresources/urls.py new file mode 100644 index 0000000..e69de29 diff --git a/cloudcmsresources/views.py b/cloudcmsresources/views.py new file mode 100644 index 0000000..e69de29 -- 1.7.10.4