Skip to content

Commit

Permalink
Use metaclass to add images and links to blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Sebastian Vetter committed Nov 28, 2013
1 parent 5f889bd commit a84a837
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 28 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@ install:
- npm -g install less@1.3.3 phantomjs
script:
- py.test --pep8 --cov fancypages
- py.test -m 'integration'
after_success:
- coveralls
44 changes: 44 additions & 0 deletions fancypages/models/blocks/base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _

from ...assets.fields import AssetKey


class MultiImageMeta(models.base.ModelBase):

def __init__(cls, name, bases, nmspc):
super(MultiImageMeta, cls).__init__(name, bases, nmspc)
if hasattr(cls, 'num_images'):
cls.add_image_fields()

def add_image_fields(cls):
if not getattr(cls, 'image_field_name', None):
cls.image_field_name = "image_%d"

for idx in range(1, cls.num_images + 1):
cls.add_to_class(
cls.image_field_name % idx,
AssetKey('assets.ImageAsset', verbose_name=_("Image %d" % idx),
related_name="+", blank=True, null=True))


class MultiLinkMeta(models.base.ModelBase):

def __init__(cls, name, bases, nmspc):
super(MultiLinkMeta, cls).__init__(name, bases, nmspc)
if hasattr(cls, 'num_links'):
cls.add_link_fields()

def add_link_fields(cls):
if not getattr(cls, 'link_field_name', None):
cls.link_field_name = "link_url_%d"

for idx in range(1, cls.num_links + 1):
cls.add_to_class(
cls.link_field_name % idx,
models.CharField(_("Link URL %d" % idx), max_length=500,
blank=True, null=True))


class MultiImageLinkMeta(MultiImageMeta, MultiLinkMeta):
pass
30 changes: 4 additions & 26 deletions fancypages/models/blocks/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django.utils.translation import ugettext_lazy as _

from ... import abstract_models
from .base import MultiImageLinkMeta
from ...assets.fields import AssetKey
from ..mixins import ImageMetadataMixin
from ...library import register_content_block
Expand Down Expand Up @@ -103,12 +104,12 @@ class Meta:

@register_content_block
class CarouselBlock(ContentBlock):
__metaclass__ = MultiImageLinkMeta

name = _("Image carousel")
code = 'carousel'
group = _("Content")
num_images = 10
image_field_name = "image_%d"
link_field_name = "link_url_%d"
num_images = num_links = 10
template_name = "fancypages/blocks/carouselblock.html"

def get_images_and_links(self):
Expand All @@ -135,29 +136,6 @@ class Meta:
app_label = 'fancypages'


# generate the image field for the CarouselBlock dynamically
# because I am lazy ;)
for idx in range(1, CarouselBlock.num_images + 1):
CarouselBlock.add_to_class(
CarouselBlock.image_field_name % idx,
AssetKey(
'assets.ImageAsset',
verbose_name=_("Image %d" % idx),
related_name="+",
blank=True,
null=True,
)
)
CarouselBlock.add_to_class(
CarouselBlock.link_field_name % idx,
models.CharField(
_("Link URL %d" % idx),
max_length=500,
blank=True, null=True
)
)


@register_content_block
class PageNavigationBlock(ContentBlock):
name = _("Page Navigation")
Expand Down
18 changes: 17 additions & 1 deletion fancypages/test/testcases.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import os
import mock

from purl import URL

from django.conf import settings
from django.test import LiveServerTestCase
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django import VERSION as DJANGO_VERSION
from django.core.management import call_command
from django.db import connections, DEFAULT_DB_ALIAS
from django.test import TestCase, LiveServerTestCase

from splinter import Browser

Expand All @@ -20,6 +22,20 @@
)


class BlockTestCase(TestCase):

def setUp(self):
super(BlockTestCase, self).setUp()
self.user = factories.UserFactory.build()

self.request_context = RequestContext(mock.MagicMock())
self.request_context['user'] = self.user

def get_rendered_block(self, block):
renderer = block.get_renderer_class()(block, self.request_context)
return renderer.render()


class SplinterTestCase(LiveServerTestCase):
username = 'peter.griffin'
email = 'peter@griffin.com'
Expand Down
23 changes: 23 additions & 0 deletions fancypages/tests/unit/blocks/test_carousel_block.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from django.db.models import get_model
from fancypages.test.testcases import BlockTestCase

CarouselBlock = get_model('fancypages', 'CarouselBlock')


class TestCarouselBlock(BlockTestCase):
model = CarouselBlock
assert_in_html = "flexslider"

def test_has_10_image_attributes(self):
carousel = CarouselBlock()
for idx in range(1, 11):
self.assertTrue(hasattr(carousel, carousel.image_field_name % idx))

def test_has_10_link_attributes(self):
carousel = CarouselBlock()
for idx in range(1, 11):
self.assertTrue(hasattr(carousel, carousel.link_field_name % idx))

def test_can_be_rendered_in_template(self):
html = self.get_rendered_block(CarouselBlock())
self.assertIn('flexslider', html)
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[pytest]
addopts = -m 'not integration'
addopts= -m 'not integration'
pep8ignore=
conftest.py ALL

Expand Down

0 comments on commit a84a837

Please sign in to comment.