diff --git a/.gitignore b/.gitignore index 623c994..fc24078 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,14 @@ local_settings.py django_flatblocks.egg-info dist build +.project +.pydevproject +/parts/* +/eggs/* +/bin/* +/develop-eggs/* +/bin +/parts +/eggs +/develop-eggs +/.settings diff --git a/AUTHORS.txt b/AUTHORS.txt index b737658..52c0e17 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -6,6 +6,7 @@ Extended by * Peter Baumgardner * Kevin Fricovsky * Horst Gutmann + * Nate Thelen Contributions by @@ -14,4 +15,5 @@ Contributions by * James O'Donnell * Mikhail Korobov * Henrik Heimbuerger - + * Gabe Harriman + \ No newline at end of file diff --git a/flatblocks/admin.py b/flatblocks/admin.py index d54e68b..fa329cd 100644 --- a/flatblocks/admin.py +++ b/flatblocks/admin.py @@ -1,10 +1,20 @@ +from django import forms +from django.conf import settings from django.contrib import admin +from django.utils.translation import ugettext_lazy as _ + from flatblocks.models import FlatBlock + +class FlatBlockForm(forms.ModelForm): + lang_code = forms.ChoiceField(label=_("Language"), choices=settings.LANGUAGES) + class Meta: + model = FlatBlock class FlatBlockAdmin(admin.ModelAdmin): - ordering = ['slug', ] - list_display = ('slug', 'header') + form = FlatBlockForm + ordering = ['slug',] + list_display = ('slug', 'header', 'lang_code', 'site') search_fields = ('slug', 'header', 'content') admin.site.register(FlatBlock, FlatBlockAdmin) diff --git a/flatblocks/management/commands/createflatblock.py b/flatblocks/management/commands/createflatblock.py index 25d92a6..1bb2f94 100644 --- a/flatblocks/management/commands/createflatblock.py +++ b/flatblocks/management/commands/createflatblock.py @@ -1,19 +1,32 @@ from django.core.management import BaseCommand, CommandError from django.db import IntegrityError +from django.conf import settings +from django.contrib.sites.models import Site from flatblocks.models import FlatBlock class Command(BaseCommand): - help = "Create a new flatblock with the given slug" + help = "Create a new flatblock with the given slug and optional LANGUAGE_CODE and SITE_ID" def handle(self, *args, **options): - if len(args) != 1: - raise CommandError, "This command requires the slug of the new " \ - "flatblock as its first argument" + if len(args) == 0 or len(args) > 3: + raise CommandError, "arguments: slug [LANGUAGE_CODE] [SITE_ID]" + slug = args[0] + + if len(args) >= 2: + lang = args[1] + else: + lang = settings.LANGUAGE_CODE + + if len(args) >= 3: + site = Site.objects.get(id=args[2]) + else: + site = Site.objects.get_current() + block = FlatBlock(header="[%s]"%slug, content="Empty flatblock", - slug=slug) + slug=slug, lang_code=lang, site=site) try: block.save() except IntegrityError, e: diff --git a/flatblocks/management/commands/deleteflatblock.py b/flatblocks/management/commands/deleteflatblock.py index 732d4ee..1b377d4 100644 --- a/flatblocks/management/commands/deleteflatblock.py +++ b/flatblocks/management/commands/deleteflatblock.py @@ -1,18 +1,31 @@ from django.core.management import BaseCommand, CommandError +from django.conf import settings +from django.contrib.sites.models import Site from flatblocks.models import FlatBlock class Command(BaseCommand): - help = "Delete a flatblock with the given slug" + help = "Delete a flatblock with the given slug and optional LANGUAGE_CODE and SITE_ID" def handle(self, *args, **options): - if len(args) != 1: - raise CommandError, "This command requires the slug of the " \ - "flatblock as its first argument" + if len(args) == 0 or len(args) > 3: + raise CommandError, "arguments: slug [LANGUAGE_CODE] [SITE_ID]" + slug = args[0] + + if len(args) >= 2: + lang = args[1] + else: + lang = settings.LANGUAGE_CODE + + if len(args) >= 3: + site = Site.objects.get(id=args[2]) + else: + site = Site.objects.get_current() + try: - FlatBlock.objects.get(slug=slug).delete() + FlatBlock.objects.get(slug=slug, lang_code=lang, site=site).delete() except FlatBlock.DoesNotExist, e: raise CommandError, "The requested flatblock doesn't exist" diff --git a/flatblocks/migrations/0002_auto__add_field_flatblock_lang_code__add_field_flatblock_site__add_uni.py b/flatblocks/migrations/0002_auto__add_field_flatblock_lang_code__add_field_flatblock_site__add_uni.py new file mode 100644 index 0000000..eb57574 --- /dev/null +++ b/flatblocks/migrations/0002_auto__add_field_flatblock_lang_code__add_field_flatblock_site__add_uni.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'FlatBlock.lang_code' + db.add_column('flatblocks_flatblock', 'lang_code', + self.gf('django.db.models.fields.CharField')(default='en-us', max_length=5, blank=True), + keep_default=False) + + # Adding field 'FlatBlock.site' + db.add_column('flatblocks_flatblock', 'site', + self.gf('django.db.models.fields.related.ForeignKey')(to=orm['sites.Site'], null=True, blank=True), + keep_default=False) + + # Adding unique constraint on 'FlatBlock', fields ['lang_code', 'slug', 'site'] + db.create_unique('flatblocks_flatblock', ['lang_code', 'slug', 'site_id']) + + def backwards(self, orm): + # Removing unique constraint on 'FlatBlock', fields ['lang_code', 'slug', 'site'] + db.delete_unique('flatblocks_flatblock', ['lang_code', 'slug', 'site_id']) + + # Deleting field 'FlatBlock.lang_code' + db.delete_column('flatblocks_flatblock', 'lang_code') + + # Deleting field 'FlatBlock.site' + db.delete_column('flatblocks_flatblock', 'site_id') + + models = { + 'flatblocks.flatblock': { + 'Meta': {'unique_together': "(('slug', 'lang_code', 'site'),)", 'object_name': 'FlatBlock'}, + 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'header': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lang_code': ('django.db.models.fields.CharField', [], {'default': "'en-us'", 'max_length': '5', 'blank': 'True'}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']", 'null': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}) + }, + 'sites.site': { + 'Meta': {'ordering': "('domain',)", '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 = ['flatblocks'] \ No newline at end of file diff --git a/flatblocks/migrations/0003_auto__del_unique_flatblock_slug.py b/flatblocks/migrations/0003_auto__del_unique_flatblock_slug.py new file mode 100644 index 0000000..e9f4b7a --- /dev/null +++ b/flatblocks/migrations/0003_auto__del_unique_flatblock_slug.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Removing unique constraint on 'FlatBlock', fields ['slug'] + db.delete_unique('flatblocks_flatblock', ['slug']) + + def backwards(self, orm): + # Adding unique constraint on 'FlatBlock', fields ['slug'] + db.create_unique('flatblocks_flatblock', ['slug']) + + models = { + 'flatblocks.flatblock': { + 'Meta': {'unique_together': "(('slug', 'lang_code', 'site'),)", 'object_name': 'FlatBlock'}, + 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'header': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lang_code': ('django.db.models.fields.CharField', [], {'default': "'en'", 'max_length': '5', 'blank': 'True'}), + 'site': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['sites.Site']", 'null': 'True', 'blank': 'True'}), + 'slug': ('django.db.models.fields.CharField', [], {'max_length': '255'}) + }, + 'sites.site': { + 'Meta': {'ordering': "('domain',)", '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 = ['flatblocks'] \ No newline at end of file diff --git a/flatblocks/models.py b/flatblocks/models.py index a749308..365a147 100644 --- a/flatblocks/models.py +++ b/flatblocks/models.py @@ -1,6 +1,8 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from django.core.cache import cache +from django.contrib.sites.models import Site +from django.conf import settings from flatblocks.settings import CACHE_PREFIX @@ -11,23 +13,25 @@ class FlatBlock(models.Model): basically a piece of content with a given name (slug) and an optional title (header) which you can, for example, use in a sidebar of a website. """ - slug = models.CharField(max_length=255, unique=True, + slug = models.CharField(max_length=255, verbose_name=_('Slug'), help_text=_("A unique name used for reference in the templates")) header = models.CharField(blank=True, null=True, max_length=255, verbose_name=_('Header'), help_text=_("An optional header for this content")) - content = models.TextField(verbose_name=_('Content'), blank=True, - null=True) + content = models.TextField(verbose_name=_('Content'), blank=True, null=True) + lang_code = models.CharField(verbose_name=_(u"language"), help_text="Language code, if this chunk is translated. Same format as LANGUAGE_CODE setting, e.g. sv-se, or de-de, etc.", blank=True, max_length=5, default=settings.LANGUAGE_CODE) + site = models.ForeignKey(Site, null=True, blank=True, verbose_name=_('site')) def __unicode__(self): - return u"%s" % (self.slug,) - + return u"%s, %s, %s" % (self.slug,str(self.site),self.lang_code) + def save(self, *args, **kwargs): super(FlatBlock, self).save(*args, **kwargs) # Now also invalidate the cache used in the templatetag - cache.delete('%s%s' % (CACHE_PREFIX, self.slug, )) + cache.delete('%s%s_%s_%s' % (CACHE_PREFIX, self.slug, self.lang_code, str(self.site))) class Meta: verbose_name = _('Flat block') verbose_name_plural = _('Flat blocks') + unique_together = (('slug', 'lang_code', 'site'),) diff --git a/flatblocks/settings.py b/flatblocks/settings.py index 75f8a9e..55e8c37 100644 --- a/flatblocks/settings.py +++ b/flatblocks/settings.py @@ -1,5 +1,7 @@ from django.conf import settings +MIDDLEWARE_CLASSES = getattr(settings, 'MIDDLEWARE_CLASSES', {}) +LANGUAGE_CODE = getattr(settings, 'LANGUAGE_CODE', 'en') CACHE_PREFIX = getattr(settings, 'FLATBLOCKS_CACHE_PREFIX', 'flatblocks_') AUTOCREATE_STATIC_BLOCKS = getattr(settings, 'FLATBLOCKS_AUTOCREATE_STATIC_BLOCKS', False) diff --git a/flatblocks/templates/flatblocks/edit.html b/flatblocks/templates/flatblocks/edit.html index 52f4da5..7b33446 100644 --- a/flatblocks/templates/flatblocks/edit.html +++ b/flatblocks/templates/flatblocks/edit.html @@ -2,5 +2,6 @@

Edit "{{ flatblock.slug }}"

{{ form.as_p }} + {% csrf_token %}
diff --git a/flatblocks/templates/flatblocks/flatblock.html b/flatblocks/templates/flatblocks/flatblock.html index 82d8b58..87959c1 100644 --- a/flatblocks/templates/flatblocks/flatblock.html +++ b/flatblocks/templates/flatblocks/flatblock.html @@ -1,6 +1,6 @@
{% if flatblock.header %} -

{{ flatblock.header }}

+

{{ flatblock.header }}

{% endif %} -
{{ flatblock.content|safe }}
-
+ {{ flatblock.content|safe }} + \ No newline at end of file diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 6b353e0..6a52249 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -45,6 +45,8 @@ from django.template import loader from django.db import models from django.core.cache import cache +from django.contrib.sites.models import Site +from django.utils.translation import get_language from flatblocks import settings @@ -149,22 +151,39 @@ def render(self, context): new_ctx.update(context) try: flatblock = None + lang = settings.LANGUAGE_CODE + + if 'django.middleware.locale.LocaleMiddleware' not in settings.MIDDLEWARE_CLASSES: + logger.warning("For i18n support in flatblocks you must have django.middleware.locale.LocaleMiddleware in your MIDDLEWARE_CLASSES") + else: + lang = get_language() + + site = Site.objects.get_current() # Django caches get_current() + cache_key = '%s%s_%s_%s' % (settings.CACHE_PREFIX, real_slug, lang, str(site)) + if self.cache_time != 0: - cache_key = settings.CACHE_PREFIX + real_slug flatblock = cache.get(cache_key) + if flatblock is None: # if flatblock's slug is hard-coded in template then it is # safe and convenient to auto-create block if it doesn't exist. - # This behaviour can be configured using the + # This behavior can be configured using the # FLATBLOCKS_AUTOCREATE_STATIC_BLOCKS setting + if self.is_variable or not settings.AUTOCREATE_STATIC_BLOCKS: - flatblock = FlatBlock.objects.get(slug=real_slug) + try: + flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang, site=site) + + # this is a bit ugly, but it will allow us to fall back on un-sited flatblock + except: + flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang) else: flatblock, _ = FlatBlock.objects.get_or_create( - slug=real_slug, + slug=real_slug, lang_code=lang, site=site, defaults = {'content': real_slug} ) + if self.cache_time != 0: if self.cache_time is None or self.cache_time == 'None': logger.debug("Caching %s for the cache's default timeout" diff --git a/flatblocks/tests.py b/flatblocks/tests.py index b12b96f..d880176 100644 --- a/flatblocks/tests.py +++ b/flatblocks/tests.py @@ -3,6 +3,8 @@ from django.core.cache import cache from django.contrib.auth.models import User from django import db +from django.contrib.sites.models import Site + from flatblocks.models import FlatBlock from flatblocks import settings @@ -15,7 +17,8 @@ def setUp(self): self.testblock = FlatBlock.objects.create( slug='block', header='HEADER', - content='CONTENT' + content='CONTENT', + site=Site.objects.get_current(), ) self.admin = User.objects.create_superuser('admin', 'admin@localhost', 'adminpwd') @@ -35,7 +38,7 @@ def testCacheReset(self): """ tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 60 %}') tpl.render(template.Context({})) - name = '%sblock' % settings.CACHE_PREFIX + name = '%sblock_%s_%s' % (settings.CACHE_PREFIX,settings.LANGUAGE_CODE,str(Site.objects.get_current())) self.assertNotEquals(None, cache.get(name)) block = FlatBlock.objects.get(slug='block') block.header = 'UPDATED' @@ -55,7 +58,8 @@ def setUp(self): self.testblock = FlatBlock.objects.create( slug='block', header='HEADER', - content='CONTENT' + content='CONTENT', + site=Site.objects.get_current(), ) def testLoadingTaglib(self): diff --git a/flatblocks/views.py b/flatblocks/views.py index eda214e..73a8ab0 100644 --- a/flatblocks/views.py +++ b/flatblocks/views.py @@ -55,7 +55,8 @@ def my_perm_check(request, flatblock): instance = form.save(commit=False) instance.slug = flatblock.slug instance.save() - del request.session[session_key] + if session_key in request.session: + del request.session[session_key] redirect_to = success_url and success_url or origin return HttpResponseRedirect(redirect_to) else: diff --git a/test_project/settings.py b/test_project/settings.py index b0ffa33..a62ba33 100644 --- a/test_project/settings.py +++ b/test_project/settings.py @@ -11,16 +11,29 @@ TEMPLATE_DEBUG=True DATABASE_ENGINE = 'sqlite3' DATABASE_NAME = '/tmp/flatblocks.db' +MIDDLEWARE_CLASSES = ( + 'django.middleware.common.CommonMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.middleware.locale.LocaleMiddleware', +) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.admin', 'django.contrib.contenttypes', 'django.contrib.sessions', + 'django.contrib.sites', 'flatblocks', 'south' ) -LANGUAGE_CODE="en" +LANGUAGES = ( + ('en-us', 'English'), + ('de', 'German'), + ('es', 'Spanish'), +) +LANGUAGE_CODE = 'en-us' TEMPLATE_DIRS = ( os.path.join(PROJECT_ROOT, 'templates'), ) ROOT_URLCONF = 'test_project.urls' +SITE_ID=1 diff --git a/test_project/templates/index.html b/test_project/templates/index.html index 05813ee..d4bf4ae 100644 --- a/test_project/templates/index.html +++ b/test_project/templates/index.html @@ -5,8 +5,26 @@ Test page for flatblock rendering + test1:
{% flatblock 'test1' 0 %} +
+
+ test2:
{% flatblock 'test2' 10 %} +
+
+ test3:
{% flatblock 'test3' None %} +
+
+ +
+ + +
diff --git a/test_project/urls.py b/test_project/urls.py index cb8646f..557c88c 100644 --- a/test_project/urls.py +++ b/test_project/urls.py @@ -8,5 +8,6 @@ urlpatterns = patterns('', url('^flatblocks/', include("flatblocks.urls")), url('^admin/', include(admin.site.urls)), + url('^i18n/', include('django.conf.urls.i18n')), url('^/?', views.index), ) diff --git a/test_project/views.py b/test_project/views.py index 6ef873c..78405ca 100644 --- a/test_project/views.py +++ b/test_project/views.py @@ -1,5 +1,5 @@ from django.shortcuts import render_to_response - +from django.template import RequestContext def index(request): - return render_to_response('index.html') + return render_to_response('index.html', None, context_instance=RequestContext(request))