From 7efeefb050fb4b02f16dc96bd7b8f0de999ef58d Mon Sep 17 00:00:00 2001 From: Nate Thelen Date: Fri, 9 Sep 2011 13:19:37 -0700 Subject: [PATCH 01/13] Added I18N and Django Sites support --- .gitignore | 6 ++++ flatblocks/admin.py | 2 +- .../management/commands/createflatblock.py | 23 ++++++++++--- .../management/commands/deleteflatblock.py | 23 ++++++++++--- flatblocks/models.py | 11 +++++-- flatblocks/settings.py | 1 + flatblocks/templates/flatblocks/edit.html | 1 + flatblocks/templatetags/flatblock_tags.py | 18 +++++++++-- flatblocks/tests.py | 32 ++++++++++--------- flatblocks/views.py | 3 +- test_project/settings.py | 4 ++- test_project/templates/index.html | 2 +- 12 files changed, 91 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index 623c994..9bc53d3 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,9 @@ local_settings.py django_flatblocks.egg-info dist build +.project +.pydevproject +/parts/* +/eggs/* +/bin/* +/develop-eggs/* \ No newline at end of file diff --git a/flatblocks/admin.py b/flatblocks/admin.py index 32660cf..ea53c56 100644 --- a/flatblocks/admin.py +++ b/flatblocks/admin.py @@ -3,7 +3,7 @@ class FlatBlockAdmin(admin.ModelAdmin): ordering = ['slug',] - list_display = ('slug', 'header') + 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/models.py b/flatblocks/models.py index 2780cb4..2045b4e 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,22 +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) + 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, default=Site.objects.get_current().id, blank=True, null=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..4f1cc61 100644 --- a/flatblocks/settings.py +++ b/flatblocks/settings.py @@ -1,5 +1,6 @@ from django.conf import settings +LANGUAGE_CODE = 'en-us' 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/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 6b353e0..a8c0afb 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -45,6 +45,7 @@ from django.template import loader from django.db import models from django.core.cache import cache +from django.contrib.sites.models import Site from flatblocks import settings @@ -132,6 +133,7 @@ def __init__(self, slug, is_variable, cache_time=0, with_template=True, self.is_variable = is_variable self.cache_time = cache_time self.with_template = with_template + self.lang_code = template.Variable('LANGUAGE_CODE') def render(self, context): if self.is_variable: @@ -149,9 +151,18 @@ def render(self, context): new_ctx.update(context) try: flatblock = None + + try: + lang = self.lang_code.resolve(context) + except template.VariableDoesNotExist: + logger.error('no LANGUAGE_CODE variable found in context, to enable you must use the RequestContext context or via: {% load i18n %}{% get_current_language as LANGUAGE_CODE %}') + return 'flatblocks error, see log' + 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 @@ -159,12 +170,13 @@ def render(self, context): # This behaviour 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) + flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang, site=site) 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..bae8384 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,7 @@ def setUp(self): self.testblock = FlatBlock.objects.create( slug='block', header='HEADER', - content='CONTENT' + content='CONTENT', ) self.admin = User.objects.create_superuser('admin', 'admin@localhost', 'adminpwd') @@ -33,9 +35,9 @@ def testCacheReset(self): """ Tests if FlatBlock.save() resets the cache. """ - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 60 %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% 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' @@ -60,11 +62,11 @@ def setUp(self): def testLoadingTaglib(self): """Tests if the taglib defined in this app can be loaded""" - tpl = template.Template('{% load flatblock_tags %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}') tpl.render(template.Context({})) def testExistingPlain(self): - tpl = template.Template('{% load flatblock_tags %}{% plain_flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% plain_flatblock "block" %}') self.assertEqual(u'CONTENT', tpl.render(template.Context({})).strip()) def testExistingTemplate(self): @@ -75,26 +77,26 @@ def testExistingTemplate(self):
CONTENT
""" - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" %}') self.assertEqual(expected, tpl.render(template.Context({}))) def testUsingMissingTemplate(self): - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" using "missing_template.html" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" using "missing_template.html" %}') exception = template.TemplateSyntaxError self.assertRaises(exception, tpl.render, template.Context({})) def testSyntax(self): - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" %}') tpl.render(template.Context({})) - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 123 %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" 123 %}') tpl.render(template.Context({})) - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" using "flatblocks/flatblock.html" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" using "flatblocks/flatblock.html" %}') tpl.render(template.Context({})) - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 123 using "flatblocks/flatblock.html" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" 123 using "flatblocks/flatblock.html" %}') tpl.render(template.Context({})) def testBlockAsVariable(self): - tpl = template.Template('{% load flatblock_tags %}{% flatblock blockvar %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock blockvar %}') tpl.render(template.Context({'blockvar': 'block'})) @@ -108,7 +110,7 @@ def testMissingStaticBlock(self):
foo
""" settings.AUTOCREATE_STATIC_BLOCKS = True - tpl = template.Template('{% load flatblock_tags %}{% flatblock "foo" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "foo" %}') self.assertEqual(expected, tpl.render(template.Context({})).strip()) self.assertEqual(FlatBlock.objects.count(), 1) self.assertEqual(expected, tpl.render(template.Context({})).strip()) @@ -118,14 +120,14 @@ def testNotAutocreatedMissingStaticBlock(self): """Tests if a missing block with hardcoded name won't be auto-created if feature is disabled""" expected = u"" settings.AUTOCREATE_STATIC_BLOCKS = False - tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" %}') self.assertEqual(expected, tpl.render(template.Context({})).strip()) self.assertEqual(FlatBlock.objects.filter(slug='block').count(), 0) def testMissingVariableBlock(self): settings.AUTOCREATE_STATIC_BLOCKS = True """Tests if a missing block with variable name will simply return an empty string""" - tpl = template.Template('{% load flatblock_tags %}{% flatblock name %}') + tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock name %}') self.assertEqual('', tpl.render(template.Context({'name': 'foo'})).strip()) diff --git a/flatblocks/views.py b/flatblocks/views.py index 62782e7..d6fecc8 100644 --- a/flatblocks/views.py +++ b/flatblocks/views.py @@ -54,7 +54,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 c2647c7..a49a995 100644 --- a/test_project/settings.py +++ b/test_project/settings.py @@ -16,10 +16,12 @@ 'django.contrib.admin', 'django.contrib.contenttypes', 'django.contrib.sessions', + 'django.contrib.sites', 'flatblocks', ) -LANGUAGE_CODE="en" +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..bbcdbc0 100644 --- a/test_project/templates/index.html +++ b/test_project/templates/index.html @@ -1,4 +1,4 @@ -{% load flatblock_tags %} +{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %} From b72711f7217fe430546a5c05799b1bdc29eb1e55 Mon Sep 17 00:00:00 2001 From: Nate Thelen Date: Thu, 15 Sep 2011 13:10:57 -0700 Subject: [PATCH 02/13] Cleaned up admin Fixed error happening when app is part of project during first syncdb Added required values to test project --- .gitignore | 6 +++++- flatblocks/admin.py | 11 +++++++++++ flatblocks/models.py | 2 +- test_project/settings.py | 10 +++++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 9bc53d3..fbef9e0 100644 --- a/.gitignore +++ b/.gitignore @@ -13,4 +13,8 @@ build /parts/* /eggs/* /bin/* -/develop-eggs/* \ No newline at end of file +/develop-eggs/* +/bin +/parts +/eggs +/develop-eggs diff --git a/flatblocks/admin.py b/flatblocks/admin.py index ea53c56..fa329cd 100644 --- a/flatblocks/admin.py +++ b/flatblocks/admin.py @@ -1,7 +1,18 @@ +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): + form = FlatBlockForm ordering = ['slug',] list_display = ('slug', 'header', 'lang_code', 'site') search_fields = ('slug', 'header', 'content') diff --git a/flatblocks/models.py b/flatblocks/models.py index 2045b4e..fbe6b5e 100644 --- a/flatblocks/models.py +++ b/flatblocks/models.py @@ -21,7 +21,7 @@ class FlatBlock(models.Model): help_text=_("An optional header for this content")) 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, default=Site.objects.get_current().id, blank=True, null=True, verbose_name=_('site')) + site = models.ForeignKey(Site, blank=True, null=True, verbose_name=_('site')) def __unicode__(self): return u"%s, %s, %s" % (self.slug,str(self.site),self.lang_code) diff --git a/test_project/settings.py b/test_project/settings.py index a49a995..55b48a1 100644 --- a/test_project/settings.py +++ b/test_project/settings.py @@ -11,6 +11,9 @@ TEMPLATE_DEBUG=True DATABASE_ENGINE = 'sqlite3' DATABASE_NAME = '/tmp/flatblocks.db' +MIDDLEWARE_CLASSES = ( + 'django.middleware.locale.LocaleMiddleware', +) INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.admin', @@ -19,7 +22,12 @@ 'django.contrib.sites', 'flatblocks', ) -LANGUAGE_CODE = 'en-us' +LANGUAGES = ( + ('en', 'English'), + ('de', 'German'), + ('es', 'Spanish'), +) +LANGUAGE_CODE = 'en' TEMPLATE_DIRS = ( os.path.join(PROJECT_ROOT, 'templates'), ) From d42018908ab8b2f5ee526eea4c30a12f2369afa1 Mon Sep 17 00:00:00 2001 From: Nate Thelen Date: Mon, 19 Sep 2011 12:07:16 -0700 Subject: [PATCH 03/13] Walked through upgrade path and ensured all errors made sense. Added additional errors where needed --- flatblocks/models.py | 2 +- flatblocks/settings.py | 3 ++- flatblocks/templatetags/flatblock_tags.py | 16 ++++++++++------ test_project/templates/index.html | 2 +- test_project/views.py | 4 ++-- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/flatblocks/models.py b/flatblocks/models.py index fbe6b5e..87c2899 100644 --- a/flatblocks/models.py +++ b/flatblocks/models.py @@ -21,7 +21,7 @@ class FlatBlock(models.Model): help_text=_("An optional header for this content")) 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, blank=True, null=True, verbose_name=_('site')) + site = models.ForeignKey(Site, blank=True, verbose_name=_('site')) def __unicode__(self): return u"%s, %s, %s" % (self.slug,str(self.site),self.lang_code) diff --git a/flatblocks/settings.py b/flatblocks/settings.py index 4f1cc61..55e8c37 100644 --- a/flatblocks/settings.py +++ b/flatblocks/settings.py @@ -1,6 +1,7 @@ from django.conf import settings -LANGUAGE_CODE = 'en-us' +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/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index a8c0afb..551d9a9 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -151,12 +151,16 @@ def render(self, context): new_ctx.update(context) try: flatblock = None + lang = settings.LANGUAGE_CODE - try: - lang = self.lang_code.resolve(context) - except template.VariableDoesNotExist: - logger.error('no LANGUAGE_CODE variable found in context, to enable you must use the RequestContext context or via: {% load i18n %}{% get_current_language as LANGUAGE_CODE %}') - return 'flatblocks error, see log' + if 'django.middleware.locale.LocaleMiddleware' not in settings.MIDDLEWARE_CLASSES: + logger.warning("For i18L support in flatblocks you must have django.middleware.locale.LocaleMiddleware in your MIDDLEWARE_CLASSES") + else: + try: + lang = self.lang_code.resolve(context) + except template.VariableDoesNotExist: + raise Exception('no LANGUAGE_CODE variable found in context. For i18l support in flatblocks you must use the RequestContext context or add this to the top of your templates: {% load i18n %}{% get_current_language as LANGUAGE_CODE %}') + site = Site.objects.get_current() # Django caches get_current() cache_key = '%s%s_%s_%s' % (settings.CACHE_PREFIX, real_slug, lang, str(site)) @@ -167,7 +171,7 @@ def render(self, context): # 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, lang_code=lang, site=site) diff --git a/test_project/templates/index.html b/test_project/templates/index.html index bbcdbc0..05813ee 100644 --- a/test_project/templates/index.html +++ b/test_project/templates/index.html @@ -1,4 +1,4 @@ -{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %} +{% load flatblock_tags %} 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)) From 7844711b174f56381342f0b47bcb1f2d4be3b78f Mon Sep 17 00:00:00 2001 From: Nate Thelen Date: Wed, 28 Sep 2011 12:18:35 -0700 Subject: [PATCH 04/13] Fixed some bugs that was causing the tests to fail --- flatblocks/templatetags/flatblock_tags.py | 6 +++--- flatblocks/tests.py | 4 +++- test_project/settings.py | 7 +++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 551d9a9..32012bc 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -151,15 +151,15 @@ def render(self, context): new_ctx.update(context) try: flatblock = None - lang = settings.LANGUAGE_CODE + lang = settings.LANGUAGE_CODE if 'django.middleware.locale.LocaleMiddleware' not in settings.MIDDLEWARE_CLASSES: - logger.warning("For i18L support in flatblocks you must have django.middleware.locale.LocaleMiddleware in your MIDDLEWARE_CLASSES") + logger.warning("For i18n support in flatblocks you must have django.middleware.locale.LocaleMiddleware in your MIDDLEWARE_CLASSES") else: try: lang = self.lang_code.resolve(context) except template.VariableDoesNotExist: - raise Exception('no LANGUAGE_CODE variable found in context. For i18l support in flatblocks you must use the RequestContext context or add this to the top of your templates: {% load i18n %}{% get_current_language as LANGUAGE_CODE %}') + raise Exception('no LANGUAGE_CODE variable found in context. For i18n support in flatblocks you must use the RequestContext context or add this to the top of your templates: {% load i18n %}{% get_current_language as LANGUAGE_CODE %}') site = Site.objects.get_current() # Django caches get_current() cache_key = '%s%s_%s_%s' % (settings.CACHE_PREFIX, real_slug, lang, str(site)) diff --git a/flatblocks/tests.py b/flatblocks/tests.py index bae8384..d8267ba 100644 --- a/flatblocks/tests.py +++ b/flatblocks/tests.py @@ -18,6 +18,7 @@ def setUp(self): slug='block', header='HEADER', content='CONTENT', + site=Site.objects.get_current(), ) self.admin = User.objects.create_superuser('admin', 'admin@localhost', 'adminpwd') @@ -57,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/test_project/settings.py b/test_project/settings.py index 55b48a1..840ddfc 100644 --- a/test_project/settings.py +++ b/test_project/settings.py @@ -12,6 +12,9 @@ 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 = ( @@ -23,11 +26,11 @@ 'flatblocks', ) LANGUAGES = ( - ('en', 'English'), + ('en-us', 'English'), ('de', 'German'), ('es', 'Spanish'), ) -LANGUAGE_CODE = 'en' +LANGUAGE_CODE = 'en-us' TEMPLATE_DIRS = ( os.path.join(PROJECT_ROOT, 'templates'), ) From b23c9893990960dc2caae212ef9e0af3a4f7d54b Mon Sep 17 00:00:00 2001 From: Nate Thelen Date: Wed, 28 Sep 2011 13:10:47 -0700 Subject: [PATCH 05/13] Removed reliance on LANGUAGE_CODE being in the template. Added language selector to test project home. --- flatblocks/templatetags/flatblock_tags.py | 7 ++---- flatblocks/tests.py | 26 +++++++++++------------ test_project/templates/index.html | 18 ++++++++++++++++ test_project/urls.py | 1 + 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 32012bc..9e62046 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -46,6 +46,7 @@ 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 @@ -133,7 +134,6 @@ def __init__(self, slug, is_variable, cache_time=0, with_template=True, self.is_variable = is_variable self.cache_time = cache_time self.with_template = with_template - self.lang_code = template.Variable('LANGUAGE_CODE') def render(self, context): if self.is_variable: @@ -156,10 +156,7 @@ def render(self, context): 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: - try: - lang = self.lang_code.resolve(context) - except template.VariableDoesNotExist: - raise Exception('no LANGUAGE_CODE variable found in context. For i18n support in flatblocks you must use the RequestContext context or add this to the top of your templates: {% load i18n %}{% get_current_language as LANGUAGE_CODE %}') + 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)) diff --git a/flatblocks/tests.py b/flatblocks/tests.py index d8267ba..d880176 100644 --- a/flatblocks/tests.py +++ b/flatblocks/tests.py @@ -36,7 +36,7 @@ def testCacheReset(self): """ Tests if FlatBlock.save() resets the cache. """ - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" 60 %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 60 %}') tpl.render(template.Context({})) name = '%sblock_%s_%s' % (settings.CACHE_PREFIX,settings.LANGUAGE_CODE,str(Site.objects.get_current())) self.assertNotEquals(None, cache.get(name)) @@ -64,11 +64,11 @@ def setUp(self): def testLoadingTaglib(self): """Tests if the taglib defined in this app can be loaded""" - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}') + tpl = template.Template('{% load flatblock_tags %}') tpl.render(template.Context({})) def testExistingPlain(self): - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% plain_flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% plain_flatblock "block" %}') self.assertEqual(u'CONTENT', tpl.render(template.Context({})).strip()) def testExistingTemplate(self): @@ -79,26 +79,26 @@ def testExistingTemplate(self):
CONTENT
""" - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" %}') self.assertEqual(expected, tpl.render(template.Context({}))) def testUsingMissingTemplate(self): - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" using "missing_template.html" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" using "missing_template.html" %}') exception = template.TemplateSyntaxError self.assertRaises(exception, tpl.render, template.Context({})) def testSyntax(self): - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" %}') tpl.render(template.Context({})) - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" 123 %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 123 %}') tpl.render(template.Context({})) - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" using "flatblocks/flatblock.html" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" using "flatblocks/flatblock.html" %}') tpl.render(template.Context({})) - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" 123 using "flatblocks/flatblock.html" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" 123 using "flatblocks/flatblock.html" %}') tpl.render(template.Context({})) def testBlockAsVariable(self): - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock blockvar %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock blockvar %}') tpl.render(template.Context({'blockvar': 'block'})) @@ -112,7 +112,7 @@ def testMissingStaticBlock(self):
foo
""" settings.AUTOCREATE_STATIC_BLOCKS = True - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "foo" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "foo" %}') self.assertEqual(expected, tpl.render(template.Context({})).strip()) self.assertEqual(FlatBlock.objects.count(), 1) self.assertEqual(expected, tpl.render(template.Context({})).strip()) @@ -122,14 +122,14 @@ def testNotAutocreatedMissingStaticBlock(self): """Tests if a missing block with hardcoded name won't be auto-created if feature is disabled""" expected = u"" settings.AUTOCREATE_STATIC_BLOCKS = False - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock "block" %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock "block" %}') self.assertEqual(expected, tpl.render(template.Context({})).strip()) self.assertEqual(FlatBlock.objects.filter(slug='block').count(), 0) def testMissingVariableBlock(self): settings.AUTOCREATE_STATIC_BLOCKS = True """Tests if a missing block with variable name will simply return an empty string""" - tpl = template.Template('{% load flatblock_tags %}{% load i18n %}{% get_current_language as LANGUAGE_CODE %}{% flatblock name %}') + tpl = template.Template('{% load flatblock_tags %}{% flatblock name %}') self.assertEqual('', tpl.render(template.Context({'name': 'foo'})).strip()) 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), ) From 741d034c22df39ab6cfbc6c4980a918985e5b017 Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 16:35:14 -0800 Subject: [PATCH 06/13] changed flatblock template slightly --- flatblocks/templates/flatblocks/flatblock.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 From 8cebdd90f963b8999725ca574aec1fcd37b3f399 Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 16:38:08 -0800 Subject: [PATCH 07/13] made site nullable --- flatblocks/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flatblocks/models.py b/flatblocks/models.py index 87c2899..ba08baf 100644 --- a/flatblocks/models.py +++ b/flatblocks/models.py @@ -21,7 +21,7 @@ class FlatBlock(models.Model): help_text=_("An optional header for this content")) 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, blank=True, verbose_name=_('site')) + site = models.ForeignKey(Site, null=True, blank=True, verbose_name=_('site')) def __unicode__(self): return u"%s, %s, %s" % (self.slug,str(self.site),self.lang_code) From 7c9e4307c8edab3280cedb1010b463ba0996067b Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 16:43:03 -0800 Subject: [PATCH 08/13] added new contributors --- AUTHORS.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index b737658..820d1b0 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,4 @@ Contributions by * James O'Donnell * Mikhail Korobov * Henrik Heimbuerger - + * Gabe Harriman From 9c0dc27feecc950c9d328b5b415da325a79febdc Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 16:57:42 -0800 Subject: [PATCH 09/13] added authors and made site optional in flatblock tag --- AUTHORS.txt | 1 + flatblocks/templatetags/flatblock_tags.py | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 820d1b0..52c0e17 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -16,3 +16,4 @@ Contributions by * Mikhail Korobov * Henrik Heimbuerger * Gabe Harriman + \ No newline at end of file diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 9e62046..dd3bc9c 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -171,12 +171,21 @@ def render(self, context): # 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, lang_code=lang, site=site) + if site: + flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang, site=site) + else: + flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang) else: - flatblock, _ = FlatBlock.objects.get_or_create( - slug=real_slug, lang_code=lang, site=site, - defaults = {'content': real_slug} - ) + if site: + flatblock, _ = FlatBlock.objects.get_or_create( + slug=real_slug, lang_code=lang, site=site, + defaults = {'content': real_slug} + ) + else: + flatblock, _ = FlatBlock.objects.get_or_create( + slug=real_slug, lang_code=lang, + defaults = {'content': real_slug} + ) if self.cache_time != 0: if self.cache_time is None or self.cache_time == 'None': From e7a963169f3870dff4b2584e910060c24712b030 Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 17:00:37 -0800 Subject: [PATCH 10/13] bugfix --- flatblocks/templatetags/flatblock_tags.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index dd3bc9c..3fbb010 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -171,17 +171,15 @@ def render(self, context): # This behavior can be configured using the # FLATBLOCKS_AUTOCREATE_STATIC_BLOCKS setting if self.is_variable or not settings.AUTOCREATE_STATIC_BLOCKS: - if site: - flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang, site=site) - else: + flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang, site=site) + if not flatblock: flatblock = FlatBlock.objects.get(slug=real_slug, lang_code=lang) else: - if site: - flatblock, _ = FlatBlock.objects.get_or_create( - slug=real_slug, lang_code=lang, site=site, - defaults = {'content': real_slug} - ) - else: + flatblock, _ = FlatBlock.objects.get_or_create( + slug=real_slug, lang_code=lang, site=site, + defaults = {'content': real_slug} + ) + if not flatblock: flatblock, _ = FlatBlock.objects.get_or_create( slug=real_slug, lang_code=lang, defaults = {'content': real_slug} From 11fdda442c46a7ff379b8b2310f75fb8e2c87595 Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 17:01:01 -0800 Subject: [PATCH 11/13] bugfix --- flatblocks/templatetags/flatblock_tags.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 3fbb010..29a6a42 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -179,11 +179,6 @@ def render(self, context): slug=real_slug, lang_code=lang, site=site, defaults = {'content': real_slug} ) - if not flatblock: - flatblock, _ = FlatBlock.objects.get_or_create( - slug=real_slug, lang_code=lang, - defaults = {'content': real_slug} - ) if self.cache_time != 0: if self.cache_time is None or self.cache_time == 'None': From e5a76c65027059991d3d860b4ddccbf8d280c103 Mon Sep 17 00:00:00 2001 From: Gabriel Harriman Date: Mon, 19 Dec 2011 17:12:41 -0800 Subject: [PATCH 12/13] fallback to unsited flatblocks --- flatblocks/templatetags/flatblock_tags.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/flatblocks/templatetags/flatblock_tags.py b/flatblocks/templatetags/flatblock_tags.py index 29a6a42..6a52249 100644 --- a/flatblocks/templatetags/flatblock_tags.py +++ b/flatblocks/templatetags/flatblock_tags.py @@ -163,16 +163,20 @@ def render(self, context): if self.cache_time != 0: 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 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, lang_code=lang, site=site) - if not flatblock: + 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( From c408723a878139de97fefbccf3f5c984b2b749f2 Mon Sep 17 00:00:00 2001 From: Nate Thelen Date: Fri, 20 Apr 2012 11:13:03 -0700 Subject: [PATCH 13/13] Fixed problem when I merged from my upstream --- .../0003_auto__del_unique_flatblock_slug.py | 36 +++++++++++++++++++ flatblocks/models.py | 2 +- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 flatblocks/migrations/0003_auto__del_unique_flatblock_slug.py 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 b160ca5..365a147 100644 --- a/flatblocks/models.py +++ b/flatblocks/models.py @@ -13,7 +13,7 @@ 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,