+# Copyright 2012 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+# 1. Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the following
+# disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and
+# documentation are those of the authors and should not be
+# interpreted as representing official policies, either expressed
+# or implied, of GRNET S.A.
+
+
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 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 Category(models.Model, translations.TranslatedObjectMixin):
"""
objects = translations.TranslatedObjectManager()
+ def entries_count(self):
+ return self.blogentries.count()
+
def __unicode__(self):
trans = translations.TranslatedObjectMixin.__unicode__(self)
return trans or _('Unnamed category')
-
class CategoryTranslation(translations.Translation(Category)):
"""
Category translation
def __unicode__(self):
return self.title
- @models.permalink
def get_absolute_url(self):
- return ('cloudcmsblog_entries_archive', (), {
+ r = reverse('cloudcmsblog_entries_archive', 'cloudcmsblog.urls', (), {
'category': self.slug,
- })
+ })
+
+ # ugly hack to fix proper application reverse url
+ BLOG_URL = ""
+ try:
+ BLOG_URL = get_blog_page().get_navigation_url()
+ except Exception, e:
+ print e
+
+ if r.startswith(BLOG_URL):
+ return r
+ else:
+ return BLOG_URL + r.lstrip('/')
+
def save(self, *args, **kwargs):
if not self.slug:
def active(self):
return self.filter(is_active=True)
+ def latest(self, limit=3):
+ return self.filter()[:limit]
+
+
+def get_blog_page():
+ """
+ Returns Page model that has been associated with blog application
+ """
+ return get_app_page(Page, "cloudcmsblog")
+
class Entry(Base):
"""
Blog post entry
intro_text = models.TextField(max_length=255,
help_text="Displayed in list views", blank=True)
image = MediaFileForeignKey(MediaFile, null=True, blank=True)
- application = models.ManyToManyField(Application,
+ application = models.ManyToManyField('cloudcms.Application',
related_name="blogentries",
verbose_name=_('application'))
def __unicode__(self):
return self.title
- @models.permalink
def get_absolute_url(self):
- return ('cloudcmsblog_entry_detail', (), {
- 'year': self.published_on.strftime('%Y'),
- 'month': self.published_on.strftime('%m'),
- 'day': self.published_on.strftime('%d'),
- 'slug': self.slug,
- })
-
+ try:
+ r = reverse('cloudcmsblog_entry_detail', 'cloudcmsblog.urls', (),
+ {
+ 'year': self.published_on.strftime('%Y'),
+ 'month': self.published_on.strftime('%m'),
+ 'day': self.published_on.strftime('%d'),
+ 'slug': self.slug,
+ })
+ except Exception,e:
+ pass
+
+ # ugly hack to fix proper application reverse url
+ BLOG_URL = ""
+ try:
+ BLOG_URL = get_blog_page().get_navigation_url()
+ except Exception, e:
+ print e
+
+ if r.startswith(BLOG_URL):
+ return r
+ else:
+ return BLOG_URL + r.lstrip('/')
+
+ def back_url(self):
+ return get_blog_page().get_navigation_url()
# Feincms navigation extension
class BlogCategoriesNavigationExtension(NavigationExtension):
url=url,
lft=0,
rght=0,
+ level=page.level + 1, # blog categories are nested, assign correct level
slug=category.translation.slug,
)
+
+# Feincms content abstract models
+class LatestEntries(models.Model):
+ title = models.CharField(max_length=255)
+ limit = models.PositiveIntegerField(default=3)
+ display_text = models.BooleanField(default=False)
+
+ class Meta:
+ abstract = True
+ verbose_name = _('Latest blog entries')
+ verbose_name_plural = _('Latest blog entries')
+
+ def render(self, **kwargs):
+ return render_to_string(['content/latest_blog.html'], {'posts':
+ Entry.objects.latest(self.limit), 'content': self})
+