diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..551200814a66d2927861a63f4b5f52272a8a5ea8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+*.pyc
+django_newsbox.egg-info
+*~
+.tox
+tests/mydatabase
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000000000000000000000000000000000000..bf4584eda8aaf2be0cc09e5bc8b57cb1221a0b3f
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+* Webu (webu.coop) https://github.com/webu
+* Dylann CORDEL <d.cordel@webu.coop> https://github.com/dylannCordel
+* Olivier Le Brouster <o.lebrouster@webu.coop>
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..4c36e0a17a450a8a8083aed25fb9a25e0f22b887
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,25 @@
+.===================================================================.
+||                    Copyright (c) 2013, Webu                     ||
+||                Currently under Beerware License                 ||
+||                            ___                                  ||
+||                          .'   '.                                ||
+||                         /       \           oOoOo               ||
+||                        |         |       ,==|||||               ||
+||                         \       /       _|| |||||               ||
+||                          '.___.'    _.-'^|| |||||               ||
+||                        __/_______.-'     '==HHHHH               ||
+||                   _.-'` /                   """""               ||
+||                .-'     /   oOoOo                                ||
+||                `-._   / ,==|||||                                ||
+||                    '-/._|| |||||                                ||
+||                     /  ^|| |||||                                ||
+||                    /    '==HHHHH                                ||
+||                   /________"""""                                ||
+||                   `\       `\                                   ||
+||                     \        `\   /                             ||
+||                      \         `\/                              ||
+||                      /                                          ||
+||                     /                                           ||
+||               jgs  /_____                                       ||
+||                                                                 ||
+'==================================================================='
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000000000000000000000000000000000000..4d32fdfe2147b41762b52c45d0e2c241e06768ee
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,12 @@
+include AUTHORS
+include LICENSE
+include MANIFEST.in
+include README.md
+include ROADMAP.md
+include TESTING.md
+recursive-include tests *
+recursive-include test_requirements *
+recursive-include newsbox/templates *
+recursive-include newsbox/locale *
+recursive-include newsbox_cms/templates *
+recursive-include newsbox_cms/locale *
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..2c1169702a277f854cc2526dcc27ba435c53a56a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,51 @@
+# Django News Box
+
+This django app is a toolbox to easily setup news in your projects.
+
+## Features
+
+ * easy custom fields
+ * optional SEO fields
+ * optional publication period
+ * optional i18n support via hvad
+ * optional django-cms support
+
+## Installation
+
+## django CMS integration
+
+### models.py
+
+    class News(NewsboxCMSBase, NewsboxSEOBase):
+        
+        class Meta:
+            newsbox_detail_url_name = "news_detail"  # optional
+
+### cms_app.py
+
+    class NewsApphook(CMSApp):
+        name = _("News")
+        urls = ["myproject.news_urls"]
+    
+    apphook_pool.register(NewsApphook)
+    
+    
+### news_urls.py
+
+    from django.conf.urls import patterns, url
+    from newsbox.views import NewsboxDetailView
+    from .models import News
+    
+    urlpatterns = patterns(
+        '',
+        url(
+            r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[0-9a-zA-Z_-]+)/$', 
+            NewsboxDetailView.as_view(
+                template_name="myproject/news_detail.html",
+                model=News,),
+            name='news_detail'),
+    )
+
+### cms_plugin.py
+
+TODO
diff --git a/ROADMAP.md b/ROADMAP.md
new file mode 100644
index 0000000000000000000000000000000000000000..53a76513d9e174b5ccfc3834106f5129f4b9bf30
--- /dev/null
+++ b/ROADMAP.md
@@ -0,0 +1,51 @@
+# Feuile de route du développement de l'application
+
+## Classes abstraites
+
+* [OK] News "basiques"
+* [OK] News qui se périment dans le temps
+* [OK] News optimisée pour le SEO
+* [TODO] News avec auteur
+* [TODO] : internationnaliser les contenus utiles (hvad ?)
+
+## Gestion des droits
+
+[TODO]
+
+## Tests unitaires
+
+[TODO]
+
+## Interface d'administration pour gérer les actualités
+
+* lien directe pour publier / dépublier une news
+* [TODO] lien pour la gestion du multi langue comme pour les pages
+* [TODO] à voir si c'est possible : lien d'affichage sur le site ?
+
+## Template basique pour afficher la liste des news
+
+TODO
+
+## Template basique pour afficher le détail d'une news
+
+TODO
+
+## Intégration à Django-CMS
+
+### Plugin pour ajouter les news sur les pages
+
+TODO
+
+### Édition / ajout front-end des news
+
+TODO
+
+## Intégration des catégories
+
+TODO ? Utile de l'intégrer plutot que de le laisser 
+à la discrétion de l'utilisateur ?
+
+## Questions :
+
+* liaison avec l'objet Site ?
+* django-catégories ? à la discrétion de l'utilisateur ?
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000000000000000000000000000000000000..d5e228b8ababd3706569e96a938744bc4e04b46d
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,25 @@
+Testing newsbox and newsbox_cms
+=================================
+
+Testing in multiple environment
+-------------------------------
+
+It's the better way to test this application. You will test it with many 
+versions of Python, Django and Django CMS for newsbox_cms.
+
+## Requirements
+
+First, you need to install tox::
+
+    pip install "tox>=1.6,<1.8"
+
+
+
+Testing in your specific environnement
+--------------------------------------
+
+If you don't care about tests this app in other environnements than yours, you 
+can only execute runtests.sh from "tests" directory. Newsbox will be tested 
+with your versions of python, Django, installed python modules etc.
+It can be usefull if you run a very specific environnement which is not tested 
+with our tox configurations.
diff --git a/newsbox/__init__.py b/newsbox/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c06be72c87a445749cca3d92df4f87e3311f7dd
--- /dev/null
+++ b/newsbox/__init__.py
@@ -0,0 +1,3 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+__version__="0.1.0"
diff --git a/newsbox/admin.py b/newsbox/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..b76dc1f66075e57e9be7a0ae3ee84757ec5d5064
--- /dev/null
+++ b/newsbox/admin.py
@@ -0,0 +1,325 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import copy
+
+from django.conf.urls import url, patterns
+from django.contrib import messages, admin
+from django.contrib.admin.models import LogEntry, CHANGE
+from django.contrib.admin.templatetags.admin_static import static
+from django.contrib.contenttypes.models import ContentType
+from django.core.urlresolvers import reverse
+from django.http import HttpResponseForbidden, HttpResponseRedirect
+from django.shortcuts import get_object_or_404
+from django.utils.translation import ugettext_lazy as _,  ungettext_lazy
+from django.utils import six
+
+
+def get_fieldset_by_field(name, fieldsets):
+    """
+    Return fieldset containing a field given by name
+    """
+    for fieldset in fieldsets:
+        options = fieldset[1]
+        if name in options.get('fields', {}):
+            return fieldset
+    return None
+
+
+def remove_field_from_fieldsets(name, fieldsets, remove_empty_fieldset=True):
+    """
+    Remove a field from all fieldset in fieldsets.
+    """
+    while True:
+        fieldset = get_fieldset_by_field(name, fieldsets)
+        if fieldset:
+            fieldset[1]['fields'].remove(name)
+            if remove_empty_fieldset and len(fieldset[1]['fields']) == 0:
+                fieldsets.remove(fieldset)
+        else:
+            break
+
+
+def add_fields_to_fieldset(
+    fields,
+    fieldsets,
+    after_field=None,
+    same_fieldset_as=None,
+    default_fieldset_name=None,
+    default_fieldset_classes=None,
+    default_fieldset_position=None,
+    replace_existing_field=False,
+    remove_empty_fieldset=False,
+):
+    """
+    Add fields in a fieldsets attribute
+
+    Try to find a fieldset containing same_fieldset_as value in fields.  If not
+    found a new fieldset is created with name `default_fieldset_name`, position
+    `default_fieldset_position` and classes `default_fieldset_classes`.
+
+    Fields are inserted just after after_field. If not found, they are inserted
+    at the end.
+
+    If replace_existing_field is True, existing fields in fieldsets with same
+    name are removed.
+
+    """
+    if same_fieldset_as is None and after_field:
+        same_fieldset_as = after_field
+
+    # Find fieldset
+    fieldset = get_fieldset_by_field(same_fieldset_as, fieldsets)
+
+    if fieldset is None:
+        fieldset = (default_fieldset_name, {
+            'fields': [],
+            'classes': default_fieldset_classes,
+        })
+        allready_inserted = False
+    else:
+        allready_inserted = True
+
+    # Insert fields
+    index = None
+    if after_field:
+        index = fieldset[1]['fields'].index(after_field) + 1
+
+    index = index or len(fieldset[1]['fields'])
+    for field in fields:
+        if replace_existing_field:
+            remove_field_from_fieldsets(
+                field, fieldsets,
+                remove_empty_fieldset=remove_empty_fieldset)
+        elif get_fieldset_by_field(field, fieldsets) is not None:
+            continue
+
+        fieldset[1]['fields'].insert(index, field)
+        index += 1
+
+    # Insert fieldset if needed.
+    if not allready_inserted and len(fieldset[1]['fields']) > 0:
+        if default_fieldset_position is not None:
+            fieldsets.insert(default_fieldset_position, fieldset)
+        else:
+            fieldsets.append(fieldset)
+
+
+def changestatus_link(obj):
+    if obj.newsbox_published:
+        title = _('Unpublish this %s') % six.text_type(
+            obj._meta.verbose_name)
+        icon_url = static('admin/img/icon-yes.gif')
+    else:
+        title = _('Publish this %s') % six.text_type(
+            obj._meta.verbose_name)
+        icon_url = static('admin/img/icon-no.gif')
+    return '<a href="%s" title="%s"><img src="%s" alt="%s" /></a>' % (
+        reverse('admin:admin_newsbox_%s_change_status' % (
+                six.text_type(obj._meta.verbose_name)),
+                args=[obj.pk, ]),
+        title, icon_url, obj.newsbox_published)
+
+
+changestatus_link.allow_tags = True
+changestatus_link.admin_order_field = 'newsbox_published'
+changestatus_link.short_description = _('published')
+
+
+class NewsboxBaseAdmin(admin.ModelAdmin):
+
+    list_filter = ('newsbox_publication_start_date', 'newsbox_published', )
+    list_display = ['get_newsbox_title', 'newsbox_date',
+                    'get_newsbox_slug', changestatus_link]
+    list_display_links = ('get_newsbox_title',)
+    fieldsets = [
+        (None, {
+            'fields': ['newsbox_title', 'newsbox_slug', 'newsbox_date', 'newsbox_published', ], }),
+        (_('Content'), {
+            'fields': ['newsbox_summary', 'newsbox_body'], }), ]
+    actions = ['publish', 'unpublish']
+    save_as = True
+
+    def __init__(self, *args, **kwargs):
+        # This is a workaround for prepopulated_fields with hvad
+        self.prepopulated_fields = {"newsbox_slug": ("newsbox_title",)}
+        super(NewsboxBaseAdmin, self).__init__(*args, **kwargs)
+
+    def get_fieldsets(self, request, obj=None):
+        """
+        Prevent anoying modification of fieldsets class attribute.
+        """
+        fieldsets = super(NewsboxBaseAdmin, self).get_fieldsets(request, obj)
+        return copy.deepcopy(fieldsets)
+
+    def get_newsbox_title(self, obj):
+        return obj.newsbox_title
+    get_newsbox_title.short_description = _('Title')
+
+    def get_newsbox_slug(self, obj):
+        return obj.newsbox_slug
+    get_newsbox_slug.short_description = _('Slug')
+
+    def get_urls(self):
+        urls = super(NewsboxBaseAdmin, self).get_urls()
+        my_urls = patterns('', url(
+            r'^([0-9]+)/change-status/$',
+            self.admin_site.admin_view(self.change_status),
+            name='admin_newsbox_%s_change_status' % (
+                six.text_type(self.model._meta.verbose_name),)))
+        return my_urls + urls
+
+    def change_status(self, request, news_id):
+        """
+        Switch the status of a news
+        """
+
+        news = get_object_or_404(self.model, pk=news_id)
+        if not news.has_publish_permission(request):
+            return HttpResponseForbidden(
+                _('You do not have permission to publish this %s')
+                % (six.text_type(self.model._meta.verbose_name),))
+
+        news.newsbox_published = not news.newsbox_published
+        news.save()
+        if news.newsbox_published:
+            messages.info(
+                request,
+                _(
+                    'The %(objtype)s "%(objtitle)s" was '
+                    'successfully published'
+                ) % {
+                    'objtype': six.text_type(self.model._meta.verbose_name),
+                    'objtitle': news}
+            )
+        else:
+            messages.info(
+                request,
+                _(
+                    'The %(objtype)s "%(objtitle)s" was '
+                    'successfully unpublished'
+                ) % {
+                    'objtype': six.text_type(self.model._meta.verbose_name),
+                    'objtitle': news}
+            )
+        LogEntry.objects.log_action(
+            user_id=request.user.id,
+            content_type_id=ContentType.objects.get_for_model(self.model).pk,
+            object_id=news_id,
+            object_repr=six.text_type(news),
+            action_flag=CHANGE,
+        )
+        return HttpResponseRedirect('../../')
+
+    def publish(self, request, queryset):
+        """
+        Marks selected news items as published
+        """
+        ok = 0
+        for news in queryset:
+            if news.newsbox_published:
+                continue
+
+            if not news.has_publish_permission(request):
+                messages.error(
+                    request,
+                    _(
+                        'You do not have permission to publish the '
+                        '%(objtype)s "%(objtitle)s"'
+                    ) % {
+                        'objtype': six.text_type(self.model._meta.verbose_name),
+                        'objtitle': news
+                    }
+                )
+                continue
+            news.newsbox_published = True
+            news.save()
+            ok += 1
+
+        messages.success(request, ungettext_lazy(
+            '%(nb)d %(objtype)s was published',
+            '%(nb)d %(objtype)s were published',
+            ok) % {'nb': ok, 'objtype': self.model._meta.verbose_name})
+    publish.short_description = _('Publish selected %(verbose_name_plural)s')
+
+    def unpublish(self, request, queryset):
+        """
+        Marks selected news items as unpublished
+        """
+        ok = 0
+        for news in queryset:
+            if not news.newsbox_published:
+                continue
+
+            if not news.has_publish_permission(request):
+                messages.error(
+                    request,
+                    _(
+                        'You do not have permission to unpublish the '
+                        '%(objtype)s "%(objtitle)s"'
+                    ) % {
+                        'objtype': six.text_type(self.model._meta.verbose_name),
+                        'objtitle': news
+                    }
+                )
+                continue
+            news.newsbox_published = False
+            news.save()
+            ok += 1
+
+        messages.success(request, ungettext_lazy(
+            '%(nb)d %(objtype)s was unpublished',
+            '%(nb)d %(objtype)s were unpublished',
+            ok) % {
+                'nb': ok,
+                'objtype': self.model._meta.verbose_name,
+            }
+        )
+    unpublish.short_description = _(
+        'Unpublish selected %(verbose_name_plural)s')
+
+class NewsboxAdmin(NewsboxBaseAdmin):
+    pass
+
+
+class NewsboxExpiredAdmin(NewsboxBaseAdmin):
+
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(NewsboxExpiredAdmin, self).get_fieldsets(request, obj)
+
+        remove_field_from_fieldsets('newsbox_published', fieldsets)
+        add_fields_to_fieldset(
+            ['newsbox_published',
+             'newsbox_publication_start_date',
+             'newsbox_publication_end_date', ],
+            fieldsets,
+            default_fieldset_name=_('Publication'),
+            default_fieldset_position=1)
+
+        return fieldsets
+
+    def get_list_display(self, request):
+        list_display = super(NewsboxExpiredAdmin, self).get_list_display(request)
+
+        list_display = list_display[:2] +\
+            ['newsbox_publication_end_date',] + list_display[2:]
+        return list_display
+
+class NewsboxSEOAdmin(NewsboxBaseAdmin):
+
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(NewsboxSEOAdmin, self).get_fieldsets(request, obj)
+
+        add_fields_to_fieldset(
+            ['newsbox_indexed',
+             'newsbox_meta_description',
+             'newsbox_meta_keywords', ],
+            fieldsets,
+            default_fieldset_name=_('SEO Settings'),
+            default_fieldset_classes=('collapse',),
+        )
+
+        return fieldsets
+
+    def get_list_display(self, request):
+        list_display = super(NewsboxSEOAdmin, self).get_list_display(request)
+        return list_display
diff --git a/newsbox/locale/fr/LC_MESSAGES/django.mo b/newsbox/locale/fr/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000000000000000000000000000000000..568c03c52430e6f7dc02de3913e9bac2a42b084f
Binary files /dev/null and b/newsbox/locale/fr/LC_MESSAGES/django.mo differ
diff --git a/newsbox/locale/fr/LC_MESSAGES/django.po b/newsbox/locale/fr/LC_MESSAGES/django.po
new file mode 100644
index 0000000000000000000000000000000000000000..ec7afe005fc914ca435123be17e23486c1c22a14
--- /dev/null
+++ b/newsbox/locale/fr/LC_MESSAGES/django.po
@@ -0,0 +1,270 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-01-18 15:31+0100\n"
+"PO-Revision-Date: 2014-01-18 15:26+0100\n"
+"Last-Translator: Dylann Cordel <cordel.d@free.fr>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: admin.py:28
+msgid "translations"
+msgstr "traductions"
+
+#: admin.py:53
+msgid "edit"
+msgstr "modifier"
+
+#: admin.py:56 models.py:72
+msgid "title"
+msgstr "titre"
+
+#: admin.py:61
+#, python-format
+msgid "Unpublish this %s"
+msgstr "Dépublier cette %s"
+
+#: admin.py:65
+#, python-format
+msgid "Publish this %s"
+msgstr "Publier cette %s"
+
+#: admin.py:75 models.py:169
+msgid "published"
+msgstr "publiée"
+
+#: admin.py:86
+msgid "Content"
+msgstr "Contenu"
+
+#: admin.py:100 newsboxcms/models.py:14
+msgid "Title"
+msgstr "Titre"
+
+#: admin.py:104
+msgid "Slug"
+msgstr "Slug"
+
+#: admin.py:123
+#, python-format
+msgid "You do not have permission to publish this %s"
+msgstr "Vous n'avez pas la permission de publier cette %s"
+
+#: admin.py:129
+#, python-format
+msgid "The %(objtype)s \"%(objtitle)s\" was  successfully published"
+msgstr "Cette %(objtype)s \"%(objtitle)s\" a été publiée avec succès"
+
+#: admin.py:135
+#, python-format
+msgid "The %(objtype)s \"%(objtitle)s\" was successfully unpublished"
+msgstr "Cette %(objtype)s \"%(objtitle)s\" a été dépubliée avec succès"
+
+#: admin.py:160
+#, python-format
+msgid "You do not have permission to publish the %(objtype)s \"%(objtitle)s\""
+msgstr ""
+"Vous n'avez pas la permission de publier cette %(objtype)s \"%(objtitle)s\""
+
+#: admin.py:172
+#, python-format
+msgid "%(nb)d %(objtype)s was published"
+msgid_plural "%(nb)d %(objtype)s were published"
+msgstr[0] "%(nb)d %(objtype)s a été dépubliée avec succès"
+msgstr[1] "%(nb)d %(objtype)s ont été dépubliées avec succès"
+
+#: admin.py:175
+#, python-format
+msgid "Publish selected %(verbose_name_plural)s"
+msgstr "Publier les %(verbose_name_plural)s sélectionnées"
+
+#: admin.py:188
+#, python-format
+msgid ""
+"You do not have permission to unpublish the %(objtype)s \"%(objtitle)s\""
+msgstr ""
+"Vous n'avez pas la permission de dépublier cette %(objtype)s \"%(objtitle)s\""
+
+#: admin.py:200
+#, python-format
+msgid "%(nb)d %(objtype)s was unpublished"
+msgid_plural "%(nb)d %(objtype)s were unpublished"
+msgstr[0] "%(nb)d %(objtype)s a été dépubliée avec succès"
+msgstr[1] "%(nb)d %(objtype)s ont été dépubliées avec succès"
+
+#: admin.py:208
+#, python-format
+msgid "Unpublish selected %(verbose_name_plural)s"
+msgstr "Dépublier les %(verbose_name_plural)s sélectionnées"
+
+#: admin.py:237
+msgid "Publication"
+msgstr "Publication"
+
+#: admin.py:244
+msgid "SEO Settings"
+msgstr "Options de référencement"
+
+#: models.py:75
+msgid "slug"
+msgstr "slug"
+
+#: models.py:77
+msgid "The part of the title that is used in the URL"
+msgstr "La partie du titre utilisée dans l'URL"
+
+#: models.py:85 models.py:95
+msgid "summary"
+msgstr "résumé"
+
+#: models.py:89 models.py:97
+msgid "body"
+msgstr "corps"
+
+#: models.py:104
+msgid "meta description"
+msgstr "méta description"
+
+#: models.py:107
+msgid "meta keywords"
+msgstr "méta mots clés"
+
+#: models.py:147
+msgid "creation date"
+msgstr "date de création"
+
+#: models.py:151
+msgid "last update date"
+msgstr "date de dernière modification"
+
+#: models.py:157
+msgid "date"
+msgstr "date"
+
+#: models.py:162
+msgid "publication start date"
+msgstr "date de début de publication"
+
+#: models.py:165
+msgid ""
+"When the news should go live. Status must be \"Published\" for news to go "
+"live."
+msgstr ""
+"Date à laquelle l'actualité sera visible. Le statut doit être \"publié\" "
+"pour que l'actualité soit visible."
+
+#: models.py:178
+#, python-format
+msgid "News n° %s"
+msgstr "Actualité n° %s"
+
+#: models.py:236 models.py:237
+msgid "news"
+msgstr "actualité"
+
+#: models.py:252
+msgid "publication end date"
+msgstr "date de fin de publication"
+
+#: models.py:255
+msgid "When to expire the news.Leave empty to never expire."
+msgstr ""
+"Date à laquelle l'actualité ne sera plus visible. Laisser vide pour qu'elle "
+"n'expire jamais."
+
+#: models.py:269
+msgid "indexed"
+msgstr "indéxée"
+
+#: models.py:272
+msgid "An unindexed news will not be indexed by search engines."
+msgstr ""
+"Une actualité non indéxée ne sera jamais indéxée par les moteurs de recherche"
+
+#: views.py:21 newsboxcms/cms_plugins.py:21
+msgid "The choosen news type to display is invalid"
+msgstr "Le type d'actualité à afficher choisi est invalide"
+
+#: newsboxcms/cms_plugins.py:10
+msgid "News list"
+msgstr "Liste d'actualité"
+
+#: newsboxcms/models.py:11
+msgid "News type to display"
+msgstr "Type d'actualité à afficher"
+
+#: newsboxcms/models.py:16
+msgid "Title to display before the list"
+msgstr "Titre à afficher avant la liste"
+
+#: newsboxcms/models.py:18
+msgid "Number of news"
+msgstr "Nombre d'actualité"
+
+#: newsboxcms/models.py:20
+msgid "Number of news to display. \"0\" allow you to display ALL news"
+msgstr ""
+"Nombre d'actualité à afficher. \"0\" permet d'afficher TOUTES les actualités "
+"(sans pagination)"
+
+#: newsboxcms/models.py:23
+msgid "Display a pager"
+msgstr "Affiche une pagination"
+
+#: newsboxcms/models.py:29
+#, fuzzy, python-format
+msgid "Display of a news"
+msgid_plural "Display of %(nb)d news"
+msgstr[0] "Affichage de toutes les actualités"
+msgstr[1] "Affichage de toutes les actualités"
+
+#: newsboxcms/models.py:33
+msgid "Display of all news"
+msgstr "Affichage de toutes les actualités"
+
+#: newsboxcms/templates/newsboxcms/list-cms.html:11
+#: templates/newsbox/list.html:38
+msgid "Read more"
+msgstr "Lire la suite"
+
+#: templates/newsbox/list.html:53
+msgid "Previous news"
+msgstr "Actualités précédentes"
+
+#: templates/newsbox/list.html:57
+#, python-format
+msgid "Page %(number)s on %(total)s"
+msgstr "Page %(number)s sur %(total)s"
+
+#: templates/newsbox/list.html:61
+msgid "Next news"
+msgstr "Actualités suivantes"
+
+#: templates/newsbox/list.html:65
+msgid "See all news"
+msgstr "Voir toutes les actualités"
+
+#~ msgid ""
+#~ "\n"
+#~ "                                    Page %(number)s on %(total)s\n"
+#~ "                                "
+#~ msgstr ""
+#~ "\n"
+#~ "                                    Page %(number)s sur %(total)s\n"
+#~ "                                "
+
+#, fuzzy
+#~ msgid "%d %s was published"
+#~ msgid_plural "%d %s were published"
+#~ msgstr[0] "publiée"
+#~ msgstr[1] "publiée"
diff --git a/newsbox/migrations/__init__.py b/newsbox/migrations/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/newsbox/models.py b/newsbox/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..10ef5d1d78faa0b859e88543cf5c9ef5432e0050
--- /dev/null
+++ b/newsbox/models.py
@@ -0,0 +1,268 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import sys
+from datetime import datetime
+
+from django.core.urlresolvers import reverse
+from django.db import models
+from django.utils.timezone import utc
+from django.utils.translation import ugettext_lazy as _
+from django.utils.encoding import python_2_unicode_compatible
+from django.utils import six
+
+newsbox_models = []
+
+def newsbox_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts):
+    class_attrs['newsbox_title'] = models.CharField(
+        verbose_name=_('title'),
+        max_length=255)
+    class_attrs['newsbox_slug'] = models.SlugField(
+        verbose_name=_('slug'),
+        unique_for_date='newsbox_date',
+        help_text=_('The part of the title that is used in the URL'))
+    class_attrs['newsbox_summary'] = models.TextField(
+        verbose_name=_('summary'))
+    class_attrs['newsbox_body'] = models.TextField(
+        verbose_name=_('body'),
+        null=False, blank=True)
+    newsbox_opts['trans_fieldnames']+=[
+        'newsbox_title', 'newsbox_slug',
+        'newsbox_summary', 'newsbox_body']
+
+def newsboxseo_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts):
+    class_attrs['newsbox_meta_description'] = models.TextField(
+        verbose_name=_('meta description'),
+        max_length=255, blank=True, null=True)
+    class_attrs['newsbox_meta_keywords'] = models.CharField(
+        verbose_name=_('meta keywords'),
+        max_length=255, blank=True, null=True)
+
+    newsbox_opts['trans_fieldnames']+=[
+        'newsbox_meta_description', 'newsbox_meta_keywords']
+
+class NewsboxManager(models.Manager):
+    """
+    Filter published news
+    """
+
+    def published(self):
+        now = datetime.utcnow().replace(tzinfo=utc)
+        query_set = super(NewsboxManager, self).get_query_set().filter(
+            # Only published News
+            models.Q(newsbox_published=True),
+        ).exclude(
+            # exclude news with publication start date in the future
+            models.Q(newsbox_publication_start_date__gt=now)
+        )
+        
+        if issubclass(self.model, NewsboxExpiredBase):
+            query_set = query_set.exclude(
+                # exclude news which are obsolete
+                models.Q(newsbox_publication_end_date__lte=now)
+            )
+        return query_set
+
+
+class NewsboxModelBase(models.base.ModelBase):
+    """
+    Metaclass used to inject django-newsboxfunctionalities into django
+    orm.
+    """
+
+    def __new__(mcls, class_name, class_bases, class_attrs):
+        super_new = super(NewsboxModelBase, mcls).__new__
+
+        # six.with_metaclass() inserts an extra class called 'NewBase' in the
+        # inheritance tree: Model -> NewBase -> object. But the initialization
+        # should be executed only once for a given model class.
+
+        # attrs will never be empty for classes declared in the standard way
+        # (ie. with the `class` keyword). This is quite robust.
+        if class_name == 'NewBase' and class_attrs == {}:
+            return super_new(mcls, class_name, class_bases, class_attrs)
+
+        # Also ensure initialization is only performed for subclasses of Model
+        # (excluding Model class itself).
+        parents = [b for b in class_bases if isinstance(b, NewsboxModelBase) and
+                not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))]
+        if not parents:
+            return super_new(mcls, class_name, class_bases, class_attrs)
+
+        #retrieve newsbox options in Meta class and delete these from the 
+        #Meta class to avoid django complain about unsupported keys.
+        #We register our meta options in `_newsbox_meta`
+        attr_meta = class_attrs.get('Meta', None)
+        if attr_meta and not getattr(attr_meta, 'ordering', None):
+            class_attrs['Meta'].ordering = ('-newsbox_date',)
+        abstract = getattr(attr_meta, 'abstract', False)
+        newsbox_opts = {}
+        newsbox_opts_keys = [
+            'detail_url_name', 
+            'metaclass_base_processor', 
+            'metaclass_final_processor', 
+            'trans_fieldnames']
+        for opt in newsbox_opts_keys:
+            newsbox_opt = 'newsbox_' + opt
+            if hasattr(attr_meta, newsbox_opt):
+                newsbox_opts[opt] = getattr(attr_meta, newsbox_opt)
+                delattr(attr_meta, newsbox_opt)
+
+        if 'trans_fieldnames' not in newsbox_opts:
+            newsbox_opts['trans_fieldnames'] = []
+
+        # register newsbox_objects manager
+        class_attrs['newsbox_objects'] = NewsboxManager()
+        
+        #Call specific metaclass processor of all bases
+        if not abstract :
+            for base in class_bases:
+                try:
+                    processor = base._newsbox_meta['metaclass_base_processor']
+                except (AttributeError, KeyError):
+                    continue
+                processor = getattr(sys.modules[base.__module__], processor)
+                processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts)
+
+            for base in class_bases:
+                try:
+                    processor = base._newsbox_meta['metaclass_final_processor']
+                except (AttributeError, KeyError):
+                    continue
+                processor = getattr(sys.modules[base.__module__], processor)
+                processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts)
+
+        if not 'default_manager' in class_attrs:
+            class_attrs['default_manager'] = class_attrs['newsbox_objects']
+        if not 'objects' in class_attrs:
+            class_attrs['objects'] = class_attrs['newsbox_objects']
+
+        # contructs class
+        cls = super_new(mcls, class_name, class_bases, class_attrs)
+
+        #Add the detail_url_name to _newsbox_meta. if not defined, we build the
+        #default one with this format : <app_label>_<model_name>_detail
+        #Names ar lowered.
+        if not abstract:
+            detail_url_name = newsbox_opts.get(
+                'detail_url_name',
+                "%s_%s_detail" % (cls._meta.app_label.lower(),
+                    cls._meta.model_name.lower(),)
+            )
+
+            newsbox_opts.update(
+                detail_url_name=detail_url_name,
+            )
+            newsbox_models.append(cls)
+        cls.add_to_class('_newsbox_meta', newsbox_opts)
+        return cls
+
+
+@python_2_unicode_compatible
+class NewsboxBase(six.with_metaclass(NewsboxModelBase, models.Model)):
+    """
+    Abstract class to build your own news
+    """
+
+    # Automatic fields
+    newsbox_creation_date = models.DateTimeField(
+        verbose_name=_('creation date'),
+        auto_now_add=True,
+        editable=False)
+    newsbox_changed_date = models.DateTimeField(
+        verbose_name=_('last update date'),
+        auto_now=True,
+        editable=False)
+
+    # Basic Publication Fields
+    newsbox_date = models.DateTimeField(
+        verbose_name=_('date'),
+        default=datetime.now, db_index=True,
+    )
+
+    newsbox_publication_start_date = models.DateTimeField(
+        verbose_name=_('publication start date'),
+        default=datetime.now, db_index=True,
+        help_text=_(
+            'When the news should go live. '
+            'Status must be "Published" for news to go live.'))
+
+    newsbox_published = models.BooleanField(
+        verbose_name=_('published'),
+        blank=True,
+        default=True,)
+
+    default_manager = NewsboxManager()
+    objects = default_manager
+
+    def __str__(self):
+        return six.text_type(self.newsbox_title)
+
+    def has_publish_permission(self, request):
+        if request.user.is_superuser:
+            return True
+        return request.user.has_perm('newsbox.publish_news', self)
+
+    def has_change_permission(self, request):
+        if request.user.is_superuser:
+            return True
+        return request.user.has_perm('newsbox.change_news', self)
+
+    def is_published(self):
+        if not self.newsbox_published:
+            return False
+
+        if isinstance(self, NewsboxExpiredBase):
+            now = datetime.utcnow().replace(tzinfo=utc)
+            if now < self.newsbox_publication_start_date:
+                return False
+            if now > self.newsbox_publication_end_date:
+                return False
+
+        return True
+
+    def get_slug(self, *args, **kwargs):
+        return self.newsbox_slug
+
+    def get_absolute_url(self, *args, **kwargs):
+        return reverse(self._newsbox_meta['detail_url_name'], args=(
+            self.newsbox_date.strftime("%Y"),
+            self.newsbox_date.strftime("%m"),
+            self.newsbox_date.strftime("%d"),
+            self.get_slug(),))
+
+    class Meta:
+        abstract = True
+        verbose_name = _('news')
+        verbose_name_plural = _('news')
+        ordering = ('-newsbox_date',)
+        newsbox_metaclass_base_processor = 'newsbox_mcls_processor'
+
+class NewsboxExpiredBase(six.with_metaclass(NewsboxModelBase, models.Model)):
+    """
+    Define News which expires in time and will not be displayed in front
+    """
+    newsbox_publication_end_date = models.DateTimeField(
+        verbose_name=_('publication end date'),
+        null=True, blank=True, db_index=True,
+        help_text=_(
+            'When to expire the news.'
+            'Leave empty to never expire.'))
+
+    class Meta:
+        abstract = True
+
+class NewsboxSEOBase(six.with_metaclass(NewsboxModelBase, models.Model)):
+    """
+    Define News which have SEO fields
+    """
+
+    # SEO Fields
+    newsbox_indexed = models.BooleanField(
+        verbose_name=_('indexed'),
+        default=True,
+        help_text=_(
+            'An unindexed news will not be indexed by search engines.'))
+
+    class Meta:
+        abstract = True
+        newsbox_metaclass_base_processor = 'newsboxseo_mcls_processor'
diff --git a/newsbox/templates/newsbox/detail.html b/newsbox/templates/newsbox/detail.html
new file mode 100644
index 0000000000000000000000000000000000000000..09f53f3e859c106a937e4428bca2ea1318781538
--- /dev/null
+++ b/newsbox/templates/newsbox/detail.html
@@ -0,0 +1,22 @@
+{% load i18n %}
+
+<article class="newsbox_detail">
+    {% block newsbox_detail_header %}
+        <header>
+            <h1>{{ news.newsbox_title }}</h1>
+            <time datetime="{{ news.newsbox_date }}">{{ news.newsbox_date|date:'d M. Y' }}</time>
+        </header>
+    {% endblock %}
+    
+    
+    {% block newsbox_detail_item_content %}
+        <div class="content">
+            
+            {% if news.newsbox_body %}
+                {{ news.newsbox_body|linebreaks }}
+            {% else %}
+                {{ news.newsbox_summary|linebreaks }}
+            {% endif %}
+        </div>
+    {% endblock %}
+</article>
diff --git a/newsbox/templates/newsbox/list.html b/newsbox/templates/newsbox/list.html
new file mode 100644
index 0000000000000000000000000000000000000000..e3d263e90600b8f141e4d49a35e311e7e8060330
--- /dev/null
+++ b/newsbox/templates/newsbox/list.html
@@ -0,0 +1,74 @@
+{% if news|length > 0 %}
+    {% load i18n %}
+    <section class="newsbox_plugin">
+
+        {% block newsbox_list_header %}
+            {% if title %}
+                <h1>
+                    {% if title_url %}
+                        <a href="{{ title_url }}">{{ title }}</a>
+                    {% else %}
+                        {{ title }}
+                    {% endif %}
+                </h1>
+            {% endif %}
+        {% endblock %}
+
+
+        {% block newsbox_list %}
+            <div class="list">
+
+                {% for news in newsset %}
+                    {% block newsbox_list_item %}
+                        <div class="news">
+                            <header>
+                                {% block newsbox_list_item_header %}
+                                    {% with news.get_absolute_url as url %}
+                                        <h2><a href="{{ url }}">{{ news.newsbox_title }}</a></h2>
+                                    {% endwith %}
+                                    <time datetime="{{ news.newsbox_date }}">{{ news.newsbox_date|date:'d M. Y' }}</time>
+                                {% endblock %}
+                            </header>
+                            
+                            {% block newsbox_list_item_content %}
+                                <div class="summary">
+                                    {{ news.newsbox_summary|linebreaks }}
+                                    {% if news.newsbox_body %}
+                                        <p class="readmore"><a href="{{ news.get_absolute_url }}">
+                                            {% trans "Read more" %}
+                                        </a></p>
+                                    {% endif %}
+                                </div>
+                            {% endblock %}
+
+                        </div>
+                    {% endblock %}
+                {% endfor %}
+
+
+                {% block newsbox_pager %}
+                    {% if with_pager %}
+                        <div class="pager">
+                            {% if newsset.has_previous %}
+                                <a class="prev" href="?page={{ newsset.previous_page_number }}">{% trans "Previous news" %}</a>
+                            {% endif %}
+
+                            <span class="current">
+                                {% blocktrans with newsset.number as number and newsset.paginator.num_pages as total %}Page {{ number }} on {{ total }}{% endblocktrans %}
+                            </span>
+
+                            {% if newsset.has_next %}
+                                <a class="next" href="?page={{ newsset.next_page_number }}">{% trans "Next news" %}</a>
+                            {% endif %}
+                        </div>
+                    {% elif all_news_url %}
+                        <a class="readmore" href="{{ all_news_url }}">{% trans "See all news" %}</a></p>
+                    {% endif %}
+                {% endblock %}
+
+            </div>
+        {% endblock %}
+    </section>
+{% else %}
+    {% block newsbox_no_news %}{% endblock %}
+{% endif %}
diff --git a/newsbox/templatetags/__init__.py b/newsbox/templatetags/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/newsbox/templatetags/get_placeholder_content.py b/newsbox/templatetags/get_placeholder_content.py
new file mode 100644
index 0000000000000000000000000000000000000000..f649636b8e95008f28bf634d5900b6ac9f681498
--- /dev/null
+++ b/newsbox/templatetags/get_placeholder_content.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django import template
+from django.utils.safestring import mark_safe
+from classytags.arguments import Argument
+from classytags.core import Options
+from cms.templatetags.cms_tags import RenderPlaceholder
+
+
+register = template.Library()
+
+
+class GetPlaceholderContent(RenderPlaceholder):
+    """
+    With this tag, you can retrieve a placeholder's content into a variable
+
+    Exemple :
+        {% get_placeholder_content news.newsbox_body as body %}
+            {% if body %}
+                {{ body|safe }}
+                some extra html
+            {% else %}
+                fall back
+            {% endif %}
+        {% endget_placeholder_content %}
+    """
+    name = 'get_placeholder_content'
+    options = Options(
+        Argument('placeholder', resolve=True),
+        Argument('width', default=None, required=False),
+        'language',
+        Argument('language', default=None, required=False),
+        'as',
+        Argument('varname', resolve=False),
+        blocks=[
+            ('endget_placeholder_content', 'nodelist'),
+        ]
+    )
+
+    def render_tag(self, context, placeholder, width, varname, language=None, nodelist=None):
+        placeholder_output = None
+        if placeholder:
+            placeholder_output = super(GetPlaceholderContent, self).render_tag(
+                context, placeholder, width, language)
+
+        context.push()
+        context[varname] = mark_safe(placeholder_output)
+        output = nodelist.render(context)
+        context.pop()
+        return output
+
+
+register.tag(GetPlaceholderContent)
diff --git a/newsbox/urls.py b/newsbox/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..b0164b0782d04a997421c299a72bf190996faaa8
--- /dev/null
+++ b/newsbox/urls.py
@@ -0,0 +1,72 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.utils.text import slugify
+from django.conf.urls import patterns, url, include
+from django.conf.urls.i18n import i18n_patterns
+
+from .models import newsbox_models
+from .views import NewsboxArchiveView, NewsboxYearArchiveView, \
+    NewsboxMonthArchiveView, NewsboxDayArchiveView, NewsboxDetailView
+
+def get_urls(
+    archive_view=NewsboxArchiveView, 
+    year_archive_view=NewsboxYearArchiveView, 
+    month_archive_view=NewsboxMonthArchiveView, 
+    day_archive_view=NewsboxDayArchiveView, 
+    detail_view=NewsboxDetailView):
+    
+    urls = ['',]
+    for model in newsbox_models :
+        app_name = model._meta.app_label.lower()
+        model_name = model.__name__.lower()
+        
+        viewurl = 'newsbox/%s/%s/'\
+                    % (app_name, model_name,)
+        urls.append(
+            url(
+                r'^%s$' % viewurl, 
+                archive_view.as_view(
+                    model=model,),
+                name='%s_%s_list' % (app_name, model_name),
+            ),
+        )
+        viewurl=viewurl+'(?P<year>\d{4})/' 
+        urls.append(
+            url(
+                r'^%s$' % viewurl, 
+                year_archive_view.as_view(
+                    model=model,),
+                name='%s_%s_list_y' % (app_name, model_name),
+            ),
+        )
+        viewurl=viewurl+'(?P<month>\d{2})/' 
+        urls.append(
+            url(
+                r'^%s$' % viewurl, 
+                month_archive_view.as_view(
+                    model=model,),
+                name='%s_%s_list_ym' % (app_name, model_name),
+            ),
+        )
+        viewurl=viewurl+'(?P<day>\d{2})/'
+        urls.append(
+            url(
+                r'^%s$' % viewurl, 
+                day_archive_view.as_view(
+                    model=model,),
+                name='%s_%s_list_ymd' % (app_name, model_name),
+            ),
+        )
+        urls.append(
+            url(
+                r'^%s(?P<slug>[0-9a-zA-Z_-]+)/$' % viewurl, 
+                detail_view.as_view(
+                    model=model,),
+                name='%s_%s_detail' % (app_name, model_name),
+            ),
+        )
+    return urls
+
+urls = get_urls()
+urlpatterns = patterns(*urls)
diff --git a/newsbox/utils.py b/newsbox/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..c53eac001478a2e4176cf35ade0b204ebd7ed5ca
--- /dev/null
+++ b/newsbox/utils.py
@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+
+def get_newsmodels_list():
+    from django.db.models import get_app, get_models
+    pass
diff --git a/newsbox/views.py b/newsbox/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..f47c0baed77066c8e2fddb765b4439780125f554
--- /dev/null
+++ b/newsbox/views.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.http import Http404, HttpResponse
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template.context import RequestContext
+from django.utils.translation import ugettext as _
+from django.db.models.loading import get_model
+from django.views.generic.dates import DateDetailView, ArchiveIndexView, \
+    YearArchiveView, MonthArchiveView, DayArchiveView
+
+from .models import NewsboxBase
+
+class NewsboxBaseArchiveView(object):
+    """
+    This view is responsible for displaying a list of newsbox
+    """
+    date_field = "newsbox_date"
+    slug_field = "newsbox_slug"
+    paginate_by = 10
+    make_object_list = True
+    allow_future = True
+    template_name = "newsbox/list.html"
+    context_object_name = 'newsset'
+    title = None
+
+    def update_context_data(self, context, **kwargs):
+        with_pager = context['is_paginated']
+        context['newsset'].number = context['page_obj'].number
+        context['newsset'].has_previous = context['page_obj'].has_previous
+        context['newsset'].has_next = context['page_obj'].has_next
+        context['newsset'].next_page_number = context['page_obj'].next_page_number
+        context['newsset'].previous_page_number = context['page_obj'].previous_page_number
+        context['newsset'].paginator = context['paginator']
+        if self.title == None:
+            title = self.model._meta.verbose_name_plural.capitalize()
+        else:
+            title=self.title
+        context.update({
+            'instance': None,
+            'title': title,
+            'title_url': '',
+            'newsbox_opts':self.model._newsbox_meta,
+            'with_pager': with_pager,
+        })
+        return context
+
+    def get_queryset(self):
+        if self.request.user.is_staff:
+            return self.model.objects.all()
+        else:
+            return self.model.objects.published()
+
+class NewsboxArchiveView(NewsboxBaseArchiveView, ArchiveIndexView):
+    def get_context_data(self, **kwargs):
+        context = super(NewsboxArchiveView, self).get_context_data(**kwargs)
+        NewsboxBaseArchiveView.update_context_data(self, context, **kwargs)
+        return context
+
+class NewsboxYearArchiveView(NewsboxBaseArchiveView, YearArchiveView):
+    def get_context_data(self, **kwargs):
+        context = super(NewsboxYearArchiveView, self).get_context_data(**kwargs)
+        NewsboxBaseArchiveView.update_context_data(self, context, **kwargs)
+        return context
+
+    def get_queryset(self):
+        if self.request.user.is_staff:
+            return self.model.objects.all()
+        else:
+            return self.model.objects.published()
+
+class NewsboxMonthArchiveView(NewsboxBaseArchiveView, MonthArchiveView):
+    month_format = "%m"
+    def get_context_data(self, **kwargs):
+        context = super(NewsboxMonthArchiveView, self).get_context_data(**kwargs)
+        NewsboxBaseArchiveView.update_context_data(self, context, **kwargs)
+        return context
+
+class NewsboxDayArchiveView(NewsboxBaseArchiveView, DayArchiveView):
+    month_format = "%m"
+    def get_context_data(self, **kwargs):
+        context = super(NewsboxDayArchiveView, self).get_context_data(**kwargs)
+        NewsboxBaseArchiveView.update_context_data(self, context, **kwargs)
+        return context
+    
+    
+
+class NewsboxDetailView(DateDetailView):
+    """
+    This view is responsible for displaying a newsbox
+    """
+    month_format = "%m"
+    date_field = "newsbox_date"
+    slug_field = "newsbox_slug"
+    template_name = "newsbox/detail.html"
+    context_object_name = "news"
+    allow_future = True
+
+    def get_context_data(self, **kwargs):
+        context = super(NewsboxDetailView, self).get_context_data(**kwargs)
+        if 'NewsboxCMSBase' in (base.__name__ for base in self.model.__bases__):
+            from menus.utils import set_language_changer
+            set_language_changer(self.request, self.object.get_absolute_url)
+        return context
+
+    def get_object(self):
+        # We check user permission
+        obj = super(NewsboxDetailView, self).get_object()
+        if(
+            not obj.is_published()
+            and not obj.has_change_permission(self.request)
+        ):
+            raise Http404
+        return obj
diff --git a/newsbox_cms/__init__.py b/newsbox_cms/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/newsbox_cms/admin.py b/newsbox_cms/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..14388ef7e5fb5aad27006684fa903576fe2284c3
--- /dev/null
+++ b/newsbox_cms/admin.py
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.contrib import admin
+from django.core.urlresolvers import reverse
+from django.utils import formats
+from django.utils.translation import ugettext_lazy as _
+from django.utils import six
+
+try:
+    from cms.admin.placeholderadmin import FrontendEditableAdminMixin, PlaceholderAdminMixin
+except ImportError:
+    # temporary django-cms backward compat
+    from cms.admin.placeholderadmin import (
+        FrontendEditableAdmin as FrontendEditableAdminMixin,
+        PlaceholderAdmin as PlaceholderAdminMixin
+    )
+
+from newsbox.admin import NewsboxBaseAdmin, remove_field_from_fieldsets, add_fields_to_fieldset
+
+
+class CustomModelCMSAdmin(admin.ModelAdmin):
+    class Media:
+        css = {
+            "all": ("newsbox_cms/custom_model.css",)
+        }
+
+
+def CustomModelCMSAdminFactory(
+    object_title=None,
+    edit_link_short_description=_('title'),
+    edit_link_admin_order_field=None,
+):
+    class klass(CustomModelCMSAdmin):
+
+        def edit_link_title(self, obj, func_or_attr=None):
+            if func_or_attr is not None:
+                if isinstance(func_or_attr, basestring):
+                    if not hasattr(obj, func_or_attr):
+                        raise ValueError(
+                            'func_or_attr is a string, it needs to be'
+                            ' an object attribute (eventualy a function)'
+                        )
+
+                    attr = getattr(obj, func_or_attr)
+                    if callable(attr):
+                        title = attr(obj)
+                    else:
+                        title = attr
+
+                elif callable(func_or_attr):
+                    title = func_or_attr(obj)
+                else:
+                    raise ValueError('func_or_attr needs to be either a string or a collable')
+
+            else:
+                title = six.text_type(obj)
+            return title
+
+        def edit_link(self, obj):
+            """
+            build the change list edit link
+            """
+            output = ''
+            edit_url = reverse(
+                'admin:%s_%s_change' % (obj._meta.app_label, obj._meta.module_name),
+                args=[obj.pk])
+
+            show_url = None
+            if hasattr(obj, 'get_absolute_url'):
+                show_url = obj.get_absolute_url()
+
+            output = '<a class="edit" href="{edit_url}" title="{edit_label}"></a>'
+
+            if show_url:
+                output += '<a class="title" href="{show_url}" target="_parent" title="{show_label}">{title}</a>'
+            else:
+                output += '<span class="title">{title}</span>'
+
+            return output.format(
+                edit_url=edit_url, show_url=show_url, show_label=_("show object's page"),
+                title=self.edit_link_title(obj, object_title), edit_label=_("edit object's parameters"))
+
+        edit_link.allow_tags = True
+        edit_link.short_description = edit_link_short_description
+        edit_link.admin_order_field = edit_link_admin_order_field
+
+
+        def get_list_display(self, request):
+            list_display = super(CustomModelCMSAdmin, self).get_list_display(request)
+            list_display = list(list_display)
+            del list_display[0]
+            list_display.insert(0, 'edit_link')
+            return list_display
+
+        def get_list_display_links(self, request, list_display):
+            return []
+
+    return klass
+
+
+def newsbox_admin_title(obj):
+    return '{date}<br/>{title}'.format(
+        date=formats.date_format(obj.newsbox_date, 'DATE_FORMAT'),
+        title=six.text_type(obj)
+    )
+
+
+class NewsboxCMSAdmin(
+    #XXX: hvad TranslatableAdmin doesn't support admin_order_field on translated field
+    # CustomModelCMSAdminFactory(edit_link_admin_order_field='newsbox_title'),
+    CustomModelCMSAdminFactory(object_title=newsbox_admin_title, edit_link_admin_order_field='newsbox_date'),
+    FrontendEditableAdminMixin,
+    PlaceholderAdminMixin,
+    NewsboxBaseAdmin
+):
+
+    def __init__(self, *args, **kwargs):
+        # We manage the edit link ourself
+        self.list_display_links = (None, )
+        return super(NewsboxCMSAdmin, self).__init__(*args, **kwargs)
+        
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(NewsboxCMSAdmin, self).get_fieldsets(request, obj)
+        remove_field_from_fieldsets('newsbox_body', fieldsets)
+        add_fields_to_fieldset(
+            ['newsbox_summary'],
+            fieldsets,
+            same_fieldset_as='newsbox_published',
+            replace_existing_field=True,
+            remove_empty_fieldset=True,
+        )
+        return fieldsets
+
+    def get_list_display(self, request):
+        list_display = super(NewsboxCMSAdmin, self).get_list_display(request)
+        list_display.remove('newsbox_date')
+        list_display.remove('get_newsbox_slug')
+        return list_display
diff --git a/newsbox_cms/cms_plugins.py b/newsbox_cms/cms_plugins.py
new file mode 100644
index 0000000000000000000000000000000000000000..d42181a9ad6da99d06c76cc52e022ed9d7aee951
--- /dev/null
+++ b/newsbox_cms/cms_plugins.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.utils.translation import ugettext as _
+from django.db import models
+from django.contrib import admin
+from cms.plugin_base import CMSPluginBase
+from newsbox.models import NewsboxBase
+
+class NewsboxPluginBase(CMSPluginBase):
+    name = _("News list") # Name of the plugin
+    render_template = "newsbox_cms/list-cms.html" # template to render the plugin
+    raw_id_fields = ('page_link',)
+
+    def render(self, context, instance, placeholder):
+        from django.db.models.loading import get_model
+        
+        NewsboxModel = instance.newsbox_model
+
+        if not NewsboxModel or not issubclass(NewsboxModel, NewsboxBase):
+            raise Exception(_("The choosen news type to display is invalid"))
+
+        if instance.numitems > 0 :
+            with_pager = instance.with_pager
+
+            if with_pager :
+                from django.core.paginator import Paginator, \
+                    EmptyPage, PageNotAnInteger
+
+                paginator = Paginator(NewsboxModel.objects.published(), 
+                    instance.numitems)
+                page = context['request'].GET.get('page')
+                try:
+                    newsset = paginator.page(page)
+                except PageNotAnInteger:
+                    # If page is not an integer, deliver first page.
+                    newsset = paginator.page(1)
+                except EmptyPage:
+                    # If page is out of range (e.g. 9999), deliver last page of results.
+                    newsset = paginator.page(paginator.num_pages)
+            else :
+                newsset = NewsboxModel.objects.published()[:instance.numitems]
+        else :
+            newsset = NewsboxModel.objects.published()
+            with_pager = False
+        context.update({
+            'instance': instance,
+            'title': instance.title,
+            'newsset':newsset,
+            'newsbox_opts':NewsboxModel._newsbox_meta,
+            'with_pager':with_pager,
+        })
+        
+        if instance.page_link:
+            context.update({
+                'title_url' : instance.page_link.get_absolute_url(),
+                'all_news_url': instance.page_link.get_absolute_url(),
+            })
+        return context
+        
+    class Meta:
+        abstract = True
diff --git a/newsbox_cms/locale/fr/LC_MESSAGES/django.mo b/newsbox_cms/locale/fr/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000000000000000000000000000000000..27fc1c4239e93e2dacb771170c4c9f4feb1dca80
Binary files /dev/null and b/newsbox_cms/locale/fr/LC_MESSAGES/django.mo differ
diff --git a/newsbox_cms/locale/fr/LC_MESSAGES/django.po b/newsbox_cms/locale/fr/LC_MESSAGES/django.po
new file mode 100644
index 0000000000000000000000000000000000000000..39af73d52916739fd09a6aeaa7427bfb465a91e8
--- /dev/null
+++ b/newsbox_cms/locale/fr/LC_MESSAGES/django.po
@@ -0,0 +1,84 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-02-20 10:29+0100\n"
+"PO-Revision-Date: 2014-02-20 10:31+0100\n"
+"Last-Translator: \n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#: admin.py:20
+msgid "title"
+msgstr "Titre"
+
+#: admin.py:70
+msgid "show object's page"
+msgstr "Afficher la page de l'objet"
+
+#: admin.py:71
+msgid "edit object's parameters"
+msgstr "Éditer les paramètres de l'objet"
+
+#: cms_plugins.py:10
+msgid "News list"
+msgstr "Liste d'actualités"
+
+#: cms_plugins.py:19
+msgid "The choosen news type to display is invalid"
+msgstr "Le type d'actualité à afficher choisi est invalide"
+
+#: models.py:12
+msgid "Title"
+msgstr "Titre"
+
+#: models.py:14
+msgid "Title to display before the list"
+msgstr "Titre à afficher avant la liste"
+
+#: models.py:16
+msgid "Number of news"
+msgstr "Nombre d'actualités"
+
+#: models.py:18
+msgid "Number of news to display. \"0\" allow you to display ALL news"
+msgstr "numbre d'actualités à afficher. Saisir \"0\" permet de TOUTES les afficher"
+
+#: models.py:21
+msgid "Display a pager"
+msgstr "Affiche une pagination"
+
+#: models.py:24
+msgid "All news page"
+msgstr "Toutes les pages des actualités"
+
+#: models.py:26
+msgid "Page displaying all news"
+msgstr "Affichage de toutes les actualités"
+
+#: models.py:31
+#, python-format
+msgid "Display of a news"
+msgid_plural "Display of %(nb)d news"
+msgstr[0] "Affichage de l'actualité"
+msgstr[1] "Affichage de  %(nb)d actualités"
+
+#: models.py:35
+msgid "Display of all news"
+msgstr "Affichage de toutes les actualités"
+
+#: templates/newsbox_cms/list-cms.html:11
+msgid "Read more"
+msgstr "Lire la suite"
+
+#~ msgid "News type to display"
+#~ msgstr "Type d'actualité à afficher"
diff --git a/newsbox_cms/models.py b/newsbox_cms/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a28d46c21a96dcf680f923e268e8176af6e1dc2
--- /dev/null
+++ b/newsbox_cms/models.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.utils.translation import ugettext_lazy as _, ungettext_lazy
+from django.utils import six
+from django.utils.encoding import python_2_unicode_compatible
+from django.db import models
+from cms.models.pluginmodel import CMSPlugin
+from cms.models.fields import PageField, PlaceholderField
+from djangocms_text_ckeditor.fields import HTMLField
+
+from newsbox.models import NewsboxModelBase
+
+
+def newsboxcms_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts):
+    class_attrs['newsbox_summary'] = HTMLField(
+        verbose_name=_('summary'))
+    class_attrs['newsbox_body'] = PlaceholderField(
+        'newsbox_body',
+        verbose_name=_('body'))
+
+    if 'newsbox_body' in newsbox_opts['trans_fieldnames']:
+        newsbox_opts['trans_fieldnames'].remove('newsbox_body')
+
+
+@python_2_unicode_compatible
+class NewsboxPluginBase(CMSPlugin):
+    title = models.CharField(
+        verbose_name=_('Title'),
+        max_length=255, blank=True, null=True,
+        help_text=_('Title to display before the list'))
+    numitems = models.PositiveSmallIntegerField(
+        verbose_name=_('Number of news'),
+        default=2,
+        help_text=_('Number of news to display. '
+            '"0" allow you to display ALL news'))
+    with_pager = models.BooleanField(
+        verbose_name=_('Display a pager'),
+        default=False)
+
+    page_link = PageField(verbose_name=_('All news page'),
+        null=True, blank=True,
+        help_text=_('Page displaying all news'))
+
+    def __str__(self):
+        if self.numitems > 0:
+            return six.text_type(ungettext_lazy(
+                'Display of a news',
+                'Display of %(nb)d news',
+                self.numitems
+            ) % {'nb':self.numitems})
+        return six.text_type(_('Display of all news'))
+
+    class Meta:
+        abstract = True
+
+
+class NewsboxCMSBase(six.with_metaclass(NewsboxModelBase, models.Model)):
+
+    class Meta:
+        abstract = True
+        newsbox_metaclass_base_processor = 'newsboxcms_mcls_processor'
diff --git a/newsbox_cms/static/newsbox_cms/custom_model.css b/newsbox_cms/static/newsbox_cms/custom_model.css
new file mode 100644
index 0000000000000000000000000000000000000000..32b677ef3d8b19713d39dc6acdfa3505bf91cf08
--- /dev/null
+++ b/newsbox_cms/static/newsbox_cms/custom_model.css
@@ -0,0 +1,11 @@
+
+body.change-list #result_list td a.edit {
+    float:right;
+    background:url("../cms/img/pagetree/sprite.png") no-repeat scroll 0px 0px transparent;
+    width:18px;
+    height:18px;
+    display:inline-block;
+    background-position: -40px -20px;
+    margin-top: 0px;
+    vertical-align: middle;
+}
diff --git a/newsbox_cms/templates/newsbox_cms/detail-cms.html b/newsbox_cms/templates/newsbox_cms/detail-cms.html
new file mode 100644
index 0000000000000000000000000000000000000000..9b4bdc61b3e97ab53bca1c84a28da8c81b852fae
--- /dev/null
+++ b/newsbox_cms/templates/newsbox_cms/detail-cms.html
@@ -0,0 +1,22 @@
+{% extends "newsbox/detail.html" %}
+{% load i18n %}
+{% load get_placeholder_content cms_tags %}
+
+{% block newsbox_detail_header %}
+    <header>
+        <h1>{% render_model news "newsbox_title" %}</h1>
+        <time datetime="{{ news.newsbox_date }}">{{ news.newsbox_date|date:'d M. Y' }}</time>
+    </header>
+{% endblock %}
+    
+{% block newsbox_detail_item_content %}
+    <div class="content">
+        {% render_placeholder news.newsbox_body %}
+
+        {% get_placeholder_content news.newsbox_body as body %}
+            {% if not body %}
+                {{ news.newsbox_summary|safe }}
+            {% endif %}
+        {% endget_placeholder_content %}
+    </div>
+{% endblock %}
diff --git a/newsbox_cms/templates/newsbox_cms/list-cms.html b/newsbox_cms/templates/newsbox_cms/list-cms.html
new file mode 100644
index 0000000000000000000000000000000000000000..812f8b8a9b689308a4c68cb411e6ac1351ad0f5d
--- /dev/null
+++ b/newsbox_cms/templates/newsbox_cms/list-cms.html
@@ -0,0 +1,18 @@
+{% extends "newsbox/list.html" %}
+{% load i18n %}
+{% load get_placeholder_content %}
+    
+{% block newsbox_list_item_content %}
+
+    <div class="summary">
+        {{ news.newsbox_summary|safe }}
+        {% get_placeholder_content news.newsbox_body as body %}
+        
+            {% if body %}
+                <p class="readmore"><a href="{{ news.get_absolute_url }}">
+                    {% trans "Read more" %}
+                </a></p>
+            {% endif %}
+        {% endget_placeholder_content %}
+    </div>
+{% endblock %}
diff --git a/newsbox_hvad/__init__.py b/newsbox_hvad/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/newsbox_hvad/admin.py b/newsbox_hvad/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb474b0a2f64e01bfa080c3756085bbd02735d9b
--- /dev/null
+++ b/newsbox_hvad/admin.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import copy
+
+from django.conf import settings
+from hvad.admin import TranslatableAdmin
+from hvad.forms import translatable_modelform_factory
+from django.utils.translation import ugettext_lazy as _
+from django.contrib.admin.util import flatten_fieldsets
+from django.utils.functional import curry
+
+
+def edit_translation_links(obj):
+    output = ''
+    for lang in obj.get_available_languages():
+        output += (
+            '<a href="./%s/?language=%s" '
+            'target="_parent" title="Edit this %s in %s">%s'
+            '</a>'
+        ) % (obj.pk, lang, obj._meta.verbose_name, lang.upper(), lang.upper(),)
+    return output
+edit_translation_links.allow_tags = True
+edit_translation_links.short_description = _('translations')
+
+
+
+class NewsboxHVADBaseAdmin(TranslatableAdmin):
+
+    #XXX: hvad TranslatableAdmin doesn't support search_fields
+    # search_fields = ['newsbox_title', 'newsbox_summary', ]
+    # date_hierarchy = 'newsbox_publication_start_date'
+
+    def get_list_display(self, request):
+        list_display = super(NewsboxHVADBaseAdmin, self).get_list_display(request)
+        # prevent modifying class list_display variable
+        list_display = copy.deepcopy(list_display)
+        if settings.LANGUAGES and len(settings.LANGUAGES) > 1:
+            list_display.insert(1, edit_translation_links)
+
+        return list_display
+
+    def get_form(self, request, obj=None, **kwargs):
+        """
+        This function is a workaround to an hvad issue. It doesn't use
+        get_fieldsets function.
+
+        Returns a Form class for use in the admin add view. This is used by
+        add_view and change_view.
+        """
+        fieldsets = self.get_fieldsets(request, obj)
+        if fieldsets:
+            fields = flatten_fieldsets(fieldsets)
+        else:
+            fields = None
+        if self.exclude is None:
+            exclude = []
+        else:
+            exclude = list(self.exclude)
+        exclude.extend(kwargs.get("exclude", []))
+        exclude.extend(self.get_readonly_fields(request, obj))
+        # Exclude language_code, adding it again to the instance is done by
+        # the LanguageAwareCleanMixin (see translatable_modelform_factory)
+        exclude.append('language_code')
+        old_formfield_callback = curry(self.formfield_for_dbfield,
+                                       request=request)
+        defaults = {
+            "form": self.form,
+            "fields": fields,
+            "exclude": exclude,
+            "formfield_callback": old_formfield_callback,
+        }
+        defaults.update(kwargs)
+        language = self._language(request)
+        return translatable_modelform_factory(language, self.model, **defaults)
+
+
+class NewsboxHVADAdmin(NewsboxHVADBaseAdmin):
+    pass
diff --git a/newsbox_hvad/models.py b/newsbox_hvad/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..18960f0fc008abdef97410fb62ae73a681e29757
--- /dev/null
+++ b/newsbox_hvad/models.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import sys
+
+from django.db import models
+from django.core.urlresolvers import reverse
+from django.utils.translation import ugettext_lazy as _,  get_language, activate
+from django.utils import six
+from django.utils.encoding import python_2_unicode_compatible
+from hvad.manager import TranslationManager
+from hvad.models import TranslatableModel, TranslatedFields, \
+    TranslatableModelBase
+from newsbox.models import NewsboxModelBase, NewsboxManager, \
+    NewsboxBase, newsbox_models
+
+
+class NewsboxHVADManager(TranslationManager, NewsboxManager):
+    pass
+
+def newsboxhvad_mcls_processor(mcls, class_name, class_bases, class_attrs, base, newsbox_opts):
+    translatedFields={}
+    for trans_field in newsbox_opts['trans_fieldnames']:
+        translatedFields[trans_field] = class_attrs.pop(trans_field)
+    class_attrs['translations'] = TranslatedFields(**translatedFields)
+    class_attrs['newsbox_objects'] = NewsboxHVADManager()
+    #class_attrs['default_manager'] = class_attrs['newsbox_objects']
+
+
+class NewsboxHVADModelBase(NewsboxModelBase, TranslatableModelBase):
+    pass
+
+
+@python_2_unicode_compatible
+class NewsboxHVADBase(six.with_metaclass(NewsboxHVADModelBase, TranslatableModel)):
+    """
+    Define News which expires in time and will not be displayed in front
+    """
+
+    default_manager = NewsboxHVADManager()
+    objects = default_manager
+
+    def __str__(self):
+        return self.lazy_translation_getter(
+            'newsbox_title',
+            _('News n° %s') % self.pk)
+
+    def get_slug(self, language=None, *args, **kwargs):
+        """
+        Returns the slug for this object for the given language.
+        """
+        if language is None or language == self.language_code:
+            return self.safe_translation_getter('newsbox_slug')
+        else:
+            instance = self.__class__.objects.language(language).get(pk=self.pk)
+            return instance.safe_translation_getter('newsbox_slug')
+
+    def get_absolute_url(self, language=None, *args, **kwargs):
+        """
+        Build url for the given language.
+        """
+        current_language = get_language()
+
+        if not language:
+            language = current_language
+
+        if language in self.get_available_languages():
+            activate(language)
+            url = reverse(self._newsbox_meta['detail_url_name'], args=(
+                self.newsbox_date.strftime("%Y"),
+                self.newsbox_date.strftime("%m"),
+                self.newsbox_date.strftime("%d"),
+                self.get_slug(language=language),))
+            activate(current_language)
+            return url
+
+        return "./"
+
+
+    class Meta:
+        abstract = True
+        verbose_name = _('news')
+        verbose_name_plural = _('news')
+        #newsbox_metaclass_base_processor = 'newsboxhvad_mcls_processor'
+        newsbox_metaclass_final_processor = 'newsboxhvad_mcls_processor'
diff --git a/newsbox_hvad/urls.py b/newsbox_hvad/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..ca160a4bf2d536932ce4cdd34c9502253badc15c
--- /dev/null
+++ b/newsbox_hvad/urls.py
@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns
+from newsbox.urls import get_urls
+
+from .views import NewsboxHVADDetailView
+
+urls = get_urls(detail_view=NewsboxHVADDetailView)
+urlpatterns = patterns(*urls)
diff --git a/newsbox_hvad/views.py b/newsbox_hvad/views.py
new file mode 100644
index 0000000000000000000000000000000000000000..209f38ab3c90f7a0ca4959cdc77d392457d980e3
--- /dev/null
+++ b/newsbox_hvad/views.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from newsbox.views import NewsboxDetailView
+
+class NewsboxHVADDetailView(NewsboxDetailView):
+
+    def get_queryset(self):
+        """
+        As slug_field is translated, we need to use translation aware
+        queryset.
+        """
+        return self.model.objects.using_translations()
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000000000000000000000000000000000000..9c201cfda104f9206a629e8a453c445a05eabb89
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from setuptools import setup, find_packages
+import os
+import newsbox
+
+
+CLASSIFIERS = [
+    'Development Status :: 5 - Production/Stable',
+    'Environment :: Web Environment',
+    'Framework :: Django',
+    'Intended Audience :: Developers',
+    'License :: OSI Approved :: BSD License',
+    'Operating System :: OS Independent',
+    'Programming Language :: Python',
+    'Topic :: Internet :: WWW/HTTP :: Dynamic Content',
+    'Topic :: Software Development',
+    'Topic :: Software Development :: Libraries :: Application Frameworks',
+    "Programming Language :: Python :: 2.6",
+    "Programming Language :: Python :: 2.7",
+    "Programming Language :: Python :: 3.3",
+]
+
+setup(
+    author="Dylann Cordel",
+    author_email="d.cordel@webu.coop",
+    name='django-newsbox',
+    version=newsbox.__version__,
+    description='A Django and Django CMS APP providing news support',
+    long_description=open(os.path.join(os.path.dirname(__file__), 'README.md')).read(),
+    url='https://dev.webu.coop/webu/django-newsbox',
+    license='BSD License',
+    platforms=['OS Independent'],
+    classifiers=CLASSIFIERS,
+    install_requires=[
+        'Django>=1.6,<1.7',
+    ],
+    packages=find_packages(exclude=["project", "project.*"]),
+    include_package_data=True,
+    zip_safe=False,
+)
diff --git a/test_requirements/django-1.6.txt b/test_requirements/django-1.6.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9cec9f618eda058f22b41cbaf04b5620fce6cd9d
--- /dev/null
+++ b/test_requirements/django-1.6.txt
@@ -0,0 +1,3 @@
+-r requirements_base.txt
+django>=1.6,<1.7
+https://github.com/KristianOellegaard/django-hvad/archive/master.zip#egg=hvad
diff --git a/test_requirements/django-1.6_cms-3.0.txt b/test_requirements/django-1.6_cms-3.0.txt
new file mode 100644
index 0000000000000000000000000000000000000000..2b2c0972a9b20f03e411a05d14236fed9c2069c3
--- /dev/null
+++ b/test_requirements/django-1.6_cms-3.0.txt
@@ -0,0 +1,37 @@
+# Currently, 3.0 is not yet released, so we use the develop branch
+git+https://github.com/divio/django-cms.git@develop#egg=django-cms
+
+# This is django-cms test requirements
+
+django>=1.6,<1.7
+django-reversion>=1.8
+
+coverage==3.7
+python-coveralls==2.4.0
+docopt==0.6.1
+unittest-xml-reporting==1.0.3
+sphinx
+Pillow==2.0
+django-classy-tags>=0.5
+South>=0.7.2
+html5lib>=0.90
+django-mptt>=0.6
+django-sekizai>=0.7
+argparse
+dj-database-url
+selenium
+django-debug-toolbar
+https://github.com/KristianOellegaard/django-hvad/archive/master.zip#egg=hvad
+-e git+git://github.com/divio/djangocms-admin-style.git#egg=djangocms-admin-style
+-e git+git://github.com/divio/djangocms-text-ckeditor.git#egg=djangocms-text-ckeditor
+-e git+git://github.com/divio/djangocms-column.git#egg=djangocms-column
+-e git+git://github.com/divio/djangocms-style.git#egg=djangocms-style
+-e git+git://github.com/divio/djangocms-file.git#egg=djangocms-file
+-e git+git://github.com/divio/djangocms-flash.git#egg=djangocms-flash
+-e git+git://github.com/divio/djangocms-googlemap.git#egg=djangocms-googlemap
+-e git+git://github.com/divio/djangocms-inherit.git#egg=djangocms-inherit
+-e git+git://github.com/divio/djangocms-picture.git#egg=djangocms-picture
+-e git+git://github.com/divio/djangocms-teaser.git#egg=djangocms-teaser
+-e git+git://github.com/divio/djangocms-video.git#egg=djangocms-video
+-e git+git://github.com/divio/djangocms-link.git#egg=djangocms-link
+pyflakes
diff --git a/test_requirements/requirements_base.txt b/test_requirements/requirements_base.txt
new file mode 100644
index 0000000000000000000000000000000000000000..66f9b96ea8e6d0c687f99422c8cf031bf35578c3
--- /dev/null
+++ b/test_requirements/requirements_base.txt
@@ -0,0 +1,3 @@
+south>=0.7.2
+pytz
+beautifulsoup4
diff --git a/tests/myapp/README.md b/tests/myapp/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..635d7799195e509b623cb97c955cd499464b8bca
--- /dev/null
+++ b/tests/myapp/README.md
@@ -0,0 +1,90 @@
+initial fixtures
+================
+
+## News
+
+If not precised, news have those default values :
+
+* newsbox_slug                      : news-%(pk)d
+* newsbox_title                     : News %(pk)d
+* newsbox_date                      : 2014-02-22 10:00:00
+* newsbox_publication_start_date    : 1985-07-02 10:00:00
+* newsbox_published                 : True
+* newsbox_summary                   : Summary of the news %(pk)d
+* newsbox_body                      : Body of the news %(pk)d
+
+### List of all available test News
+
+1. A basic classic published news 
+2. A not published news via newsbox_published
+ * newsbox_published = False
+3. A not published news via newsbox_publication_start_date
+ * newsbox_publication_start_date = 2020-01-01 10:00:00
+4. A published news without body
+ * newsbox_body = ''
+5. A not published news via newsbox_published (same as #2)
+ * newsbox_published = False
+6. A published news about an old event
+ * newsbox_date = 2005-07-15 10:00:00
+7. A published news about a future event
+ * newsbox_date = 2020-01-01 10:00:00
+
+## NewsExpired
+
+If not precised, Expired news have default values from news for classic news 
+fields and those values for specific Expired news fields :
+
+* newsbox_publication_end_date      : 2014-02-22 10:00:00
+
+### List of all available test NewsExpired
+
+* from 1 to 4 : same as News
+5. A not published news via his expiration's date
+ * newsbox_publication_end_date = 2000-01-01 10:00:00
+* from 6 to 7 : same as News
+
+## NewsSEO
+
+If not precised, SEO news have default values from news for classic news fields
+and those values for specific SEO news fields :
+
+* newsbox_indexed                   : True
+* newsbox_meta_description          : Meta description of the news %(pk)d
+* newsbox_meta_keywords             : keyword1, keyword2, news-%(pk)d
+
+### List of all available test NewsExpired
+
+* from 1 to 5 : same as News
+6. same as #6 of News but not indexed news via newsbox_indexed
+ * newsbox_indexed = False
+7. same as #7 of News
+
+## NewsComplete
+
+If not precised, Complete news have default values from news for classic news 
+fields, from NewsSEO for seo fields, from NewsExpired for expired fields.
+
+### List of all available test NewsComplete
+
+* from 1 to 5 : same as NewsExpired
+6. Same as #6 of NewsSEO
+7. same as #7 of News
+
+## NewsExtended
+
+If not precised, Complete news have default values from news for classic news 
+fields, from NewsSEO for seo fields, from NewsExpired for expired fields and 
+those values for specific NewsExtended news fields :
+
+* general_field                     : Test
+* content_field                     : Extra content of the news %(pk)d
+* seo_field                         : Extra SEO of the news %(pk)d
+
+### List of all available test NewsExtended
+
+* from 1 to 7 : same as NewsComplete
+
+## Code used to generate test news
+
+You can see the code used to generate initial fixtures in utils.py in this 
+directory.
diff --git a/tests/myapp/__init__.py b/tests/myapp/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26
--- /dev/null
+++ b/tests/myapp/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/tests/myapp/admin.py b/tests/myapp/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..10fbc62d88a4dbf713c5dca5c2a52cc343f4480c
--- /dev/null
+++ b/tests/myapp/admin.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from django.contrib import admin
+from newsbox.admin import NewsboxAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin
+
+from .models import News, NewsSEO, NewsExpired, NewsComplete, NewsExtended
+
+class NewsAdmin(NewsboxAdmin):
+    pass
+
+admin.site.register(News, NewsAdmin)
+
+
+class NewsSEOAdmin(NewsboxSEOAdmin):
+    pass
+
+admin.site.register(NewsSEO, NewsSEOAdmin)
+
+
+class NewsExpiredAdmin(NewsboxExpiredAdmin):
+    pass
+
+admin.site.register(NewsExpired, NewsExpiredAdmin)
+
+
+class NewsCompleteAdmin(NewsboxSEOAdmin, NewsboxExpiredAdmin):
+    pass
+
+admin.site.register(NewsComplete, NewsCompleteAdmin)
+
+
+class NewsExtendedAdmin(NewsboxSEOAdmin, NewsboxExpiredAdmin):
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(NewsExtendedAdmin, self).get_fieldsets(request, obj)
+        fieldsets[0][1]['fields'].append('general_field')
+        fieldsets[2][1]['fields'].append('content_field')
+        fieldsets[3][1]['fields'].append('seo_field')
+        return fieldsets
+
+    def get_list_display(self, request):
+        list_display = super(NewsExtendedAdmin, self).get_list_display(request)
+        list_display.append('seo_field')
+        return list_display
+
+admin.site.register(NewsExtended, NewsExtendedAdmin)
diff --git a/tests/myapp/fixtures/tests_data.json b/tests/myapp/fixtures/tests_data.json
new file mode 100644
index 0000000000000000000000000000000000000000..7b70649815cb535af9c5d7c92a5d95b7c4b9d50d
--- /dev/null
+++ b/tests/myapp/fixtures/tests_data.json
@@ -0,0 +1,632 @@
+[
+{
+    "pk": 1, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-1", 
+        "newsbox_creation_date": "2014-03-11T13:54:03.213Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 1", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_changed_date": "2014-03-11T13:54:03.213Z", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_slug": "news-2", 
+        "newsbox_creation_date": "2014-03-11T13:54:03.398Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 2", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_changed_date": "2014-03-11T13:54:03.398Z", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-3", 
+        "newsbox_creation_date": "2014-03-11T13:54:03.598Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 3", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_changed_date": "2014-03-11T13:54:03.598Z", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-4", 
+        "newsbox_creation_date": "2014-03-11T13:54:03.882Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 4", 
+        "newsbox_body": "", 
+        "newsbox_changed_date": "2014-03-11T13:54:03.882Z", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_slug": "news-5", 
+        "newsbox_creation_date": "2014-03-11T13:54:04.083Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 5", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_changed_date": "2014-03-11T13:54:04.083Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-6", 
+        "newsbox_creation_date": "2014-03-11T13:54:04.293Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 6", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_changed_date": "2014-03-11T13:54:04.293Z", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-7", 
+        "newsbox_creation_date": "2014-03-11T13:54:04.502Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 7", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_changed_date": "2014-03-11T13:54:04.503Z", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_creation_date": "2014-03-11T13:54:01.813Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 1", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_changed_date": "2014-03-11T13:54:01.813Z", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_creation_date": "2014-03-11T13:54:02.005Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 2", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_changed_date": "2014-03-11T13:54:02.005Z", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_creation_date": "2014-03-11T13:54:02.201Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 3", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_changed_date": "2014-03-11T13:54:02.201Z", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_creation_date": "2014-03-11T13:54:02.408Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 4", 
+        "newsbox_body": "", 
+        "newsbox_changed_date": "2014-03-11T13:54:02.408Z", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_creation_date": "2014-03-11T13:54:02.602Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 5", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_changed_date": "2014-03-11T13:54:02.602Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_creation_date": "2014-03-11T13:54:02.810Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_indexed": false, 
+        "newsbox_summary": "Summary of the news 6", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_changed_date": "2014-03-11T13:54:02.810Z", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp.newsseo", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_creation_date": "2014-03-11T13:54:03.019Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 7", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_changed_date": "2014-03-11T13:54:03.019Z", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-1", 
+        "newsbox_changed_date": "2014-03-11T13:53:50.409Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:50.409Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 1", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_slug": "news-2", 
+        "newsbox_changed_date": "2014-03-11T13:53:50.593Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:50.593Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 2", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-3", 
+        "newsbox_changed_date": "2014-03-11T13:53:50.795Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:50.795Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 3", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-4", 
+        "newsbox_changed_date": "2014-03-11T13:53:50.988Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:50.988Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 4", 
+        "newsbox_body": "", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-5", 
+        "newsbox_changed_date": "2014-03-11T13:53:51.196Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:51.196Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 5", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-6", 
+        "newsbox_changed_date": "2014-03-11T13:53:51.406Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:51.406Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 6", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp.newsexpired", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-7", 
+        "newsbox_changed_date": "2014-03-11T13:53:51.589Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:51.589Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_summary": "Summary of the news 7", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_changed_date": "2014-03-11T13:53:28.605Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:28.605Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 1", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_changed_date": "2014-03-11T13:53:28.763Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:28.763Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 2", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_changed_date": "2014-03-11T13:53:28.947Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:28.947Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 3", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_changed_date": "2014-03-11T13:53:29.125Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:29.125Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 4", 
+        "newsbox_body": "", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_changed_date": "2014-03-11T13:53:29.368Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:29.368Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 5", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_changed_date": "2014-03-11T13:53:29.594Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:29.594Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_indexed": false, 
+        "newsbox_summary": "Summary of the news 6", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_changed_date": "2014-03-11T13:53:29.787Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:29.787Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "Summary of the news 7", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "Extra content of the news 1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_changed_date": "2014-03-11T13:53:49.052Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:49.052Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "seo_field": "Extra SEO of the news 1", 
+        "newsbox_summary": "Summary of the news 1", 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "content_field": "Extra content of the news 2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_changed_date": "2014-03-11T13:53:49.243Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:49.243Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "seo_field": "Extra SEO of the news 2", 
+        "newsbox_summary": "Summary of the news 2", 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "Extra content of the news 3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_changed_date": "2014-03-11T13:53:49.445Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:49.445Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "seo_field": "Extra SEO of the news 3", 
+        "newsbox_summary": "Summary of the news 3", 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "Extra content of the news 4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_changed_date": "2014-03-11T13:53:49.629Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:49.629Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "seo_field": "Extra SEO of the news 4", 
+        "newsbox_summary": "Summary of the news 4", 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "newsbox_body": "", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "content_field": "Extra content of the news 5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_changed_date": "2014-03-11T13:53:49.830Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:49.830Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "seo_field": "Extra SEO of the news 5", 
+        "newsbox_summary": "Summary of the news 5", 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "Extra content of the news 6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_changed_date": "2014-03-11T13:53:50.016Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:50.016Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": false, 
+        "seo_field": "Extra SEO of the news 6", 
+        "newsbox_summary": "Summary of the news 6", 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "Extra content of the news 7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_changed_date": "2014-03-11T13:53:50.208Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:50.208Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "seo_field": "Extra SEO of the news 7", 
+        "newsbox_summary": "Summary of the news 7", 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 7"
+    }
+}
+]
diff --git a/tests/myapp/models.py b/tests/myapp/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..eddc3fd82ca67fe2ca4c24a85aeebb2f82385c32
--- /dev/null
+++ b/tests/myapp/models.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from django.db import models
+from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase
+
+class News(NewsboxBase):
+    class Meta:
+        verbose_name = 'news - Basic'
+        verbose_name_plural = 'news - Basic'
+
+class NewsSEO(NewsboxBase, NewsboxSEOBase):
+    class Meta:
+        verbose_name = 'news - SEO'
+        verbose_name_plural = 'news - SEO'
+
+class NewsExpired(NewsboxBase, NewsboxExpiredBase):
+    class Meta:
+        verbose_name = 'news - Expirable'
+        verbose_name_plural = 'news - Expirable'
+
+class NewsComplete(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase):
+    class Meta:
+        verbose_name = 'news - Complete'
+        verbose_name_plural = 'news - Complete'
+
+class NewsExtended(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase):
+    general_field = models.CharField(max_length=50)
+    content_field = models.CharField(max_length=50)
+    seo_field = models.CharField(max_length=50)
+    
+    class Meta:
+        verbose_name = 'news - Extended'
+        verbose_name_plural = 'news - Extended'
diff --git a/tests/myapp/tests.py b/tests/myapp/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9ca0137a6e480e9cd0bcd97eb82fd7ad834c9be
--- /dev/null
+++ b/tests/myapp/tests.py
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from django.test import TestCase, Client
+from django.core.paginator import EmptyPage
+from bs4 import BeautifulSoup
+from .models import News, NewsSEO, NewsExpired, NewsComplete, NewsExtended
+
+
+class NewsboxAbstractModelsTests(TestCase):
+
+    fixtures = ['tests_data.json',]
+    
+    def test_01_manager_published(self):
+        """
+        Test if we only get really published news via the manager
+        """
+        newsClasses = [
+            News, NewsSEO, NewsExpired, NewsComplete, NewsExtended,
+        ]
+        for cls in newsClasses:
+            returned_ids = list(cls.objects.published().values_list(
+                'id', flat=True).order_by('id'))
+            self.assertEqual(
+                (cls.__name__,returned_ids), 
+                (cls.__name__,[1, 4, 6, 7,]))
+    
+    def test_02_view_archive_200(self):
+        """
+        Test if generic archive view return right informations.
+        """
+        c = Client()
+        r = c.get('/news/')
+
+        self.assertEqual(r.status_code, 200)
+        self.assertIn('newsset', r.context)
+        self.assertEqual(r.context['newsset'][0].pk, 7)
+        self.assertEqual(r.context['newsset'].number, 1)
+        self.assertEqual(r.context['newsset'].paginator.num_pages, 4)
+        self.assertFalse(r.context['newsset'].has_previous())
+        self.assertTrue(r.context['newsset'].has_next())
+        self.assertRaises(EmptyPage, r.context['newsset'].previous_page_number)
+        self.assertEqual(r.context['newsset'].next_page_number(), 2)
+        
+    
+    def test_03_view_year_archive_200(self):
+        """
+        Test if generic year views return right informations.
+        """
+        c = Client()
+        r = c.get('/news/2005/')
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.context['newsset'][0].pk, 6)
+        self.assertFalse(r.context['with_pager'])
+        r = c.get('/news/2014/')
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.context['newsset'].paginator.num_pages, 2)
+        r = c.get('/news/2020/')
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.context['newsset'].paginator.num_pages, 1)
+
+    def test_04_view_year_archive_404(self):
+        """
+        Test if generic year views return a 404 with an URL with a year without
+        any news.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/1985/')
+        self.assertEqual(r.status_code, 404)
+    
+    def test_05_view_month_archive_200(self):
+        """
+        Test if generic month views return right informations.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/2005/07/')
+        self.assertEqual(r.status_code, 200)
+        ref = c.get('/newsbox/myapp/news/2005/')
+        self.assertEqual(r.content, ref.content)
+
+    def test_06_view_month_archive_404(self):
+        """
+        Test if generic month views return a 404 with an URL with a year + month
+        without any news.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/1985/07/')
+        self.assertEqual(r.status_code, 404)
+    
+    def test_07_view_day_archive_200(self):
+        """
+        Test if generic day views return right informations.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/2005/07/15/')
+        self.assertEqual(r.status_code, 200)
+        ref = c.get('/newsbox/myapp/news/2005/07/')
+        self.assertEqual(r.content, ref.content)
+
+    def test_08_view_month_archive_404(self):
+        """
+        Test if generic day views return a 404 with an URL with a date without 
+        any news.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/1985/07/02/')
+        self.assertEqual(r.status_code, 404)
+
+    def test_09_view_detail_200(self):
+        """
+        Test if generic day views return right informations.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/2005/07/15/news-6/')
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.context['news'].pk, 6)
+
+    def test_10_view_detail_404(self):
+        """
+        Test if generic day views return a 404 with an URL with a date without 
+        any news.
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/1985/07/02/my-birthday/')
+        self.assertEqual(r.status_code, 404)
+
+    def test_11_view_detail_404_not_published(self):
+        """
+        Test if generic day views return a 404 with an URL with a not published
+        news
+        """
+        c = Client()
+        r = c.get('/newsbox/myapp/news/2014/02/22/news-2/')
+        self.assertEqual(r.status_code, 404)
+
+    def has_readmore_link(self, news):
+        readmore_p = news.find('p', class_='readmore')
+        if readmore_p:
+            readmore_a = readmore_p.find('a')
+            if readmore_a:
+                return True
+
+        return False
+
+    def get_news_in_list_by_summary(self, response, summary):
+        soup = BeautifulSoup(response.content)
+        for news in soup.find_all('div', class_='news'):
+            readmore_summary = news.find('p', text=summary)
+            if readmore_summary:
+                return news
+        return None
+
+    def test_news_4_has_no_readmore_link(self):
+        """
+        Test if readmore link is not present in news 4
+        """
+        c = Client()
+        r = c.get('/news/?page=2')
+        news = self.get_news_in_list_by_summary(r, u'Summary of the news 4')
+        self.assertIsNotNone(news)
+
+        found = self.has_readmore_link(news)
+        self.assertFalse(found)
+
+    def test_news_6_has_readmore_link(self):
+        """
+        Test if readmore link is present in news 6
+        """
+        c = Client()
+        r = c.get('/news/2005/')
+        news = self.get_news_in_list_by_summary(r, u'Summary of the news 6')
+        self.assertIsNotNone(news)
+  
+        found = self.has_readmore_link(news)
+        self.assertTrue(found)
diff --git a/tests/myapp/urls.py b/tests/myapp/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddb3e6932166578a67fdba119c96fd9ad30e8a3b
--- /dev/null
+++ b/tests/myapp/urls.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import url, include, patterns
+from django.contrib import admin
+from django.conf import settings
+from newsbox.views import NewsboxYearArchiveView, NewsboxArchiveView
+
+from .models import News
+
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    url(r'^admin/', include(admin.site.urls)),
+    url(r'^', include('newsbox.urls')),
+    url(r'^news/$', 
+        NewsboxArchiveView.as_view(model=News, paginate_by=1), 
+        name='news_list',),
+    url(r'^news/(?P<year>\d{4})/$', 
+        NewsboxYearArchiveView.as_view(model=News, paginate_by=1), 
+        name='news_list_y',),
+)
diff --git a/tests/myapp_all/__init__.py b/tests/myapp_all/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26
--- /dev/null
+++ b/tests/myapp_all/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/tests/myapp_all/admin.py b/tests/myapp_all/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..95ff7bb7784ef79cc2ea61b1e867ed6d45a623f8
--- /dev/null
+++ b/tests/myapp_all/admin.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+from django.contrib import admin
+from newsbox_cms.admin import NewsboxCMSAdmin
+from newsbox.admin import NewsboxSEOAdmin, NewsboxExpiredAdmin
+from newsbox_hvad.admin import NewsboxHVADAdmin
+
+from .models import News, NewsComplete, NewsExtended
+
+class NewsAdmin(NewsboxHVADAdmin, NewsboxCMSAdmin):
+    pass
+
+admin.site.register(News, NewsAdmin)
+
+
+class NewsCompleteAdmin(NewsboxHVADAdmin, NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin):
+    pass
+
+admin.site.register(NewsComplete, NewsCompleteAdmin)
+
+
+class NewsExtendedAdmin(NewsboxHVADAdmin, NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin):
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(NewsExtendedAdmin, self).get_fieldsets(request, obj)
+        fieldsets[0][1]['fields'].append('general_field')
+        fieldsets[2][1]['fields'].append('content_field')
+        fieldsets[3][1]['fields'].append('seo_field')
+        return fieldsets
+
+    def get_list_display(self, request):
+        list_display = super(NewsExtendedAdmin, self).get_list_display(request)
+        list_display.append('seo_field')
+        return list_display
+
+admin.site.register(NewsExtended, NewsExtendedAdmin)
diff --git a/tests/myapp_all/cms_app.py b/tests/myapp_all/cms_app.py
new file mode 100644
index 0000000000000000000000000000000000000000..d25c3bee48b54eb42e1f5658856af3e60b9e806c
--- /dev/null
+++ b/tests/myapp_all/cms_app.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+from cms.app_base import CMSApp
+from cms.apphook_pool import apphook_pool
+
+class NewsApphook(CMSApp):
+    name = 'News'
+    urls = ["myapp_all.urls_news"]
+
+apphook_pool.register(NewsApphook)
diff --git a/tests/myapp_all/cms_plugins.py b/tests/myapp_all/cms_plugins.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae203265d409663e0a02c615dbd2a1c312a9aa2b
--- /dev/null
+++ b/tests/myapp_all/cms_plugins.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+from cms.plugin_pool import plugin_pool
+from newsbox_cms.cms_plugins import NewsboxPluginBase
+
+from .models import NewsPlugin as NewsPluginModel
+
+
+class NewsPlugin(NewsboxPluginBase):
+    name = "News list ALL" # Name of the plugin
+    model = NewsPluginModel
+
+plugin_pool.register_plugin(NewsPlugin) 
diff --git a/tests/myapp_all/fixtures/tests_data.json b/tests/myapp_all/fixtures/tests_data.json
new file mode 100644
index 0000000000000000000000000000000000000000..d81809eec81375f4ee57481426c703bcffa393a0
--- /dev/null
+++ b/tests/myapp_all/fixtures/tests_data.json
@@ -0,0 +1,835 @@
+[
+{
+    "pk": 1, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 1, 
+        "newsbox_slug": "news-1", 
+        "newsbox_title": "News 1", 
+        "newsbox_summary": "<p>Summary of the news 1</p>"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 1, 
+        "newsbox_slug": "actualite-1", 
+        "newsbox_title": "Actualit\u00e9 1", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 1</p>"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 2, 
+        "newsbox_slug": "news-2", 
+        "newsbox_title": "News 2", 
+        "newsbox_summary": "<p>Summary of the news 2</p>"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 2, 
+        "newsbox_slug": "actualite-2", 
+        "newsbox_title": "Actualit\u00e9 2", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 2</p>"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 3, 
+        "newsbox_slug": "news-3", 
+        "newsbox_title": "News 3", 
+        "newsbox_summary": "<p>Summary of the news 3</p>"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 3, 
+        "newsbox_slug": "actualite-3", 
+        "newsbox_title": "Actualit\u00e9 3", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 3</p>"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 4, 
+        "newsbox_slug": "news-4", 
+        "newsbox_title": "News 4", 
+        "newsbox_summary": "<p>Summary of the news 4</p>"
+    }
+},
+{
+    "pk": 8, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 4, 
+        "newsbox_slug": "actualite-4", 
+        "newsbox_title": "Actualit\u00e9 4", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 4</p>"
+    }
+},
+{
+    "pk": 9, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 5, 
+        "newsbox_slug": "news-5", 
+        "newsbox_title": "News 5", 
+        "newsbox_summary": "<p>Summary of the news 5</p>"
+    }
+},
+{
+    "pk": 10, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 5, 
+        "newsbox_slug": "actualite-5", 
+        "newsbox_title": "Actualit\u00e9 5", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 5</p>"
+    }
+},
+{
+    "pk": 11, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 6, 
+        "newsbox_slug": "news-6", 
+        "newsbox_title": "News 6", 
+        "newsbox_summary": "<p>Summary of the news 6</p>"
+    }
+},
+{
+    "pk": 12, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 6, 
+        "newsbox_slug": "actualite-6", 
+        "newsbox_title": "Actualit\u00e9 6", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 6</p>"
+    }
+},
+{
+    "pk": 13, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "en", 
+        "master": 7, 
+        "newsbox_slug": "news-7", 
+        "newsbox_title": "News 7", 
+        "newsbox_summary": "<p>Summary of the news 7</p>"
+    }
+},
+{
+    "pk": 14, 
+    "model": "myapp_all.newstranslation", 
+    "fields": {
+        "language_code": "fr", 
+        "master": 7, 
+        "newsbox_slug": "actualite-7", 
+        "newsbox_title": "Actualit\u00e9 7", 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 7</p>"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_creation_date": "2014-03-29T14:22:26.190Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_body": 24, 
+        "newsbox_changed_date": "2014-03-29T14:22:26.717Z"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_creation_date": "2014-03-29T14:22:27.254Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_body": 27, 
+        "newsbox_changed_date": "2014-03-29T14:22:27.782Z"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_creation_date": "2014-03-29T14:22:28.279Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_body": 30, 
+        "newsbox_changed_date": "2014-03-29T14:22:28.907Z"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_creation_date": "2014-03-29T14:22:29.718Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_body": 33, 
+        "newsbox_changed_date": "2014-03-29T14:22:30.273Z"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_creation_date": "2014-03-29T14:22:30.760Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_body": 36, 
+        "newsbox_changed_date": "2014-03-29T14:22:31.355Z"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_creation_date": "2014-03-29T14:22:31.842Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_body": 39, 
+        "newsbox_changed_date": "2014-03-29T14:22:32.397Z"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_all.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_creation_date": "2014-03-29T14:22:32.892Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_body": 42, 
+        "newsbox_changed_date": "2014-03-29T14:22:33.428Z"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "master": 1, 
+        "newsbox_summary": "<p>Summary of the news 1</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", 
+        "newsbox_slug": "actualite-1", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", 
+        "master": 1, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 1</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 1"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "master": 2, 
+        "newsbox_summary": "<p>Summary of the news 2</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", 
+        "newsbox_slug": "actualite-2", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", 
+        "master": 2, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 2</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 2"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "master": 3, 
+        "newsbox_summary": "<p>Summary of the news 3</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", 
+        "newsbox_slug": "actualite-3", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", 
+        "master": 3, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 3</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 3"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "master": 4, 
+        "newsbox_summary": "<p>Summary of the news 4</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 8, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", 
+        "newsbox_slug": "actualite-4", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", 
+        "master": 4, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 4</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 4"
+    }
+},
+{
+    "pk": 9, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "master": 5, 
+        "newsbox_summary": "<p>Summary of the news 5</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 10, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", 
+        "newsbox_slug": "actualite-5", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", 
+        "master": 5, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 5</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 5"
+    }
+},
+{
+    "pk": 11, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "master": 6, 
+        "newsbox_summary": "<p>Summary of the news 6</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 12, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", 
+        "newsbox_slug": "actualite-6", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", 
+        "master": 6, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 6</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 6"
+    }
+},
+{
+    "pk": 13, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "master": 7, 
+        "newsbox_summary": "<p>Summary of the news 7</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 14, 
+    "model": "myapp_all.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", 
+        "newsbox_slug": "actualite-7", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", 
+        "master": 7, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 7</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:34.561Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:34.018Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 45, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-29T14:22:35.785Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:35.132Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 48, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:36.926Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:36.389Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 51, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:38.026Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:37.480Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 54, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-29T14:22:39.167Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:38.580Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 57, 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:40.374Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:39.779Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_indexed": false, 
+        "newsbox_body": 60, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_all.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:41.557Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:40.920Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 63, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "content_field": "Extra content of the news 1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "seo_field": "Extra SEO of the news 1", 
+        "master": 1, 
+        "newsbox_summary": "<p>Summary of the news 1</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 1", 
+        "newsbox_slug": "actualite-1", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 1", 
+        "master": 1, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 1</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 1"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "content_field": "Extra content of the news 2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "seo_field": "Extra SEO of the news 2", 
+        "master": 2, 
+        "newsbox_summary": "<p>Summary of the news 2</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 2", 
+        "newsbox_slug": "actualite-2", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 2", 
+        "master": 2, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 2</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 2"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "content_field": "Extra content of the news 3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "seo_field": "Extra SEO of the news 3", 
+        "master": 3, 
+        "newsbox_summary": "<p>Summary of the news 3</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 3", 
+        "newsbox_slug": "actualite-3", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 3", 
+        "master": 3, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 3</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 3"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "content_field": "Extra content of the news 4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "seo_field": "Extra SEO of the news 4", 
+        "master": 4, 
+        "newsbox_summary": "<p>Summary of the news 4</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 8, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 4", 
+        "newsbox_slug": "actualite-4", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 4", 
+        "master": 4, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 4</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 4"
+    }
+},
+{
+    "pk": 9, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "content_field": "Extra content of the news 5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "seo_field": "Extra SEO of the news 5", 
+        "master": 5, 
+        "newsbox_summary": "<p>Summary of the news 5</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 10, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 5", 
+        "newsbox_slug": "actualite-5", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 5", 
+        "master": 5, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 5</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 5"
+    }
+},
+{
+    "pk": 11, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "content_field": "Extra content of the news 6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "seo_field": "Extra SEO of the news 6", 
+        "master": 6, 
+        "newsbox_summary": "<p>Summary of the news 6</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 12, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 6", 
+        "newsbox_slug": "actualite-6", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 6", 
+        "master": 6, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 6</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 6"
+    }
+},
+{
+    "pk": 13, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "content_field": "Extra content of the news 7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "seo_field": "Extra SEO of the news 7", 
+        "master": 7, 
+        "newsbox_summary": "<p>Summary of the news 7</p>", 
+        "language_code": "en", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 14, 
+    "model": "myapp_all.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 7", 
+        "newsbox_slug": "actualite-7", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 7", 
+        "master": 7, 
+        "newsbox_summary": "<p>R\u00e9sum\u00e9 de l'actualit\u00e9 7</p>", 
+        "language_code": "fr", 
+        "newsbox_title": "Actualit\u00e9 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:18.579Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:18.020Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 3, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-29T14:22:19.795Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:19.234Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 6, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:21.070Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:20.334Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 9, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:22.186Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:21.608Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 12, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-29T14:22:23.352Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:22.748Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 15, 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:24.476Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:23.922Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": false, 
+        "newsbox_body": 18, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_all.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-29T14:22:25.617Z", 
+        "newsbox_creation_date": "2014-03-29T14:22:25.055Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_body": 21, 
+        "newsbox_publication_end_date": null
+    }
+}
+]
diff --git a/tests/myapp_all/models.py b/tests/myapp_all/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc25caa264c0e8a3e8df6261444dc59a435160cb
--- /dev/null
+++ b/tests/myapp_all/models.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase
+from newsbox_cms.models import NewsboxCMSBase, NewsboxPluginBase
+from newsbox_hvad.models import NewsboxHVADBase
+
+class News(NewsboxHVADBase, NewsboxBase, NewsboxCMSBase):
+    class Meta:
+        verbose_name = 'news - HVADCMS'
+        verbose_name_plural = 'news - HVADCMS'
+        newsbox_detail_url_name = 'news_detail'
+
+class NewsComplete(NewsboxHVADBase, NewsboxBase, NewsboxCMSBase, NewsboxSEOBase, NewsboxExpiredBase):
+    class Meta:
+        verbose_name = 'news - CompleteHVADCMS'
+        verbose_name_plural = 'news - CompleteHVADCMS'
+        newsbox_detail_url_name = 'newscomplete_detail'
+
+class NewsExtended(NewsboxHVADBase, NewsboxBase, NewsboxCMSBase, NewsboxSEOBase, NewsboxExpiredBase):
+    general_field = models.CharField(max_length=50)
+    content_field = models.CharField(max_length=50)
+    seo_field = models.CharField(max_length=50)
+    
+    class Meta:
+        verbose_name = 'news - ExtendedHVADCMS'
+        verbose_name_plural = 'news - ExtendedHVADCMS'
+        newsbox_trans_fieldnames = ['content_field', 'seo_field']
+        newsbox_detail_url_name = 'newsextended_detail'
+
+
+
+class NewsPlugin(NewsboxPluginBase):
+    newsbox_model = News
+
diff --git a/tests/myapp_all/templates/base.html b/tests/myapp_all/templates/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..914218d4ab6cf3f8b0e573e7cf62ea7bb0a026e7
--- /dev/null
+++ b/tests/myapp_all/templates/base.html
@@ -0,0 +1,13 @@
+{% load cms_tags sekizai_tags %}
+<html>
+    <head>
+        {% render_block "css" %}
+    </head>
+    <body>
+        {% cms_toolbar %}
+        <div style="margin-top:200px;">
+        {% block main %}{% endblock %}
+        </div>
+        {% render_block "js" %}
+    </body>
+</html>
diff --git a/tests/myapp_all/templates/list-cms.html b/tests/myapp_all/templates/list-cms.html
new file mode 100644
index 0000000000000000000000000000000000000000..726433cc7586ae1049bc637168ac31d8251a52d8
--- /dev/null
+++ b/tests/myapp_all/templates/list-cms.html
@@ -0,0 +1 @@
+{% extends "newsbox/list-cms.html" %}
diff --git a/tests/myapp_all/templates/page.html b/tests/myapp_all/templates/page.html
new file mode 100644
index 0000000000000000000000000000000000000000..4ed33cab160a992834bd4306fefbed218e42d3aa
--- /dev/null
+++ b/tests/myapp_all/templates/page.html
@@ -0,0 +1,6 @@
+{% extends "base.html" %}
+{% load cms_tags %}
+
+{% block main %}
+  {% placeholder main %}
+{% endblock %}
diff --git a/tests/myapp_all/tests.py b/tests/myapp_all/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..06a2feb2186509f35532709c69d715ed263c1e8a
--- /dev/null
+++ b/tests/myapp_all/tests.py
@@ -0,0 +1,140 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from copy import copy
+
+from django.test import TestCase, Client
+from django.contrib.auth.models import User
+from django.core.paginator import EmptyPage
+from django.utils.translation import activate
+from cms.test_utils.testcases import CMSTestCase
+from cms.plugin_rendering import render_plugin
+from cms.api import create_page, add_plugin, publish_page, create_title
+from djangocms_text_ckeditor.fields import HTMLField
+
+from .models import News, NewsComplete, NewsExtended, NewsPlugin as NewsPluginModel
+from .cms_plugins import NewsPlugin
+
+
+class NewsboxAbstractModelsTests(TestCase):
+
+    fixtures = ['tests_data.json',]
+    
+
+    def test_01_manager_published(self):
+        """
+        Test if we only get really published news via the manager
+        """
+        newsClasses = [
+            News, NewsComplete, NewsExtended,
+        ]
+        for cls in newsClasses:
+            returned_ids = list(cls.objects.published().values_list(
+                'id', flat=True).order_by('id'))
+            self.assertEqual(
+                (cls.__name__,returned_ids), 
+                (cls.__name__,[1, 4, 6, 7,]))
+
+    def test_02_summary_as_html_field(self):
+        """
+        Test if newsbox_summary field is HTMLField
+        """
+        newsClasses = [
+            News, NewsComplete, NewsExtended,
+        ]
+
+        for cls in newsClasses:
+            try:
+                transmodel = cls.translations.related.model
+                summary_field = transmodel._meta.get_field('newsbox_summary')
+            except:
+                self.fail('%s is not properly configured' % cls)
+            self.assertIsInstance(summary_field,HTMLField)
+
+
+class NewsboxPageIntegrationTests(CMSTestCase):
+
+    fixtures = ['tests_data.json',]
+
+    def setUp(self):
+        self.super_user = User(username="test", is_staff=True, is_active=True, is_superuser=True)
+        self.super_user.set_password("test")
+        self.super_user.save()
+        
+        home = create_page(title='Home', slug='home',
+            template='page.html', 
+            language='en', published=True,
+            reverse_id='home', in_navigation=True)
+
+        create_title('fr', 'Accueil', home, slug='accueil')
+        home.publish('en')
+        home.publish('fr')
+
+        self.page = create_page(title='News page', slug='news-page',
+            template='page.html', parent=home,
+            language='en', published=True, apphook='NewsApphook',
+            reverse_id='newspage', in_navigation=True)
+        create_title('fr', 'page Actualités', self.page, slug='page-actualites')
+        self.placeholder = self.page.placeholders.get(slot='main')
+
+        self.plugin_en = add_plugin(
+            self.placeholder, 'NewsPlugin', 'en', 
+            title = 'News',
+            numitems = 1,
+            with_pager = True,
+            page_link = None,)
+        self.plugin_en.save()
+
+        self.plugin_fr = add_plugin(
+            self.placeholder, 'NewsPlugin', 'fr', 
+            title = 'Actualités',
+            numitems = 1,
+            with_pager = True,
+            page_link = None,)
+        self.plugin_fr.save()
+        
+        self.page.publish('en')
+        self.page.publish('fr')
+        self.page.reload()
+        
+        self.newsPlugin = NewsPlugin()
+        self.placeholder = self.page.placeholders.get(slot='main')
+
+    def test_01_cmsplugin_context(self):
+        expected_results = {'en':'News 7', 'fr':'Actualité 7',}
+        for lang in expected_results:
+            activate(lang)
+            context = self.get_context(
+                self.page.get_absolute_url(), page=self.page)
+            self.newsPlugin.render(
+                context, 
+                getattr(self, 'plugin_%s' % lang), 
+                self.placeholder)
+            self.assertIn('newsset', context)
+            self.assertEqual(context['newsset'][0].pk, 7)
+            self.assertEqual(
+                context['newsset'][0].newsbox_title, 
+                expected_results[lang])
+            self.assertEqual(context['newsset'].number, 1)
+            self.assertEqual(context['newsset'].paginator.num_pages, 4)
+            self.assertFalse(context['newsset'].has_previous())
+            self.assertTrue(context['newsset'].has_next())
+            self.assertRaises(EmptyPage, context['newsset'].previous_page_number)
+            self.assertEqual(context['newsset'].next_page_number(), 2)
+
+    def test_02_wrong_language_404(self):
+        c = Client()
+        r_en = c.get('/en/news-page/2020/01/01/news-7/')
+        r_fr = c.get('/fr/page-actualites/2020/01/01/actualite-7/')
+        r_en_and_fr = c.get('/en/news-page/2020/01/01/actualite-7/')
+        self.assertEqual(r_en.status_code, 200)
+        self.assertEqual(r_fr.status_code, 200)
+        self.assertEqual(r_en_and_fr.status_code, 404)
+
+    def test_03_get_absolute_url(self):
+        news7 = News.objects.get(pk=7)
+        expected_results = {
+            'en':'/en/news-page/2020/01/01/news-7/', 
+            'fr':'/fr/page-actualites/2020/01/01/actualite-7/',}
+        for lang in expected_results:
+            activate(lang)
+            self.assertEqual(news7.get_absolute_url(), expected_results[lang])
diff --git a/tests/myapp_all/urls.py b/tests/myapp_all/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..1753ed9add8c09cd5088913304aa86d19782c7e1
--- /dev/null
+++ b/tests/myapp_all/urls.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import url, include
+from django.conf.urls.i18n import i18n_patterns
+from django.contrib import admin
+from django.conf import settings
+
+admin.autodiscover()
+
+urlpatterns = i18n_patterns('',
+    url(r'^admin/', include(admin.site.urls)),
+    url(r'', include('cms.urls')),
+)
diff --git a/tests/myapp_all/urls_news.py b/tests/myapp_all/urls_news.py
new file mode 100644
index 0000000000000000000000000000000000000000..9cdc95282bb8059d016a0ef7276db3d3c89045a0
--- /dev/null
+++ b/tests/myapp_all/urls_news.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns, url
+from newsbox_hvad.views import NewsboxHVADDetailView
+
+from .models import News
+
+urlpatterns = patterns(
+    '',
+    url(
+        r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[0-9a-zA-Z_-]+)/$', 
+        NewsboxHVADDetailView.as_view(model=News,),
+        name='news_detail'),
+)
diff --git a/tests/myapp_cms/__init__.py b/tests/myapp_cms/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26
--- /dev/null
+++ b/tests/myapp_cms/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/tests/myapp_cms/admin.py b/tests/myapp_cms/admin.py
new file mode 100644
index 0000000000000000000000000000000000000000..05fbf1c16cac538b1597b68d97ddd6d45e4d75e1
--- /dev/null
+++ b/tests/myapp_cms/admin.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.contrib import admin
+from newsbox_cms.admin import NewsboxCMSAdmin
+from newsbox.admin import NewsboxSEOAdmin, NewsboxExpiredAdmin
+
+from .models import News, NewsComplete, NewsExtended
+
+class NewsAdmin(NewsboxCMSAdmin):
+    pass
+
+admin.site.register(News, NewsAdmin)
+
+
+class NewsCompleteAdmin(NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin):
+    pass
+
+admin.site.register(NewsComplete, NewsCompleteAdmin)
+
+
+class NewsExtendedAdmin(NewsboxCMSAdmin, NewsboxSEOAdmin, NewsboxExpiredAdmin):
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(NewsExtendedAdmin, self).get_fieldsets(request, obj)
+        fieldsets[0][1]['fields'].append('general_field')
+        fieldsets[2][1]['fields'].append('content_field')
+        fieldsets[3][1]['fields'].append('seo_field')
+        return fieldsets
+
+    def get_list_display(self, request):
+        list_display = super(NewsExtendedAdmin, self).get_list_display(request)
+        list_display.append('seo_field')
+        return list_display
+
+admin.site.register(NewsExtended, NewsExtendedAdmin)
diff --git a/tests/myapp_cms/cms_app.py b/tests/myapp_cms/cms_app.py
new file mode 100644
index 0000000000000000000000000000000000000000..3e60259150f57a8d10090282a4c3a02b43c611c7
--- /dev/null
+++ b/tests/myapp_cms/cms_app.py
@@ -0,0 +1,11 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from cms.app_base import CMSApp
+from cms.apphook_pool import apphook_pool
+
+class NewsApphook(CMSApp):
+    name = 'News'
+    urls = ["myapp_cms.urls_news"]
+
+apphook_pool.register(NewsApphook)
diff --git a/tests/myapp_cms/cms_plugins.py b/tests/myapp_cms/cms_plugins.py
new file mode 100644
index 0000000000000000000000000000000000000000..35817176c442fbd12dbc5e2f4896877370dcdc69
--- /dev/null
+++ b/tests/myapp_cms/cms_plugins.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from cms.plugin_pool import plugin_pool
+from newsbox_cms.cms_plugins import NewsboxPluginBase
+
+from .models import NewsPlugin as NewsPluginModel
+
+
+class NewsPlugin(NewsboxPluginBase):
+    model = NewsPluginModel
+
+plugin_pool.register_plugin(NewsPlugin) 
diff --git a/tests/myapp_cms/fixtures/tests_data.json b/tests/myapp_cms/fixtures/tests_data.json
new file mode 100644
index 0000000000000000000000000000000000000000..ef097333ab094dd5c91c235d35110107f6be7407
--- /dev/null
+++ b/tests/myapp_cms/fixtures/tests_data.json
@@ -0,0 +1,394 @@
+[
+{
+    "pk": 1, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-1", 
+        "newsbox_creation_date": "2014-03-11T13:53:45.196Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 1</p>", 
+        "newsbox_body": 16, 
+        "newsbox_changed_date": "2014-03-11T13:53:45.196Z", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_slug": "news-2", 
+        "newsbox_creation_date": "2014-03-11T13:53:45.799Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 2</p>", 
+        "newsbox_body": 18, 
+        "newsbox_changed_date": "2014-03-11T13:53:45.799Z", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-3", 
+        "newsbox_creation_date": "2014-03-11T13:53:46.402Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 3</p>", 
+        "newsbox_body": 20, 
+        "newsbox_changed_date": "2014-03-11T13:53:46.402Z", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-4", 
+        "newsbox_creation_date": "2014-03-11T13:53:47.013Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 4</p>", 
+        "newsbox_body": 22, 
+        "newsbox_changed_date": "2014-03-11T13:53:47.013Z", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_slug": "news-5", 
+        "newsbox_creation_date": "2014-03-11T13:53:47.618Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 5</p>", 
+        "newsbox_body": 24, 
+        "newsbox_changed_date": "2014-03-11T13:53:47.618Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-6", 
+        "newsbox_creation_date": "2014-03-11T13:53:48.237Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 6</p>", 
+        "newsbox_body": 26, 
+        "newsbox_changed_date": "2014-03-11T13:53:48.237Z", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_cms.news", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_slug": "news-7", 
+        "newsbox_creation_date": "2014-03-11T13:53:48.840Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_summary": "<p>Summary of the news 7</p>", 
+        "newsbox_body": 28, 
+        "newsbox_changed_date": "2014-03-11T13:53:48.840Z", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_changed_date": "2014-03-11T13:53:52.178Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:52.178Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "<p>Summary of the news 1</p>", 
+        "newsbox_body": 30, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_changed_date": "2014-03-11T13:53:52.797Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:52.797Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "<p>Summary of the news 2</p>", 
+        "newsbox_body": 32, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_changed_date": "2014-03-11T13:53:53.426Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:53.426Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "<p>Summary of the news 3</p>", 
+        "newsbox_body": 34, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_changed_date": "2014-03-11T13:53:54.055Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:54.055Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "<p>Summary of the news 4</p>", 
+        "newsbox_body": 36, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_changed_date": "2014-03-11T13:53:54.674Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:54.674Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "<p>Summary of the news 5</p>", 
+        "newsbox_body": 38, 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_changed_date": "2014-03-11T13:53:55.303Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:55.303Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_indexed": false, 
+        "newsbox_summary": "<p>Summary of the news 6</p>", 
+        "newsbox_body": 40, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_cms.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_changed_date": "2014-03-11T13:53:55.922Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:55.921Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_summary": "<p>Summary of the news 7</p>", 
+        "newsbox_body": 42, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "", 
+        "newsbox_slug": "news-1", 
+        "newsbox_changed_date": "2014-03-11T13:53:40.980Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:40.980Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": true, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 1</p>", 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "newsbox_body": 2, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "content_field": "", 
+        "newsbox_slug": "news-2", 
+        "newsbox_changed_date": "2014-03-11T13:53:41.585Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:41.585Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": true, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 2</p>", 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "newsbox_body": 4, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "", 
+        "newsbox_slug": "news-3", 
+        "newsbox_changed_date": "2014-03-11T13:53:42.180Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:42.180Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": true, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 3</p>", 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "newsbox_body": 6, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "", 
+        "newsbox_slug": "news-4", 
+        "newsbox_changed_date": "2014-03-11T13:53:42.785Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:42.784Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": true, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 4</p>", 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "newsbox_body": 8, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "content_field": "", 
+        "newsbox_slug": "news-5", 
+        "newsbox_changed_date": "2014-03-11T13:53:43.377Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:43.377Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": true, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 5</p>", 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "newsbox_body": 10, 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "", 
+        "newsbox_slug": "news-6", 
+        "newsbox_changed_date": "2014-03-11T13:53:43.980Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:43.980Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": false, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 6</p>", 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "newsbox_body": 12, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_cms.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "content_field": "", 
+        "newsbox_slug": "news-7", 
+        "newsbox_changed_date": "2014-03-11T13:53:44.583Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:44.583Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "general_field": "", 
+        "newsbox_indexed": true, 
+        "seo_field": "", 
+        "newsbox_summary": "<p>Summary of the news 7</p>", 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "newsbox_body": 14, 
+        "newsbox_publication_end_date": null, 
+        "newsbox_title": "News 7"
+    }
+}
+]
diff --git a/tests/myapp_cms/models.py b/tests/myapp_cms/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..16622b3be7067855272dbbc6f64e19a27bbf47d9
--- /dev/null
+++ b/tests/myapp_cms/models.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase
+from newsbox_cms.models import NewsboxCMSBase, NewsboxPluginBase
+
+class News(NewsboxBase, NewsboxCMSBase):
+    class Meta:
+        verbose_name = 'news - CMS'
+        verbose_name_plural = 'news - CMS'
+        newsbox_detail_url_name = 'news_detail'
+
+
+class NewsComplete(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase, NewsboxCMSBase):
+    class Meta:
+        verbose_name = 'news - CompleteCMS'
+        verbose_name_plural = 'news - CompleteCMS'
+        newsbox_detail_url_name = 'newscomplete_detail'
+
+
+class NewsExtended(NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase, NewsboxCMSBase):
+    general_field = models.CharField(max_length=50)
+    content_field = models.CharField(max_length=50)
+    seo_field = models.CharField(max_length=50)
+    
+    class Meta:
+        verbose_name = 'news - ExtendedCMS'
+        verbose_name_plural = 'news - ExtendedCMS'
+        newsbox_detail_url_name = 'newsextended_detail'
+
+
+class NewsPlugin(NewsboxPluginBase):
+    newsbox_model = News
+
diff --git a/tests/myapp_cms/templates/base.html b/tests/myapp_cms/templates/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..8e730c87d61dd1403be1be462f71167d8ae314cb
--- /dev/null
+++ b/tests/myapp_cms/templates/base.html
@@ -0,0 +1,13 @@
+{% load cms_tags sekizai_tags %}
+<html>
+    <head>
+        {% render_block "css" %}
+    </head>
+    <body>
+        {% cms_toolbar %}
+        {% block main %}
+            {% placeholder main %}
+        {% endblock %}
+        {% render_block "js" %}
+    </body>
+</html>
diff --git a/tests/myapp_cms/templates/list-cms.html b/tests/myapp_cms/templates/list-cms.html
new file mode 100644
index 0000000000000000000000000000000000000000..726433cc7586ae1049bc637168ac31d8251a52d8
--- /dev/null
+++ b/tests/myapp_cms/templates/list-cms.html
@@ -0,0 +1 @@
+{% extends "newsbox/list-cms.html" %}
diff --git a/tests/myapp_cms/templates/page.html b/tests/myapp_cms/templates/page.html
new file mode 100644
index 0000000000000000000000000000000000000000..4ed33cab160a992834bd4306fefbed218e42d3aa
--- /dev/null
+++ b/tests/myapp_cms/templates/page.html
@@ -0,0 +1,6 @@
+{% extends "base.html" %}
+{% load cms_tags %}
+
+{% block main %}
+  {% placeholder main %}
+{% endblock %}
diff --git a/tests/myapp_cms/tests.py b/tests/myapp_cms/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0a52845b2ea6df49e632a0824f25ef8e8070e36
--- /dev/null
+++ b/tests/myapp_cms/tests.py
@@ -0,0 +1,150 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from copy import copy
+
+from django.test import TestCase, Client
+from django.contrib.auth.models import User
+from django.core.paginator import EmptyPage
+from cms.test_utils.testcases import CMSTestCase
+from cms.plugin_rendering import render_plugin
+from cms.api import create_page, add_plugin, publish_page
+from djangocms_text_ckeditor.fields import HTMLField
+
+from .models import News, NewsComplete, NewsExtended, NewsPlugin as NewsPluginModel
+from .cms_plugins import NewsPlugin
+
+
+class NewsboxAbstractModelsTests(TestCase):
+
+    fixtures = ['tests_data.json',]
+    
+
+    def test_01_manager_published(self):
+        """
+        Test if we only get really published news via the manager
+        """
+        newsClasses = [
+            News, NewsComplete, NewsExtended,
+        ]
+        for cls in newsClasses:
+            returned_ids = list(cls.objects.published().values_list(
+                'id', flat=True).order_by('id'))
+            self.assertEqual(
+                (cls.__name__,returned_ids), 
+                (cls.__name__,[1, 4, 6, 7,]))
+
+    def test_02_summary_as_html_field(self):
+        """
+        Test if newsbox_summary field is HTMLField
+        """
+        newsClasses = [
+            News, NewsComplete, NewsExtended,
+        ]
+
+        for cls in newsClasses:
+            try:
+                summary_field = cls._meta.get_field('newsbox_summary')
+            except:
+                self.fail('%s is not properly configured' % cls)
+            self.assertIsInstance(summary_field, HTMLField)
+
+
+class NewsboxPageIntegrationTests(CMSTestCase):
+
+    fixtures = ['tests_data.json',]
+
+    def setUp(self):
+        self.super_user = User(username="test", is_staff=True, is_active=True, is_superuser=True)
+        self.super_user.set_password("test")
+        self.super_user.save()
+        
+        home = create_page(title='Home',
+            template='page.html', 
+            language='en', published=True,
+            reverse_id='home', in_navigation=True)
+
+        self.page = create_page(title='News page',
+            template='page.html', parent=home,
+            language='en', published=True, apphook='NewsApphook',
+            reverse_id='newspage', in_navigation=True)
+
+        self.placeholder = self.page.placeholders.get(slot='main')
+        self.plugin = add_plugin(
+            self.placeholder, 'NewsPlugin', 'en', 
+            title = 'News',
+            numitems = 1,
+            with_pager = True,
+            page_link = None,)
+        self.plugin.save()
+        self.newsPlugin = NewsPlugin()
+        self.page = publish_page(self.page, self.super_user, 'en')
+        self.placeholder = self.page.placeholders.get(slot='main')
+
+    def test_01_cmsplugin_context(self):
+        context = self.get_context(self.page.get_absolute_url(), page=self.page)
+        self.newsPlugin.render(context, self.plugin, self.placeholder)
+        self.assertIn('newsset', context)
+        self.assertEqual(context['newsset'][0].pk, 7)
+        self.assertEqual(context['newsset'].number, 1)
+        self.assertEqual(context['newsset'].paginator.num_pages, 4)
+        self.assertFalse(context['newsset'].has_previous())
+        self.assertTrue(context['newsset'].has_next())
+        self.assertRaises(EmptyPage, context['newsset'].previous_page_number)
+        self.assertEqual(context['newsset'].next_page_number(), 2)
+
+    def test_02_cmsplugin_disable_pager(self):
+        context = self.get_context(self.page.get_absolute_url(), page=self.page)
+        plugin = copy(self.plugin)
+        plugin.with_pager = False
+        self.newsPlugin.render(context, plugin, self.placeholder)
+        self.assertIn('newsset', context)
+        with self.assertRaises(AttributeError):
+            getattr(context['newsset'], 'has_previous')
+        with self.assertRaises(AttributeError):
+            getattr(context['newsset'], 'paginator')
+
+    def test_03_cmsplugin_numitems(self):
+        context = self.get_context(self.page.get_absolute_url(), page=self.page)
+        plugin = copy(self.plugin)
+        plugin.numitems = 2
+        self.newsPlugin.render(context, plugin, self.placeholder)
+        self.assertIn('newsset', context)
+        self.assertEqual(context['newsset'].paginator.num_pages, 2)
+
+    def test_04_cmsplugin_html(self):
+        context = self.get_context(self.page.get_absolute_url(), page=self.page)
+        self.newsPlugin.render(context, self.plugin, self.placeholder)
+        html = render_plugin(
+            context, 
+            self.newsPlugin, 
+            self.placeholder, 
+            self.newsPlugin.render_template)
+        self.assertIn('<a href="/news-page/2020/01/01/news-7/">News 7</a>', html)
+        self.assertIn('<a class="next" href="?page=2">Next news</a>', html)
+
+    def test_05_app_view_detail_200(self):
+        """
+        Test if generic day views return right informations.
+        """
+        c = Client()
+        r = c.get('/news-page/2005/07/15/news-6/')
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.context['news'].pk, 6)
+
+    def test_06_app_view_detail_404(self):
+        """
+        Test if generic day views return a 404 with an URL with a date without 
+        any news.
+        """
+        c = Client()
+        r = c.get('/news-page/1985/07/02/my-birthday/')
+        self.assertEqual(r.status_code, 404)
+
+    def test_07_app_view_detail_404_not_published(self):
+        """
+        Test if generic day views return a 404 with an URL with a not published
+        news
+        """
+        c = Client()
+        r = c.get('/news-page/2014/02/22/news-2/')
+        self.assertEqual(r.status_code, 404)
diff --git a/tests/myapp_cms/urls.py b/tests/myapp_cms/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..2a7ddb5aa121a3fc2cbe246b7c05f4278931a0f0
--- /dev/null
+++ b/tests/myapp_cms/urls.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import url, include, patterns
+from django.contrib import admin
+from django.conf import settings
+
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    url(r'^admin/', include(admin.site.urls)),
+    url(r'', include('cms.urls')),
+)
diff --git a/tests/myapp_cms/urls_news.py b/tests/myapp_cms/urls_news.py
new file mode 100644
index 0000000000000000000000000000000000000000..a9a706d718a2bf8c43e31e2352995c8b550910f3
--- /dev/null
+++ b/tests/myapp_cms/urls_news.py
@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import patterns, url
+from newsbox.views import NewsboxDetailView
+
+from .models import News
+
+urlpatterns = patterns(
+    '',
+    url(
+        r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[0-9a-zA-Z_-]+)/$', 
+        NewsboxDetailView.as_view(
+            model=News,),
+        name='news_detail'),
+)
diff --git a/tests/myapp_hvad/__init__.py b/tests/myapp_hvad/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..40a96afc6ff09d58a702b76e3f7dd412fe975e26
--- /dev/null
+++ b/tests/myapp_hvad/__init__.py
@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-
diff --git a/tests/myapp_hvad/fixtures/tests_data.json b/tests/myapp_hvad/fixtures/tests_data.json
new file mode 100644
index 0000000000000000000000000000000000000000..1c6ef94c10adaaafba9b688206993ff258a7c6e1
--- /dev/null
+++ b/tests/myapp_hvad/fixtures/tests_data.json
@@ -0,0 +1,856 @@
+[
+{
+    "pk": 1, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-1", 
+        "master": 1, 
+        "newsbox_summary": "Summary of the news 1", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-1", 
+        "master": 1, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 1", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 1", 
+        "newsbox_title": "Actualit\u00e9 1"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-2", 
+        "master": 2, 
+        "newsbox_summary": "Summary of the news 2", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-2", 
+        "master": 2, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 2", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 2", 
+        "newsbox_title": "Actualit\u00e9 2"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-3", 
+        "master": 3, 
+        "newsbox_summary": "Summary of the news 3", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-3", 
+        "master": 3, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 3", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 3", 
+        "newsbox_title": "Actualit\u00e9 3"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-4", 
+        "master": 4, 
+        "newsbox_summary": "Summary of the news 4", 
+        "language_code": "en", 
+        "newsbox_body": "", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 8, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-4", 
+        "master": 4, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 4", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 4", 
+        "newsbox_title": "Actualit\u00e9 4"
+    }
+},
+{
+    "pk": 9, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-5", 
+        "master": 5, 
+        "newsbox_summary": "Summary of the news 5", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 10, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-5", 
+        "master": 5, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 5", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 5", 
+        "newsbox_title": "Actualit\u00e9 5"
+    }
+},
+{
+    "pk": 11, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-6", 
+        "master": 6, 
+        "newsbox_summary": "Summary of the news 6", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 12, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-6", 
+        "master": 6, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 6", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 6", 
+        "newsbox_title": "Actualit\u00e9 6"
+    }
+},
+{
+    "pk": 13, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "news-7", 
+        "master": 7, 
+        "newsbox_summary": "Summary of the news 7", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 14, 
+    "model": "myapp_hvad.newstranslation", 
+    "fields": {
+        "newsbox_slug": "actualite-7", 
+        "master": 7, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 7", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 7", 
+        "newsbox_title": "Actualit\u00e9 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:29.989Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:30.366Z", 
+        "newsbox_published": true, 
+        "newsbox_date": "2014-02-22T08:00:00Z"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:30.736Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:31.111Z", 
+        "newsbox_published": false, 
+        "newsbox_date": "2014-02-22T08:00:00Z"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:31.496Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:31.884Z", 
+        "newsbox_published": true, 
+        "newsbox_date": "2014-02-22T08:00:00Z"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:32.261Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:32.646Z", 
+        "newsbox_published": true, 
+        "newsbox_date": "2014-02-22T08:00:00Z"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:33.016Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:33.377Z", 
+        "newsbox_published": false, 
+        "newsbox_date": "2014-02-22T08:00:00Z"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:33.752Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:34.122Z", 
+        "newsbox_published": true, 
+        "newsbox_date": "2005-07-15T08:00:00Z"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_hvad.news", 
+    "fields": {
+        "newsbox_creation_date": "2014-03-11T13:53:34.499Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_changed_date": "2014-03-11T13:53:34.868Z", 
+        "newsbox_published": true, 
+        "newsbox_date": "2020-01-01T08:00:00Z"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "master": 1, 
+        "newsbox_summary": "Summary of the news 1", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", 
+        "newsbox_slug": "actualite-1", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", 
+        "master": 1, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 1", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 1", 
+        "newsbox_title": "Actualit\u00e9 1"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "master": 2, 
+        "newsbox_summary": "Summary of the news 2", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", 
+        "newsbox_slug": "actualite-2", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", 
+        "master": 2, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 2", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 2", 
+        "newsbox_title": "Actualit\u00e9 2"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "master": 3, 
+        "newsbox_summary": "Summary of the news 3", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", 
+        "newsbox_slug": "actualite-3", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", 
+        "master": 3, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 3", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 3", 
+        "newsbox_title": "Actualit\u00e9 3"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "master": 4, 
+        "newsbox_summary": "Summary of the news 4", 
+        "language_code": "en", 
+        "newsbox_body": "", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 8, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", 
+        "newsbox_slug": "actualite-4", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", 
+        "master": 4, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 4", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 4", 
+        "newsbox_title": "Actualit\u00e9 4"
+    }
+},
+{
+    "pk": 9, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "master": 5, 
+        "newsbox_summary": "Summary of the news 5", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 10, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", 
+        "newsbox_slug": "actualite-5", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", 
+        "master": 5, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 5", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 5", 
+        "newsbox_title": "Actualit\u00e9 5"
+    }
+},
+{
+    "pk": 11, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "master": 6, 
+        "newsbox_summary": "Summary of the news 6", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 12, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", 
+        "newsbox_slug": "actualite-6", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", 
+        "master": 6, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 6", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 6", 
+        "newsbox_title": "Actualit\u00e9 6"
+    }
+},
+{
+    "pk": 13, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "master": 7, 
+        "newsbox_summary": "Summary of the news 7", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 14, 
+    "model": "myapp_hvad.newscompletetranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", 
+        "newsbox_slug": "actualite-7", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", 
+        "master": 7, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 7", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 7", 
+        "newsbox_title": "Actualit\u00e9 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:35.631Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:35.238Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-11T13:53:36.378Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:35.993Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:37.124Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:36.747Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:37.871Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:37.494Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-11T13:53:38.660Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:38.272Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:39.438Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:39.045Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "newsbox_indexed": false, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_hvad.newscomplete", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:40.209Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:39.824Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-1", 
+        "content_field": "Extra content of the news 1", 
+        "newsbox_slug": "news-1", 
+        "newsbox_meta_description": "Meta description of the news 1", 
+        "seo_field": "Extra SEO of the news 1", 
+        "master": 1, 
+        "newsbox_summary": "Summary of the news 1", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 1", 
+        "newsbox_title": "News 1"
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-1", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 1", 
+        "newsbox_slug": "actualite-1", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 1", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 1", 
+        "master": 1, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 1", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 1", 
+        "newsbox_title": "Actualit\u00e9 1"
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-2", 
+        "content_field": "Extra content of the news 2", 
+        "newsbox_slug": "news-2", 
+        "newsbox_meta_description": "Meta description of the news 2", 
+        "seo_field": "Extra SEO of the news 2", 
+        "master": 2, 
+        "newsbox_summary": "Summary of the news 2", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 2", 
+        "newsbox_title": "News 2"
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-2", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 2", 
+        "newsbox_slug": "actualite-2", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 2", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 2", 
+        "master": 2, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 2", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 2", 
+        "newsbox_title": "Actualit\u00e9 2"
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-3", 
+        "content_field": "Extra content of the news 3", 
+        "newsbox_slug": "news-3", 
+        "newsbox_meta_description": "Meta description of the news 3", 
+        "seo_field": "Extra SEO of the news 3", 
+        "master": 3, 
+        "newsbox_summary": "Summary of the news 3", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 3", 
+        "newsbox_title": "News 3"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-3", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 3", 
+        "newsbox_slug": "actualite-3", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 3", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 3", 
+        "master": 3, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 3", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 3", 
+        "newsbox_title": "Actualit\u00e9 3"
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-4", 
+        "content_field": "Extra content of the news 4", 
+        "newsbox_slug": "news-4", 
+        "newsbox_meta_description": "Meta description of the news 4", 
+        "seo_field": "Extra SEO of the news 4", 
+        "master": 4, 
+        "newsbox_summary": "Summary of the news 4", 
+        "language_code": "en", 
+        "newsbox_body": "", 
+        "newsbox_title": "News 4"
+    }
+},
+{
+    "pk": 8, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-4", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 4", 
+        "newsbox_slug": "actualite-4", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 4", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 4", 
+        "master": 4, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 4", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 4", 
+        "newsbox_title": "Actualit\u00e9 4"
+    }
+},
+{
+    "pk": 9, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-5", 
+        "content_field": "Extra content of the news 5", 
+        "newsbox_slug": "news-5", 
+        "newsbox_meta_description": "Meta description of the news 5", 
+        "seo_field": "Extra SEO of the news 5", 
+        "master": 5, 
+        "newsbox_summary": "Summary of the news 5", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 5", 
+        "newsbox_title": "News 5"
+    }
+},
+{
+    "pk": 10, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-5", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 5", 
+        "newsbox_slug": "actualite-5", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 5", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 5", 
+        "master": 5, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 5", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 5", 
+        "newsbox_title": "Actualit\u00e9 5"
+    }
+},
+{
+    "pk": 11, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-6", 
+        "content_field": "Extra content of the news 6", 
+        "newsbox_slug": "news-6", 
+        "newsbox_meta_description": "Meta description of the news 6", 
+        "seo_field": "Extra SEO of the news 6", 
+        "master": 6, 
+        "newsbox_summary": "Summary of the news 6", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 6", 
+        "newsbox_title": "News 6"
+    }
+},
+{
+    "pk": 12, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-6", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 6", 
+        "newsbox_slug": "actualite-6", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 6", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 6", 
+        "master": 6, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 6", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 6", 
+        "newsbox_title": "Actualit\u00e9 6"
+    }
+},
+{
+    "pk": 13, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "keyword1, keyword2, news-7", 
+        "content_field": "Extra content of the news 7", 
+        "newsbox_slug": "news-7", 
+        "newsbox_meta_description": "Meta description of the news 7", 
+        "seo_field": "Extra SEO of the news 7", 
+        "master": 7, 
+        "newsbox_summary": "Summary of the news 7", 
+        "language_code": "en", 
+        "newsbox_body": "Body of the news 7", 
+        "newsbox_title": "News 7"
+    }
+},
+{
+    "pk": 14, 
+    "model": "myapp_hvad.newsextendedtranslation", 
+    "fields": {
+        "newsbox_meta_keywords": "motclef1, motclef2, actualite-7", 
+        "content_field": "Contenu additionnel de l'actualit\u00e9 7", 
+        "newsbox_slug": "actualite-7", 
+        "newsbox_meta_description": "Meta description de l'actualit\u00e9 7", 
+        "seo_field": "SEO additionnel de l'actualit\u00e9 7", 
+        "master": 7, 
+        "newsbox_summary": "R\u00e9sum\u00e9 de l'actualit\u00e9 7", 
+        "language_code": "fr", 
+        "newsbox_body": "Corps de l'actualit\u00e9 7", 
+        "newsbox_title": "Actualit\u00e9 7"
+    }
+},
+{
+    "pk": 1, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:56.517Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:56.124Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 2, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-11T13:53:57.329Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:56.946Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 3, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:58.094Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:57.716Z", 
+        "newsbox_publication_start_date": "2020-01-01T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 4, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:53:59.046Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:58.487Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 5, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": false, 
+        "newsbox_changed_date": "2014-03-11T13:53:59.843Z", 
+        "newsbox_creation_date": "2014-03-11T13:53:59.451Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2014-02-22T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": "2000-01-01T08:00:00Z"
+    }
+},
+{
+    "pk": 6, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:54:00.657Z", 
+        "newsbox_creation_date": "2014-03-11T13:54:00.246Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2005-07-15T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": false, 
+        "newsbox_publication_end_date": null
+    }
+},
+{
+    "pk": 7, 
+    "model": "myapp_hvad.newsextended", 
+    "fields": {
+        "newsbox_published": true, 
+        "newsbox_changed_date": "2014-03-11T13:54:01.420Z", 
+        "newsbox_creation_date": "2014-03-11T13:54:01.033Z", 
+        "newsbox_publication_start_date": "1985-07-02T08:00:00Z", 
+        "newsbox_date": "2020-01-01T08:00:00Z", 
+        "general_field": "Test", 
+        "newsbox_indexed": true, 
+        "newsbox_publication_end_date": null
+    }
+}
+]
diff --git a/tests/myapp_hvad/models.py b/tests/myapp_hvad/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..84885858e14cc2afdb1d79707f1bcc2eff747353
--- /dev/null
+++ b/tests/myapp_hvad/models.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models
+from newsbox.models import NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase
+from newsbox_hvad.models import NewsboxHVADBase
+
+class News(NewsboxHVADBase, NewsboxBase):
+    class Meta:
+        verbose_name = 'news - HVAD'
+        verbose_name_plural = 'news - HVAD'
+
+class NewsComplete(NewsboxHVADBase, NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase):
+    class Meta:
+        verbose_name = 'news - CompleteHVAD'
+        verbose_name_plural = 'news - CompleteHVAD'
+
+class NewsExtended(NewsboxHVADBase, NewsboxBase, NewsboxSEOBase, NewsboxExpiredBase):
+    general_field = models.CharField(max_length=50)
+    content_field = models.CharField(max_length=50)
+    seo_field = models.CharField(max_length=50)
+    
+    class Meta:
+        verbose_name = 'news - ExtendedHVAD'
+        verbose_name_plural = 'news - ExtendedHVAD'
+        newsbox_trans_fieldnames = ['content_field', 'seo_field']
+
diff --git a/tests/myapp_hvad/tests.py b/tests/myapp_hvad/tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..60e3504cbfaf2899eb7b7bb0246a1de0ab10e9ac
--- /dev/null
+++ b/tests/myapp_hvad/tests.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.test import TestCase, Client
+from django.core.paginator import EmptyPage
+from django.utils.translation import activate
+
+from .models import News, NewsComplete, NewsExtended
+
+
+
+
+class NewsboxAbstractModelsTests(TestCase):
+
+    fixtures = ['tests_data.json',]
+    
+    def test_01_manager_published(self):
+        """
+        Test if we only get really published news via the manager
+        """
+        newsClasses = [
+            News, NewsComplete, NewsExtended
+        ]
+        for cls in newsClasses:
+            returned_ids = list(cls.objects.published().values_list(
+                'id', flat=True).order_by('id'))
+            self.assertEqual(
+                (cls.__name__,returned_ids), 
+                (cls.__name__,[1, 4, 6, 7,]))
+
+    def test_02_extra_translated_fields(self):
+        news = NewsExtended.objects.get(pk=1)
+        self.assertEqual(
+            list(news.get_available_languages()),
+            ['en', 'fr'])
+        news_fr = NewsExtended.objects.language('fr').get(pk=1)
+        news_en = NewsExtended.objects.language('en').get(pk=1)
+        self.assertEqual(
+            news_fr.content_field, 
+            'Contenu additionnel de l\'actualité 1')
+        self.assertEqual(
+            news_en.content_field, 
+            'Extra content of the news 1')
+        self.assertEqual(news_en.general_field, news_fr.general_field)
+    
+    def test_03_view_archive_200(self):
+        """
+        Test if generic archive view return right informations.
+        """
+        c = Client()
+        r = c.get('/en/news/')
+
+        self.assertEqual(r.status_code, 200)
+        self.assertIn('newsset', r.context)
+        self.assertEqual(r.context['newsset'][0].pk, 7)
+        self.assertEqual(r.context['newsset'].number, 1)
+        self.assertEqual(r.context['newsset'].paginator.num_pages, 4)
+        self.assertFalse(r.context['newsset'].has_previous())
+        self.assertTrue(r.context['newsset'].has_next())
+        self.assertRaises(EmptyPage, r.context['newsset'].previous_page_number)
+        self.assertEqual(r.context['newsset'].next_page_number(), 2)
+        
+    
+    def test_04_view_detail_200(self):
+        """
+        Test if generic day views return right informations.
+        """
+        c = Client()
+        r = c.get('/en/newsbox/myapp_hvad/news/2005/07/15/news-6/')
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.context['news'].pk, 6)
+
+    def test_05_view_detail_404(self):
+        """
+        Test if generic day views return a 404 with an URL with a date without 
+        any news.
+        """
+        c = Client()
+        r = c.get('/en/newsbox/myapp_hvad/news/1985/07/02/my-birthday/')
+        self.assertEqual(r.status_code, 404)
+
+    def test_06_view_detail_404_not_published(self):
+        """
+        Test if generic day views return a 404 with an URL with a not published
+        news
+        """
+        c = Client()
+        r = c.get('/en/newsbox/myapp_hvad/news/2014/02/22/news-2/')
+        self.assertEqual(r.status_code, 404)
+
+    def test_07_view_detail_translated(self):
+        c = Client()
+        r_en = c.get('/en/newsbox/myapp_hvad/news/2005/07/15/news-6/')
+        r_fr = c.get('/fr/newsbox/myapp_hvad/news/2005/07/15/actualite-6/')
+        self.assertEqual(r_fr.context['news'].pk, r_en.context['news'].pk)
+        self.assertEqual(r_fr.context['news'].newsbox_title, 'Actualité 6')
+        self.assertEqual(r_en.context['news'].newsbox_title, 'News 6')
+
+    def test_08_get_absolute_url(self):
+        news6 = News.objects.get(pk=6)
+        expected_results = {
+            'en':'/en/newsbox/myapp_hvad/news/2005/07/15/news-6/',
+            'fr':'/fr/newsbox/myapp_hvad/news/2005/07/15/actualite-6/',}
+        for lang in expected_results:
+            activate(lang)
+            self.assertEqual(news6.get_absolute_url(), expected_results[lang])
diff --git a/tests/myapp_hvad/urls.py b/tests/myapp_hvad/urls.py
new file mode 100644
index 0000000000000000000000000000000000000000..04c49fa68a74c6908af7b07ef2c40dd4ac0f6894
--- /dev/null
+++ b/tests/myapp_hvad/urls.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf.urls import url, include
+from django.conf.urls.i18n import i18n_patterns
+from django.contrib import admin
+from django.conf import settings
+from newsbox.views import NewsboxYearArchiveView, NewsboxArchiveView
+
+from .models import News
+
+admin.autodiscover()
+
+urlpatterns = i18n_patterns('',
+    url(r'^admin/', include(admin.site.urls)),
+    url(r'^', include('newsbox_hvad.urls')),
+    url(r'^news/$', 
+        NewsboxArchiveView.as_view(model=News, paginate_by=1), 
+        name='news_list',),
+    url(r'^news/(?P<year>\d{4})/$', 
+        NewsboxYearArchiveView.as_view(model=News, paginate_by=1), 
+        name='news_list_y',),
+)
diff --git a/tests/runtests.sh b/tests/runtests.sh
new file mode 100755
index 0000000000000000000000000000000000000000..274086ae7f10564efcecf2f90dbbef012b8f75dd
--- /dev/null
+++ b/tests/runtests.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+export PYTHONPATH="./"
+
+if [ `which django-admin.py` ] ; then
+    export DJANGO_ADMIN=django-admin.py
+else
+    export DJANGO_ADMIN=django-admin
+fi
+
+export args="$@"
+if [ -z "$args" ] ; then
+    # avoid running the tests for django.contrib.* (they're in INSTALLED_APPS)
+    export args=myapp
+fi
+
+if [ "$args" = "myapp_cms" ] ; then
+    export DJANGO_SETTINGS_MODULE='settings_cms'
+elif [ "$args" = "myapp_hvad" ] ; then
+    export DJANGO_SETTINGS_MODULE='settings_hvad'
+elif [ "$args" = "myapp_all" ] ; then
+    export DJANGO_SETTINGS_MODULE='settings_all'
+else
+    export DJANGO_SETTINGS_MODULE='settings'
+fi
+
+$DJANGO_ADMIN test --traceback --settings=$DJANGO_SETTINGS_MODULE --verbosity 2 --pythonpath="../" "$args"
diff --git a/tests/settings.py b/tests/settings.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f1ad520b9f95cb5304589a2300606661107f82b
--- /dev/null
+++ b/tests/settings.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+import os
+
+DIRNAME = os.path.dirname(__file__)
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': 'mydatabase'
+    }
+}
+STATIC_URL = '/static/'
+STATICFILES_FINDERS = (
+    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
+)
+INSTALLED_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.staticfiles',
+    'django.contrib.admin',
+    
+    'newsbox',
+    'myapp',
+)
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+)
+# Required for Django 1.4+
+STATIC_URL = '/static/'
+# Required for Django 1.5+
+SECRET_KEY = 'abc123'
+USE_TZ = True
+LANGUAGE_CODE = 'en'
+LANGUAGES = [('en', 'English')]
+ROOT_URLCONF = 'myapp.urls'
diff --git a/tests/settings_all.py b/tests/settings_all.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd68248722654f080772f1991facf0a68270ac89
--- /dev/null
+++ b/tests/settings_all.py
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from settings_cms import *
+
+INSTALLED_APPS = list(INSTALLED_APPS + ('myapp_all',))
+INSTALLED_APPS.remove('myapp_cms')
+INSTALLED_APPS = tuple(INSTALLED_APPS)
+
+LANGUAGES = [('en', 'English',), ('fr', 'French',),]
+ROOT_URLCONF = 'myapp_all.urls'
+MIDDLEWARE_CLASSES=MIDDLEWARE_CLASSES+(
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.locale.LocaleMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+CMS_PLACEHOLDER_CONF = {
+    'main': {
+        'name': "Main content",
+        'plugins': ['NewsPlugin','TextPlugin'],
+    },
+}
diff --git a/tests/settings_cms.py b/tests/settings_cms.py
new file mode 100644
index 0000000000000000000000000000000000000000..aff9a8d54bce6b5db45f7c3764447b460bdd9aca
--- /dev/null
+++ b/tests/settings_cms.py
@@ -0,0 +1,53 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from settings import *
+
+SITE_ID = 1
+INSTALLED_APPS = list(INSTALLED_APPS + (
+    #cms requirements
+    'cms',  # django CMS itself
+    'mptt',  # utilities for implementing a modified pre-order traversal tree
+    'menus',  # helper for model independent hierarchical website navigation
+    'south',  # intelligent schema and data migrations
+    'sekizai',  # for javascript and css management
+    'djangocms_admin_style',  # for the admin skin. You **must** add 'djangocms_admin_style' in the list before 'django.contrib.admin'.
+    'django.contrib.messages',  # to enable messages framework (see :ref:`Enable messages <enable-messages>`)
+    'djangocms_text_ckeditor',
+    'newsbox_cms',
+    'myapp_cms',
+))
+INSTALLED_APPS.remove('myapp')
+INSTALLED_APPS = tuple(INSTALLED_APPS)
+MIDDLEWARE_CLASSES = (
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.locale.LocaleMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'cms.middleware.page.CurrentPageMiddleware',
+    'cms.middleware.user.CurrentUserMiddleware',
+    'cms.middleware.toolbar.ToolbarMiddleware',
+    'cms.middleware.language.LanguageCookieMiddleware',
+)
+TEMPLATE_CONTEXT_PROCESSORS = (
+    'django.contrib.auth.context_processors.auth',
+    'django.contrib.messages.context_processors.messages',
+    'django.core.context_processors.i18n',
+    'django.core.context_processors.request',
+    'django.core.context_processors.media',
+    'django.core.context_processors.static',
+    'cms.context_processors.cms_settings',
+    'sekizai.context_processors.sekizai',
+)
+CMS_TEMPLATES = (
+    ('page.html', 'page'),
+)
+ROOT_URLCONF = 'myapp_cms.urls'
+CMS_PLACEHOLDER_CONF = {
+    'main': {
+        'name': "Main content",
+        'plugins': ['NewsPlugin',],
+    },
+}
diff --git a/tests/settings_hvad.py b/tests/settings_hvad.py
new file mode 100644
index 0000000000000000000000000000000000000000..f549c36a51563a7fa03ed56eba9aac21f06698f4
--- /dev/null
+++ b/tests/settings_hvad.py
@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from settings import *
+
+LANGUAGES = [('en', 'English'),('fr', 'French'),]
+ROOT_URLCONF = 'myapp_hvad.urls'
+MIDDLEWARE_CLASSES=(
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.locale.LocaleMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+
+INSTALLED_APPS = list(INSTALLED_APPS + ('hvad', 'myapp_hvad',))
+INSTALLED_APPS.remove('myapp')
+INSTALLED_APPS = tuple(INSTALLED_APPS)
diff --git a/tests/utils.py b/tests/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..17a8e09eacac1fbaa04695dcb6fbac07762d8922
--- /dev/null
+++ b/tests/utils.py
@@ -0,0 +1,256 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+from myapp.models import News, NewsExpired, NewsSEO, NewsComplete, NewsExtended
+from myapp_cms.models import News as cms_News, \
+     NewsComplete as cms_NewsComplete, \
+     NewsExtended as cms_NewsExtended
+from myapp_hvad.models import News as hvad_News, \
+     NewsComplete as hvad_NewsComplete, \
+     NewsExtended as hvad_NewsExtended
+from myapp_all.models import News as all_News, \
+     NewsComplete as all_NewsComplete, \
+     NewsExtended as all_NewsExtended
+from cms.models.placeholdermodel import Placeholder
+from cms.api import add_plugin
+
+def get_fields_values(newsTypes, newsType, i, inherited):
+    fields_values={}
+    if newsType in inherited :
+        return fields_values
+    inherited.append(newsType)
+
+    for inheritedType in newsTypes[newsType]['overwrites']['inherit']:
+        fields_values.update(get_fields_values(newsTypes, inheritedType, i, []))
+    if i in newsTypes[newsType]['overwrites']:
+        fields_values.update(newsTypes[newsType]['overwrites'][i])
+    return fields_values
+
+def create_tests_data(app=None):
+    
+    #Translations of translatable fields
+    translations = {
+        'en':{
+            #default content is already in english
+        },
+        'fr':{
+            'newsbox_slug':'actualite-%d',
+            'newsbox_title':'Actualité %d',
+            'newsbox_summary':'Résumé de l\'actualité %d',
+            'newsbox_body':'Corps de l\'actualité %d',
+            'newsbox_meta_description':'Meta description de l\'actualité %d',
+            'newsbox_meta_keywords':'motclef1, motclef2, actualite-%d',
+            'content_field':'Contenu additionnel de l\'actualité %d',
+            'seo_field':'SEO additionnel de l\'actualité %d',
+        },
+    }
+    translatable_fields = translations['fr'].keys()
+    
+    #array of available NewsTypes
+    #for each NewsType, we define a subarray with the model to use and 
+    #default fields values in "overwrites" which is a subarray too :
+    #   - inherit is a list of other NewsTypes to get default fields.from their conf
+    #   - key 0 is the default values for all news
+    #   - keys 1 to N is an array with values to overwrite for news 1 to N.
+    # Can also contain a "languages" list with language code for translations. 
+    #Only used for HVAD Models. Translations are in "translations" variable.
+    newsTypes = {
+        'News' : {
+            'model':News,
+            'overwrites':{
+                'inherit':[],
+                #0 is for base values
+                0:{
+                    'newsbox_slug':'news-%d',
+                    'newsbox_title':'News %d',
+                    'newsbox_date':'2014-02-22T10:00:00+02:00',
+                    'newsbox_publication_start_date':'1985-07-02T10:00:00+02:00',
+                    'newsbox_published':True,
+                    'newsbox_summary':'Summary of the news %d',
+                    'newsbox_body':'Body of the news %d',
+                },
+                1:{},
+                2:{'newsbox_published':False},
+                3:{'newsbox_publication_start_date':'2020-01-01T10:00:00+02:00'},
+                4:{'newsbox_body':''},
+                5:{'newsbox_published':False},
+                6:{'newsbox_date':'2005-07-15T10:00:00+02:00'},
+                7:{'newsbox_date':'2020-01-01T10:00:00+02:00'},
+            },
+        },
+        'NewsExpired' : {
+            'model':NewsExpired,
+            'overwrites':{
+                'inherit':['News',],
+                5:{
+                    'newsbox_published':True, 
+                    'newsbox_publication_end_date':'2000-01-01T10:00:00+02:00',
+                },
+            },
+        },
+        'NewsSEO' : {
+            'model':NewsSEO,
+            'overwrites':{
+                'inherit':['News',],
+                0:{
+                    'newsbox_indexed':True,
+                    'newsbox_meta_description':'Meta description of the news %d',
+                    'newsbox_meta_keywords':'keyword1, keyword2, news-%d',
+                },
+                6:{
+                    'newsbox_indexed':False,
+                },
+            },
+        },
+        'NewsComplete' : {
+            'model':NewsComplete,
+            'overwrites':{
+                'inherit':['NewsExpired', 'NewsSEO'],
+            },
+        },
+        'NewsExtended' : {
+            'model':NewsExtended,
+            'overwrites':{
+                'inherit':['NewsComplete'],
+                0:{
+                    'general_field':'Test',
+                    'content_field':'Extra content of the news %d',
+                    'seo_field':'Extra SEO of the news %d',
+                },
+            }
+        },
+        
+        #CMS Models
+        'cms_News' : {
+            'model':cms_News,
+            'overwrites':{
+                'inherit':['News',],
+                0:{
+                    'newsbox_summary':'<p>Summary of the news %d</p>',
+                    'newsbox_body':'<p>Body of the news %d</p>',
+                },
+            },
+        },
+        'cms_NewsComplete' : {
+            'model':cms_NewsComplete,
+            'overwrites':{
+                'inherit':['NewsComplete', 'cms_News'],
+            },
+        },
+        'cms_NewsExtended' : {
+            'model':cms_NewsExtended,
+            'overwrites':{
+                'inherit':['cms_NewsComplete'],
+            },
+        },
+        
+        #HVAD Models
+        'hvad_News' : {
+            'languages':['en', 'fr',],
+            'model':hvad_News,
+            'overwrites':{
+                'inherit':['News',],
+            },
+        },
+        'hvad_NewsComplete' : {
+            'languages':['en', 'fr',],
+            'model':hvad_NewsComplete,
+            'overwrites':{
+                'inherit':['NewsComplete', 'hvad_News'],
+            },
+        },
+        'hvad_NewsExtended' : {
+            'languages':['en', 'fr',],
+            'model':hvad_NewsExtended,
+            'overwrites':{
+                'inherit':['NewsExtended', 'hvad_NewsComplete'],
+            },
+        },
+        
+        #ALL Models
+        'all_News' : {
+            'languages':['en', 'fr',],
+            'model':all_News,
+            'overwrites':{
+                'inherit':['News',],
+                0:{
+                    'newsbox_summary':'<p>Summary of the news %d</p>',
+                    'newsbox_body':'<p>Body of the news %d</p>',
+                },
+            },
+        },
+        'all_NewsComplete' : {
+            'languages':['en', 'fr',],
+            'model':all_NewsComplete,
+            'overwrites':{
+                'inherit':['NewsComplete', 'all_News'],
+            },
+        },
+        'all_NewsExtended' : {
+            'languages':['en', 'fr',],
+            'model':all_NewsExtended,
+            'overwrites':{
+                'inherit':['NewsExtended', 'all_NewsComplete'],
+            },
+        },
+    }
+    nb_news_a_creer = len(newsTypes['News']['overwrites'])-2
+    for newsType, infos in newsTypes.items():
+        if app and app +'_' not in newsType:
+            continue
+        base_kwargs = get_fields_values(newsTypes, newsType, 0, [])
+
+
+        print '\n%s\n' % newsType + '-' * len(newsType)
+        
+        for i in range(1, nb_news_a_creer+1):
+
+            if not 'languages' in infos:
+                infos['languages'] = [None,]
+
+            for lang in infos['languages']:
+                kwargs = base_kwargs.copy()
+                kwargs.update(get_fields_values(newsTypes, newsType, i, []))
+                #Retrieve translated values if a lang is specified
+                if lang and lang in translations and translations[lang]:
+                    for k in translations[lang]:
+                        if k in kwargs :
+                            if kwargs[k][0:3] == '<p>':
+                                kwargs[k] = '<p>'+translations[lang][k]+'</p>'
+                            else:
+                                kwargs[k] = translations[lang][k]
+
+                #Add the "nth" informations for fields which need it
+                for k in kwargs:
+                    if type(kwargs[k]) in (str, unicode) and '%d' in kwargs[k]:
+                        kwargs[k] = kwargs[k] % i
+                
+                try:
+                    #Transform field into placeholders if needed
+                    ph_names = getattr(infos['model']._meta, 'placeholder_field_names')
+                    for ph_name in ph_names:
+                        if not ph_name in kwargs:
+                            continue
+                        ph = Placeholder.objects.create(slot=ph_name)
+                        add_plugin(ph, 'TextPlugin', lang if lang != None else 'en', body=kwargs[ph_name])
+                        kwargs[ph_name] = ph
+                except AttributeError:
+                    pass
+
+                translatable_values = {k:v 
+                    for k, v in kwargs.items() 
+                    if k in translatable_fields}
+                untranslatable_fields = list(set(kwargs) - set(translatable_fields))
+                untranslatable_values = {k:v 
+                    for k, v in kwargs.items() 
+                    if k in untranslatable_fields}
+                
+                langstr = ' (%s)' % lang if lang else ''
+                print ' - %d%s : %s' % (i, langstr, kwargs['newsbox_title'])
+                if lang == infos['languages'][0]:
+                    news = infos['model'](**untranslatable_values)
+
+                if lang  :
+                    news.translate(lang)
+                for k in translatable_values:
+                    setattr(news, k, translatable_values[k])
+                news.save()
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000000000000000000000000000000000000..ba0e97be1897077859e2932365860e167cf177c3
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,77 @@
+[tox]
+envlist=
+  py26-16,
+  py27-16,
+  py32-16,
+  py33-16,
+  py34-16,
+  
+  py26-cms30,
+  py27-cms30,
+; cms seems to be not yet compatible with python 3.0
+;  py32-cms30,
+;  py33-cms30,
+;  py34-cms30,
+
+[testenv]
+changedir = {toxinidir}/tests
+
+[testenv:py26-16]
+basepython = python2.6
+deps = -r{toxinidir}/test_requirements/django-1.6.txt
+commands =  ./runtests.sh myapp {posargs}
+            ./runtests.sh myapp_hvad {posargs}
+
+[testenv:py27-16]
+basepython = python2.7
+deps = -r{toxinidir}/test_requirements/django-1.6.txt
+commands = ./runtests.sh myapp {posargs}
+            ./runtests.sh myapp_hvad {posargs}
+
+[testenv:py32-16]
+basepython = python3.2
+deps = -r{toxinidir}/test_requirements/django-1.6.txt
+commands = ./runtests.sh myapp {posargs}
+;            ./runtests.sh myapp_hvad {posargs}
+
+[testenv:py33-16]
+basepython = python3.3
+deps = -r{toxinidir}/test_requirements/django-1.6.txt
+commands = ./runtests.sh myapp {posargs}
+;            ./runtests.sh myapp_hvad {posargs}
+
+[testenv:py34-16]
+basepython = python3.4
+deps = -r{toxinidir}/test_requirements/django-1.6.txt
+commands = ./runtests.sh myapp {posargs}
+;            ./runtests.sh myapp_hvad {posargs}
+
+[testenv:py26-cms30]
+basepython = python2.6
+deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt
+commands =  ./runtests.sh myapp_cms {posargs}
+            ./runtests.sh myapp_all {posargs}
+
+[testenv:py27-cms30]
+basepython = python2.7
+deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt
+commands =  ./runtests.sh myapp_cms {posargs}
+            ./runtests.sh myapp_all {posargs}
+
+[testenv:py32-cms30]
+basepython = python3.2
+deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt
+commands =  ./runtests.sh myapp_cms {posargs}
+            ./runtests.sh myapp_all {posargs}
+
+[testenv:py33-cms30]
+basepython = python3.3
+deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt
+commands =  ./runtests.sh myapp_cms {posargs}
+            ./runtests.sh myapp_all {posargs}
+
+[testenv:py34-cms30]
+basepython = python3.4
+deps = -r{toxinidir}/test_requirements/django-1.6_cms-3.0.txt
+commands =  ./runtests.sh myapp_cms {posargs}
+            ./runtests.sh myapp_all {posargs}