Commits

Dries Desmet  committed ffd6008

Remove all references to cmsplugin_blog and replace it with
cmsplugin_job

  • Participants

Comments (0)

Files changed (73)

+Copyright (c) 2011, Øyvind Saltvik
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Djeese Factory GmbH nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL DJEESE FACTORY GMBH BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+recursive-include cmsplugin_job/templates *
+recursive-include cmsplugin_job/locale *
+recursive-include cmsplugin_job/static *
+A simple django-cms plugin meant to publish a few vacancies. It's based on fivethreeo's cmsplugin-blog.

File cmsplugin_job/__init__.py

+# -*- coding: utf-8 -*-
+VERSION = (1, 1, 2, 'final', 0)
+
+def get_version(): # pragma: no cover
+    version = '%s.%s' % (VERSION[0], VERSION[1])
+    if VERSION[2]:
+        version = '%s.%s' % (version, VERSION[2])
+    if VERSION[3:] == ('alpha', 0):
+        version = '%s pre-alpha' % version
+    else:
+        if VERSION[3] != 'final':
+            version = '%s %s %s' % (version, VERSION[3], VERSION[4])
+    return version

File cmsplugin_job/admin.py

+from cms.forms.widgets import PlaceholderPluginEditorWidget
+from cms.models.pluginmodel import CMSPlugin
+from cms.utils import get_language_from_request
+from cmsplugin_job.models import Entry, EntryTitle
+from cmsplugin_job.widgets import AutoCompleteTagInput
+from django import forms
+from django.contrib import admin
+from django.conf import settings
+from django.forms import CharField
+from django.http import HttpResponse
+from django.template.defaultfilters import title
+from django.utils.text import capfirst
+from django.utils.translation import ugettext_lazy as _
+from simple_translation.admin import PlaceholderTranslationAdmin
+from simple_translation.forms import TranslationModelForm
+from simple_translation.utils import get_translation_queryset
+
+class EntryForm(TranslationModelForm):
+        
+    class Meta:
+        model = Entry
+        widgets = {'tags': AutoCompleteTagInput}
+        
+class M2MPlaceholderAdmin(PlaceholderTranslationAdmin):
+    
+    def get_form(self, request, obj=None, **kwargs):
+        """
+        Get PageForm for the Page model and modify its fields depending on
+        the request.
+        """
+        form = super(M2MPlaceholderAdmin, self).get_form(request, obj, **kwargs)
+        
+        if obj:        
+            
+            for placeholder_name in obj._meta.get_field('placeholders').placeholders:
+                
+                placeholder, created = obj.placeholders.get_or_create(slot=placeholder_name)
+                
+                defaults = {'label': capfirst(placeholder_name), 'help_text': ''}
+                defaults.update(kwargs)
+                
+                widget = PlaceholderPluginEditorWidget(request, self.placeholder_plugin_filter)
+                widget.choices = []
+                
+                form.base_fields[placeholder.slot] = CharField(widget=widget, required=False)   
+                form.base_fields[placeholder.slot].initial = placeholder.pk
+                
+        return form
+        
+    def get_fieldsets(self, request, obj=None):
+        """
+        Add fieldsets of placeholders to the list of already existing
+        fieldsets.
+        """
+        given_fieldsets = super(M2MPlaceholderAdmin, self).get_fieldsets(request, obj=None)
+
+        if obj: # edit
+            for placeholder_name in obj._meta.get_field('placeholders').placeholders:
+                given_fieldsets += [(title(placeholder_name), {'fields':[placeholder_name], 'classes':['plugin-holder']})]
+
+        return given_fieldsets
+            
+    def move_plugin(self, request): # pragma: no cover
+        
+        def get_placeholder(plugin, request):
+            
+            return plugin.placeholder
+            
+        if request.method == "POST":    
+            if 'plugin_id' in request.POST:
+                plugin = CMSPlugin.objects.get(pk=int(request.POST['plugin_id']))
+                if "placeholder" in request.POST:
+                    obj = plugin.placeholder._get_attached_model().objects.get(placeholders__cmsplugin=plugin)
+                    placeholder = obj.placeholders.get(slot=request.POST["placeholder"])
+                else:
+                    placeholder = plugin.placeholder
+                # plugin positions are 0 based, so just using count here should give us 'last_position + 1'
+                position = CMSPlugin.objects.filter(placeholder=placeholder).count()
+                plugin.placeholder = placeholder
+                plugin.position = position
+                plugin.save()
+            pos = 0
+            if 'ids' in request.POST:
+                for id in request.POST['ids'].split("_"):
+                    plugin = CMSPlugin.objects.get(pk=id)
+                    if plugin.position != pos:
+                        plugin.position = pos
+                        plugin.save()
+                    pos += 1
+            else:
+                HttpResponse(str("error"))
+            return HttpResponse(str("ok"))
+        else:
+            return HttpResponse(str("error"))        
+                
+class BaseEntryAdmin(M2MPlaceholderAdmin):
+    
+    form = EntryForm
+    
+    # needed because of admin validation
+    prepopulated_fields = not settings.DEBUG and {'slug': ('title',)} or {}
+    
+    search_fields = ('entrytitle__title', 'tags')
+    list_display = ('title', 'languages', 'author', 'is_published', 'pub_date')
+    list_editable = ('is_published',)
+    list_filter = ('is_published', 'pub_date')
+    date_hierarchy = 'pub_date'
+
+    def author(self, obj):
+        return get_translation_queryset(obj)[0].author
+    author.short_description = _('author')
+    author.admin_order_field = 'entrytitle__author'
+
+    def title(self, obj):
+        return get_translation_queryset(obj)[0].title
+    title.short_description = _('title')
+    title.admin_order_field = 'entrytitle__title'
+    
+    # needed because of admin validation
+    def get_fieldsets(self, request, obj=None):
+        fieldsets = super(BaseEntryAdmin, self).get_fieldsets(request, obj=obj)
+        fieldsets[0] = (None, {'fields': (
+            'language',
+            'is_published',
+            'pub_date',
+            'author',
+            'title',
+            'slug',
+            'tags'
+        )})
+        return fieldsets
+        
+    def save_translated_model(self, request, obj, translation_obj, form, change):
+        if not translation_obj.author:
+            translation_obj.author=request.user
+        super(BaseEntryAdmin, self).save_translated_model(request, obj, translation_obj, form, change)
+
+if 'guardian' in settings.INSTALLED_APPS: # pragma: no cover
+    from guardian.admin import GuardedModelAdmin
+    class EntryAdmin(BaseEntryAdmin, GuardedModelAdmin):
+        pass
+else:
+    EntryAdmin = BaseEntryAdmin
+    
+admin.site.register(Entry, EntryAdmin)

File cmsplugin_job/cms_app.py

+from cms.app_base import CMSApp
+from cms.apphook_pool import apphook_pool
+from django.utils.translation import ugettext_lazy as _
+
+class JobApphook(CMSApp):
+    name = _("Jobs Apphook")
+    urls = ["cmsplugin_job.urls"]
+
+apphook_pool.register(JobApphook)

File cmsplugin_job/cms_plugins.py

+from django.utils.translation import ugettext_lazy as _
+
+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+from cms.utils import get_language_from_request
+
+from simple_translation.utils import get_translation_filter_language
+
+from cmsplugin_job.models import LatestJobsPlugin, Job
+
+class CMSLatestJobsPlugin(CMSPluginBase):
+    """
+        Plugin class for the latest jobs
+    """
+    model = LatestJobsPlugin
+    name = _('Latest jobs')
+    render_template = "cmsplugin_job/latest_jobs_plugin.html"
+    
+    def render(self, context, instance, placeholder):
+        """
+            Render the latest entries
+        """
+        qs = Jobs.published.all()
+        
+        if instance.current_language_only:
+            language = get_language_from_request(context["request"])
+            kw = get_translation_filter_language(Job, language)
+            qs = qs.filter(**kw)
+            
+        latest = qs[:instance.limit]
+        
+        context.update({
+            'instance': instance,
+            'latest': latest,
+            'object_list': latest,
+            'placeholder': placeholder
+        })
+        return context
+
+plugin_pool.register_plugin(CMSLatestJobsPlugin)

File cmsplugin_job/locale/de/LC_MESSAGES/django.mo

Binary file added.

File cmsplugin_job/locale/de/LC_MESSAGES/django.po

+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# raphaa <webmaster@raphaa.de>, 2011.
+msgid ""
+msgstr ""
+"Project-Id-Version: cmsplugin-blog\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-07-28 21:47+0200\n"
+"PO-Revision-Date: 2011-05-19 14:42+0000\n"
+"Last-Translator: raphaa <webmaster@raphaa.de>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: de_DE\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:110 models.py:91
+msgid "author"
+msgstr "Autor"
+
+#: admin.py:115 models.py:89
+msgid "title"
+msgstr "Titel"
+
+#: cms_app.py:6
+msgid "Blog Apphook"
+msgstr "Blog-Applikation"
+
+#: cms_plugins.py:12 templates/cmsplugin_blog/entry_archive.html:5
+msgid "Latest entries"
+msgstr "Die neuesten Einträge"
+
+#: feeds.py:45 feeds.py:56
+#, python-format
+msgid "%(site)s blog entries"
+msgstr "%(site)s Blog-Einträge"
+
+#: feeds.py:46 feeds.py:57
+#, python-format
+msgid "%(site)s blog entries in %(lang)s"
+msgstr "%(site)s Blog-Einträge in %(lang)s"
+
+#: feeds.py:85
+#, python-format
+msgid "%(title)s tagged \"%(tag)s\""
+msgstr "%(title)s markiert \"%(tag)s\""
+
+#: feeds.py:97
+#, python-format
+msgid "%(description)s tagged \"%(tag)s\""
+msgstr "%(description)s markiert \"%(tag)s\""
+
+#: feeds.py:114
+#, python-format
+msgid "%(title)s by %(author)s"
+msgstr "%(title)s von \"%(author)s\""
+
+#: feeds.py:126
+#, python-format
+msgid "%(description)s by %(author)s"
+msgstr "%(description)s by \"%(author)s\""
+
+#: models.py:40
+msgid "is published"
+msgstr "Veröffentlicht"
+
+#: models.py:41
+msgid "publish at"
+msgstr "Veröffentlicht am"
+
+#: models.py:80 models.py:87
+msgid "entry"
+msgstr "Eintrag"
+
+#: models.py:81
+msgid "entries"
+msgstr "Einträge"
+
+#: models.py:88
+msgid "language"
+msgstr "Sprache"
+
+#: models.py:90
+msgid "slug"
+msgstr "Slug"
+
+#: models.py:107
+msgid "entry title"
+msgstr "Eintragtitel"
+
+#: models.py:108
+msgid "entry titles"
+msgstr "Eintragtitel"
+
+#: models.py:114
+msgid "Number of entries items to show"
+msgstr "Anzahl der angezeigten Einträge"
+
+#: models.py:115
+msgid "Limits the number of items that will be displayed"
+msgstr "Maximale Anzahl an Elemente, die angezeigt werden sollen"
+
+#: models.py:117
+msgid "Only show entries for the current language"
+msgstr "Nur Einträge für die aktuelle Sprache anzeigen"
+
+#: templates/cmsplugin_blog/author_links_snippet.html:3
+msgid "See entries by"
+msgstr "Einträge von"
+
+#: templates/cmsplugin_blog/entry_archive.html:14
+#: templates/cmsplugin_blog/latest_entries.html:7
+msgid "No entries"
+msgstr "Keine Einträge"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:6
+#: templates/cmsplugin_blog/entry_archive_month.html:6
+#: templates/cmsplugin_blog/entry_archive_year.html:7
+msgid "Entries for"
+msgstr "Einträge für"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:14
+msgid "No entries for this day"
+msgstr "Keine Einträge für diesen Tag"
+
+#: templates/cmsplugin_blog/entry_archive_month.html:13
+msgid "No entries for this month"
+msgstr "Keine Einträge für diesen Monat"
+
+#: templates/cmsplugin_blog/entry_archive_year.html:12
+msgid "No entries for this year"
+msgstr "Keine Einträge für dieses Jahr"
+
+#: templates/cmsplugin_blog/entry_author_list.html:11
+msgid "Entries by"
+msgstr "Einträge von"
+
+#: templates/cmsplugin_blog/entry_author_list.html:20
+msgid "No entries by"
+msgstr "Keine Einträge von"
+
+#: templates/cmsplugin_blog/entry_list.html:11
+msgid "Entries tagged"
+msgstr "Markierte Einträge"
+
+#: templates/cmsplugin_blog/entry_list.html:20
+msgid "No entries tagged"
+msgstr "Keine Einträge markiert"
+
+#: templates/cmsplugin_blog/month_links_snippet.html:3
+msgid "See entries for"
+msgstr "Einträge für"
+
+#: templates/cmsplugin_blog/tag_links_snippet.html:3
+msgid "See entries tagged"
+msgstr "Markierte Einträge"

File cmsplugin_job/locale/en/LC_MESSAGES/django.mo

Binary file added.

File cmsplugin_job/locale/en/LC_MESSAGES/django.po

+# 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.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-08-12 11:23+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
+
+#: admin.py:110 models.py:91
+msgid "author"
+msgstr ""
+
+#: admin.py:115 models.py:89
+msgid "title"
+msgstr ""
+
+#: cms_app.py:6
+msgid "Blog Apphook"
+msgstr ""
+
+#: cms_plugins.py:12 templates/cmsplugin_blog/entry_archive.html:5
+msgid "Latest entries"
+msgstr ""
+
+#: feeds.py:45 feeds.py:56
+#, python-format
+msgid "%(site)s blog entries"
+msgstr ""
+
+#: feeds.py:46 feeds.py:57
+#, python-format
+msgid "%(site)s blog entries in %(lang)s"
+msgstr ""
+
+#: feeds.py:85
+#, python-format
+msgid "%(title)s tagged \"%(tag)s\""
+msgstr ""
+
+#: feeds.py:97
+#, python-format
+msgid "%(description)s tagged \"%(tag)s\""
+msgstr ""
+
+#: feeds.py:114
+#, python-format
+msgid "%(title)s by %(author)s"
+msgstr ""
+
+#: feeds.py:126
+#, python-format
+msgid "%(description)s by %(author)s"
+msgstr ""
+
+#: models.py:40
+msgid "is published"
+msgstr ""
+
+#: models.py:41
+msgid "publish at"
+msgstr ""
+
+#: models.py:80 models.py:87
+msgid "entry"
+msgstr ""
+
+#: models.py:81
+msgid "entries"
+msgstr ""
+
+#: models.py:88
+msgid "language"
+msgstr ""
+
+#: models.py:90
+msgid "slug"
+msgstr ""
+
+#: models.py:108
+msgid "blogentry"
+msgstr ""
+
+#: models.py:109
+msgid "blogentries"
+msgstr ""
+
+#: models.py:115
+msgid "Number of entries items to show"
+msgstr ""
+
+#: models.py:116
+msgid "Limits the number of items that will be displayed"
+msgstr ""
+
+#: models.py:118
+msgid "Only show entries for the current language"
+msgstr ""
+
+#: templates/cmsplugin_blog/author_links_snippet.html:3
+msgid "See entries by"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_archive.html:17
+#: templates/cmsplugin_blog/latest_entries.html:13
+msgid "No entries"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_archive_day.html:6
+#: templates/cmsplugin_blog/entry_archive_month.html:6
+#: templates/cmsplugin_blog/entry_archive_year.html:7
+msgid "Entries for"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_archive_day.html:17
+msgid "No entries for this day"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_archive_month.html:18
+msgid "No entries for this month"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_archive_year.html:12
+msgid "No entries for this year"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_author_list.html:11
+msgid "Entries by"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_author_list.html:23
+msgid "No entries by"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_list.html:11
+msgid "Entries tagged"
+msgstr ""
+
+#: templates/cmsplugin_blog/entry_list.html:23
+msgid "No entries tagged"
+msgstr ""
+
+#: templates/cmsplugin_blog/month_links_snippet.html:3
+msgid "See entries for"
+msgstr ""
+
+#: templates/cmsplugin_blog/tag_links_snippet.html:3
+msgid "See entries tagged"
+msgstr ""

File cmsplugin_job/locale/nb/LC_MESSAGES/django.mo

Binary file added.

File cmsplugin_job/locale/nb/LC_MESSAGES/django.po

+# 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: cmsplugin-blog\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-08-12 11:23+0200\n"
+"PO-Revision-Date: 2011-05-18 14:18+0000\n"
+"Last-Translator: fivethreeo <oyvind.saltvik@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: nb\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: admin.py:110 models.py:91
+msgid "author"
+msgstr "forfatter"
+
+#: admin.py:115 models.py:89
+#, fuzzy
+msgid "title"
+msgstr "Tittel"
+
+#: cms_app.py:6
+msgid "Blog Apphook"
+msgstr "Blogg Applikasjon"
+
+#: cms_plugins.py:12 templates/cmsplugin_blog/entry_archive.html:5
+msgid "Latest entries"
+msgstr "Siste innlegg"
+
+#: feeds.py:45 feeds.py:56
+#, fuzzy, python-format
+msgid "%(site)s blog entries"
+msgstr "Blogginlegg"
+
+#: feeds.py:46 feeds.py:57
+#, fuzzy, python-format
+msgid "%(site)s blog entries in %(lang)s"
+msgstr "Bloginnlegg på %s"
+
+#: feeds.py:85
+#, python-format
+msgid "%(title)s tagged \"%(tag)s\""
+msgstr "%(title)s tagget med \"%(tag)s\""
+
+#: feeds.py:97
+#, python-format
+msgid "%(description)s tagged \"%(tag)s\""
+msgstr "%(description)s tagget med \"%(tag)s\""
+
+#: feeds.py:114
+msgid "%(title)s by %(author)s"
+msgstr "%(title)s av %(author)s"
+
+#: feeds.py:126
+msgid "%(description)s by %(author)s"
+msgstr "%(description)s av %(author)s"
+
+#: models.py:40
+msgid "is published"
+msgstr "er publisert"
+
+#: models.py:41
+msgid "publish at"
+msgstr "publisert når"
+
+#: models.py:80 models.py:87
+msgid "entry"
+msgstr "innlegg"
+
+#: models.py:81
+msgid "entries"
+msgstr "innlegg"
+
+#: models.py:88
+msgid "language"
+msgstr "Språk"
+
+#: models.py:90
+msgid "slug"
+msgstr "Pen adressse"
+
+#: models.py:108
+msgid "blogentry"
+msgstr "innlegg"
+
+#: models.py:109
+msgid "blogentries"
+msgstr "Blogginlegg"
+
+#: models.py:115
+msgid "Number of entries items to show"
+msgstr "Antall innlegg som skal vises"
+
+#: models.py:116
+msgid "Limits the number of items that will be displayed"
+msgstr "Begrenser antall innlegg som vil bli vist"
+
+#: models.py:118
+msgid "Only show entries for the current language"
+msgstr "Bare vis innlegg for aktivt språk"
+
+#: templates/cmsplugin_blog/author_links_snippet.html:3
+msgid "See entries by"
+msgstr "Se innlegg av"
+
+#: templates/cmsplugin_blog/entry_archive.html:17
+#: templates/cmsplugin_blog/latest_entries.html:13
+msgid "No entries"
+msgstr "Ingen innlegg"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:6
+#: templates/cmsplugin_blog/entry_archive_month.html:6
+#: templates/cmsplugin_blog/entry_archive_year.html:7
+msgid "Entries for"
+msgstr "Innlegg for"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:17
+msgid "No entries for this day"
+msgstr "Ingen innlegg for denne dagen"
+
+#: templates/cmsplugin_blog/entry_archive_month.html:18
+msgid "No entries for this month"
+msgstr "Ingen innlegg for denne måneden"
+
+#: templates/cmsplugin_blog/entry_archive_year.html:12
+msgid "No entries for this year"
+msgstr "Ingen innlegg for dette året"
+
+#: templates/cmsplugin_blog/entry_author_list.html:11
+msgid "Entries by"
+msgstr "Innlegg for"
+
+#: templates/cmsplugin_blog/entry_author_list.html:23
+#, fuzzy
+msgid "No entries by"
+msgstr "Ingen bloginnlegg av"
+
+#: templates/cmsplugin_blog/entry_list.html:11
+msgid "Entries tagged"
+msgstr "Bloginnlegg tagget"
+
+#: templates/cmsplugin_blog/entry_list.html:23
+msgid "No entries tagged"
+msgstr "Ingen innlegg tagget"
+
+#: templates/cmsplugin_blog/month_links_snippet.html:3
+msgid "See entries for"
+msgstr "Se innlegg for"
+
+#: templates/cmsplugin_blog/tag_links_snippet.html:3
+msgid "See entries tagged"
+msgstr "Se innlegg med stikkord"
+
+#~ msgid "Published"
+#~ msgstr "Publisert"

File cmsplugin_job/locale/pl/LC_MESSAGES/django.mo

Binary file added.

File cmsplugin_job/locale/pl/LC_MESSAGES/django.po

+# 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.
+# 
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2011-09-17 16:36+0100\n"
+"PO-Revision-Date: 2011-09-17 17:49\n"
+"Last-Translator:   <krzysztof.bandurski@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: \n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+"X-Translated-Using: django-rosetta 0.6.2\n"
+
+#: admin.py:111 models.py:100
+msgid "author"
+msgstr "autor"
+
+#: admin.py:116 models.py:98
+msgid "title"
+msgstr "tytuł"
+
+#: cms_app.py:6
+msgid "Blog Apphook"
+msgstr "Blog Apphook"
+
+#: cms_plugins.py:16 templates/cmsplugin_blog/entry_archive.html:7
+msgid "Latest entries"
+msgstr "Ostatnie wpisy"
+
+#: feeds.py:47 feeds.py:58
+#, python-format
+msgid "%(site)s blog entries"
+msgstr "wpisy %(site)s"
+
+#: feeds.py:48 feeds.py:59
+#, python-format
+msgid "%(site)s blog entries in %(lang)s"
+msgstr "wpisy %(site)s w jęz. %(lang)s"
+
+#: feeds.py:88
+#, python-format
+msgid "%(title)s tagged \"%(tag)s\""
+msgstr "%(title)s oznaczony tagiem \"%(tag)s\""
+
+#: feeds.py:100
+#, python-format
+msgid "%(description)s tagged \"%(tag)s\""
+msgstr "%(description)s oznaczony tagiem \"%(tag)s\""
+
+#: feeds.py:117
+#, python-format
+msgid "%(title)s by %(author)s"
+msgstr "%(title)s wpisane przez %(author)s"
+
+#: feeds.py:129
+#, python-format
+msgid "%(description)s by %(author)s"
+msgstr "%(description)s wpisane przez %(author)s"
+
+#: models.py:40
+msgid "is published"
+msgstr "opublikowany"
+
+#: models.py:41
+msgid "publish at"
+msgstr "publikuj"
+
+#: models.py:86 models.py:96
+msgid "entry"
+msgstr "wpis"
+
+#: models.py:87
+msgid "entries"
+msgstr "wpisy"
+
+#: models.py:97
+msgid "language"
+msgstr "język"
+
+#: models.py:99
+msgid "slug"
+msgstr "slug"
+
+#: models.py:122
+msgid "blogentry"
+msgstr "wpis"
+
+#: models.py:123
+msgid "blogentries"
+msgstr "wpisy"
+
+#: models.py:129
+msgid "Number of entries items to show"
+msgstr "Ilość wpisów do pokazania"
+
+#: models.py:130
+msgid "Limits the number of items that will be displayed"
+msgstr "Ogranicza ilość wyświetlanych elementów"
+
+#: models.py:132
+msgid "Only show entries for the current language"
+msgstr "Pokaż tylko wpisy w bieżącym języku"
+
+#: templates/cmsplugin_blog/author_links_snippet.html:3
+msgid "See entries by"
+msgstr "Pokaż wpisy, których autorem jest"
+
+#: templates/cmsplugin_blog/entry_archive.html:19
+#: templates/cmsplugin_blog/latest_entries.html:12
+msgid "No entries"
+msgstr "Ilość wpisów"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:7
+#: templates/cmsplugin_blog/entry_archive_month.html:7
+#: templates/cmsplugin_blog/entry_archive_year.html:8
+msgid "Entries for"
+msgstr "Wpisy z"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:18
+msgid "No entries for this day"
+msgstr "Ilość wpisów z tego dnia"
+
+#: templates/cmsplugin_blog/entry_archive_month.html:19
+msgid "No entries for this month"
+msgstr "Ilość wpisów z tego miesiąca"
+
+#: templates/cmsplugin_blog/entry_archive_year.html:13
+msgid "No entries for this year"
+msgstr "Ilość wpisów z tego roku"
+
+#: templates/cmsplugin_blog/entry_author_list.html:13
+msgid "Entries by"
+msgstr "Wpisy dodane przez"
+
+#: templates/cmsplugin_blog/entry_author_list.html:25
+msgid "No entries by"
+msgstr "Ilość wpisów dodanych przez"
+
+#: templates/cmsplugin_blog/entry_list.html:13
+msgid "Entries tagged"
+msgstr "Wpisy oznaczone tagami"
+
+#: templates/cmsplugin_blog/entry_list.html:25
+msgid "No entries tagged"
+msgstr "Ilość wpisów oznaczonych tagami"
+
+#: templates/cmsplugin_blog/month_links_snippet.html:3
+msgid "See entries for"
+msgstr "Pokaż wpisy z"
+
+#: templates/cmsplugin_blog/tag_links_snippet.html:3
+msgid "See entries tagged"
+msgstr "Pokaż wpisy oznaczone tagami"

File cmsplugin_job/locale/ru/LC_MESSAGES/django.mo

Binary file added.

File cmsplugin_job/locale/ru/LC_MESSAGES/django.po

+# 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: cmsplugin-blog\n"
+"Report-Msgid-Bugs-To: http://github.com/fivethreeo/cmsplugin-blog/issues\n"
+"POT-Creation-Date: 2011-03-03 23:32+0100\n"
+"PO-Revision-Date: 2011-05-16 00:10+0000\n"
+"Last-Translator: fivethreeo <oyvind.saltvik@gmail.com>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n"
+
+#: cms_app.py:6
+msgid "Blog Apphook"
+msgstr "Блог"
+
+#: cms_plugins.py:12 templates/cmsplugin_blog/entry_archive.html:5
+msgid "Latest entries"
+msgstr "Последние записи"
+
+#: feeds.py:36 feeds.py:47
+msgid "Blog entries"
+msgstr "Записи блога"
+
+#: feeds.py:37 feeds.py:48
+#, python-format
+msgid "Blog entries in %s"
+msgstr "Записи блога на %s"
+
+#: feeds.py:74
+#, python-format
+msgid "%(title)s tagged \"%(tag)s\""
+msgstr "%(title)s с тегом \"%(tag)s\""
+
+#: feeds.py:86
+#, python-format
+msgid "%(description)s tagged \"%(tag)s\""
+msgstr "%(description)s с тегом \"%(tag)s\""
+
+#: models.py:38
+msgid "Is published"
+msgstr "Опубликована"
+
+#: models.py:39
+msgid "Published"
+msgstr "Опубликована"
+
+#: models.py:49 models.py:56
+msgid "entry"
+msgstr ""
+
+#: models.py:50
+msgid "entries"
+msgstr ""
+
+#: models.py:57
+msgid "Language"
+msgstr "Язык"
+
+#: models.py:58
+msgid "Title"
+msgstr "Заголовок"
+
+#: models.py:59
+msgid "Slug"
+msgstr "Slug"
+
+#: models.py:76
+msgid "entry title"
+msgstr ""
+
+#: models.py:77
+msgid "entry titles"
+msgstr ""
+
+#: models.py:83
+msgid "Number of entries items to show"
+msgstr "Количество отображаемых записей"
+
+#: models.py:84
+msgid "Limits the number of items that will be displayed"
+msgstr "Ограничение количества отображаемых записей"
+
+#: models.py:86
+msgid "Only show entries for the current language"
+msgstr "Показывать записи только на текущем языке"
+
+#: templates/cmsplugin_blog/entry_archive.html:14
+#: templates/cmsplugin_blog/latest_entries.html:7
+msgid "No entries"
+msgstr "Нет записей"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:6
+#: templates/cmsplugin_blog/entry_archive_month.html:6
+#: templates/cmsplugin_blog/entry_archive_year.html:7
+msgid "Entries for"
+msgstr "Записи для"
+
+#: templates/cmsplugin_blog/entry_archive_day.html:14
+msgid "No entries for this day"
+msgstr "Нет записей за этот день"
+
+#: templates/cmsplugin_blog/entry_archive_month.html:13
+msgid "No entries for this month"
+msgstr "Нет записей за этот месяц"
+
+#: templates/cmsplugin_blog/entry_archive_year.html:12
+msgid "No entries for this year"
+msgstr "Нет записей за этот год"
+
+#: templates/cmsplugin_blog/entry_list.html:5
+msgid "Entries tagged"
+msgstr "Записи с тегом"
+
+#: templates/cmsplugin_blog/entry_list.html:14
+msgid "No entries tagged"
+msgstr "Нет записей с тегом"
+
+#: templates/cmsplugin_blog/month_links_snippet.html:3
+msgid "See entries for"
+msgstr "Смотреть запись для"
+
+#: templates/cmsplugin_blog/tag_links_snippet.html:3
+msgid "See entries tagged"
+msgstr "Смотреть записи с тегом"

File cmsplugin_job/middleware.py

+from simple_translation.middleware import MultilingualGenericsMiddleware, filter_queryset_language
+
+class MultilingualJobEntriesMiddleware(MultilingualGenericsMiddleware):
+    
+    language_fallback_middlewares = [
+        'django.middleware.locale.LocaleMiddleware',
+        'cms.middleware.multilingual.MultilingualURLMiddleware'
+    ]
+
+    def process_view(self, request, view_func, view_args, view_kwargs):
+        super(MultilingualJobEntriesMiddleware, self).process_view(request, view_func, view_args, view_kwargs)
+        if 'queryset_or_model' in view_kwargs and hasattr(view_kwargs['queryset_or_model'], 'model'):
+            view_kwargs['queryset_or_model'] = filter_queryset_language(request, view_kwargs['queryset_or_model'])

File cmsplugin_job/models.py

+import datetime
+
+from django.core.urlresolvers import reverse
+from django.db import models
+from django.db.models.query import QuerySet
+from django.conf import settings
+from django.utils.translation import get_language, ugettext_lazy as _
+
+from cms.utils.placeholder import PlaceholderNoAction
+from cms.utils.urlutils import urljoin
+
+from cms.models import CMSPlugin, Title
+
+from simple_translation.actions import SimpleTranslationPlaceholderActions
+from djangocms_utils.fields import M2MPlaceholderField
+
+class PublishedJobsQueryset(QuerySet):
+    
+    def published(self):
+        return self.filter(is_published=True, pub_date__lte=datetime.datetime.now())
+        
+class JobsManager(models.Manager):
+    
+    def get_query_set(self):
+        return PublishedJobsQueryset(self.model)
+                            
+class PublishedJobsManager(JobsManager):
+    """
+        Filters out all unpublished and items with a publication date in the future
+    """
+    def get_query_set(self):
+        return super(PublishedEntriesManager, self).get_query_set().published()
+                    
+CMSPLUGIN_JOB_PLACEHOLDERS = getattr(settings, 'CMSPLUGIN_JOB_PLACEHOLDERS', ('job', ))
+              
+class Job(models.Model):
+    is_published = models.BooleanField(_('is published'))
+    pub_date = models.DateTimeField(_('publish at'), default=datetime.datetime.now)
+ 
+    placeholders = M2MPlaceholderField(actions=SimpleTranslationPlaceholderActions(), placeholders=CMSPLUGIN_BLOG_PLACEHOLDERS)
+    
+    objects = JobsManager()
+    published = PublishedJobsManager()
+
+    def get_absolute_url(self, language=None):
+        if not language:
+            language = get_language()
+        try:
+            url = self.jobtitle_set.get(language=language).get_absolute_url()
+            if url[1:len(language)+1] == language:
+                url = url[len(language)+1:]
+            return url
+        except JobTitle.DoesNotExist:
+            return ''
+
+    def language_changer(self, language):
+        url = self.get_absolute_url(language)
+        if url:
+            return url
+
+        # There is no entry in the given language, we return blog's root
+
+        blog_prefix = ''
+
+        try:
+            title = Title.objects.get(application_urls='JobApphook', language=language)
+            blog_prefix = urljoin(reverse('pages-root'), title.overwrite_url or title.slug)
+        except Title.DoesNotExist:
+            # Blog app hook not defined anywhere?
+            pass
+
+        return blog_prefix or reverse('pages-root')
+        
+    def _template(self):
+        from simple_translation.utils import get_translated_model
+        model = get_translated_model(self.__class__)
+        return model.DETAIL_TEMPLATE
+    template = property(_template)
+         
+    class Meta:
+        verbose_name = _('job')
+        verbose_name_plural = _('jobs')
+        ordering = ('-pub_date', )
+
+
+class AbstractJobTitle(models.Model):
+    
+    DETAIL_TEMPLATE = 'cmsplugin_job/job_detail.html'
+    
+    job = models.ForeignKey(Job, verbose_name=_('job'))
+    language = models.CharField(_('language'), max_length=15, choices=settings.LANGUAGES)
+    title = models.CharField(_('title'), max_length=255)
+    slug = models.SlugField(_('slug'), max_length=255)
+    
+    def __unicode__(self):
+        return self.title
+        
+    def _get_absolute_url(self):
+        language_namespace = 'cmsplugin_job.middleware.MultilingualJobEntriesMiddleware' in settings.MIDDLEWARE_CLASSES and '%s:' % self.language or ''
+        return ('%sjob_detail' % language_namespace, (), {
+            'slug': self.slug,
+        })
+    get_absolute_url = models.permalink(_get_absolute_url)
+
+    class Meta:
+        unique_together = ('language', 'slug')
+        abstract=True
+    
+class JobTitle(AbstractJobTitle):
+    
+    class Meta:
+        verbose_name = _('jobentry')
+        verbose_name_plural = _('jobentries')
+        unique_together = ('language', 'slug')
+        
+class LatestJobsPlugin(CMSPlugin):
+    """
+        Model for the settings when using the latest jobs cms plugin
+    """
+    limit = models.PositiveIntegerField(_('Number of job items to show'), 
+                    help_text=_('Limits the number of jobs that will be displayed'))
+                    
+    current_language_only = models.BooleanField(_('Only show jobs for the current language'))

File cmsplugin_job/simple_translate.py

+from cmsplugin_blog.models import Entry, EntryTitle
+from simple_translation.translation_pool import translation_pool
+
+translation_pool.register_translation(Entry, EntryTitle)
+

File cmsplugin_job/sitemaps.py

+from django.contrib.sitemaps import Sitemap
+from cmsplugin_blog.models import EntryTitle
+
+class BlogSitemap(Sitemap):
+    changefreq = "monthly"
+    priority = 0.5
+
+    def items(self):
+        return EntryTitle.objects.filter(entry__is_published=True)
+
+    def lastmod(self, obj):
+        return obj.entry.pub_date

File cmsplugin_job/static/cmsplugin_job/change_form.js

+(function($) {
+    $(document).ready(function() {
+        // saveform event handler
+        $('#entry_form').submit(function(){
+            if($('iframe').length){
+                var question = gettext("Not all plugins are saved. Are you sure you want to save the page?\nAll unsaved plugin content will tried to save.");
+                var answer = confirm(question, true);
+                if (answer){
+                    $('iframe').contents().find('#content-main>form').each(function(){
+                        try{
+                            this.submit();
+                        } catch(err) { 
+                            return false;
+                        }
+                    });
+                    return true;
+                }else{
+                    return false;
+                }
+            }
+        });
+    });
+})(blog.jQuery);

File cmsplugin_job/static/cmsplugin_job/cmsplugin_blog.css

+.ui-menu-item {
+	list-style-type: none;
+}

File cmsplugin_job/static/cmsplugin_job/jquery_init.js

+var blog = {
+    "jQuery": jQuery.noConflict(true)
+};
+
+(function($){
+// add csrf here if needed
+})(blog.jQuery);

File cmsplugin_job/templates/admin/cmsplugin_job/admin_helpers.html

+{% if use_missing %}
+    <script type="text/javascript" src="{{ STATIC_URL|default:MEDIA_URL }}missing/n11ndata.js"></script>
+    <script type="text/javascript" src="{{ STATIC_URL|default:MEDIA_URL }}missing/n11n.js"></script>
+    <script type="text/javascript" src="{{ STATIC_URL|default:MEDIA_URL }}missing/urlify2.js"></script>
+{% endif %}

File cmsplugin_job/templates/admin/cmsplugin_job/change_form.html

+{% extends "admin/change_form.html" %}
+
+{% block extrahead %}
+{% load cmsplugin_blog_tags %}
+{{ block.super }}
+{% if not add %}
+    <script type="text/javascript" src="{{ STATIC_URL|default:MEDIA_URL }}cmsplugin_blog/change_form.js"></script>
+{% endif %}
+    {% admin_helpers %}
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/cmsplugin_job_base.html

+{% block extrahead %}
+{{ block.super }}
+<link rel="alternate" type="application/rss+xml" title="RSS feed" href="{% if request.LANGUAGE_CODE %}/{{ request.LANGUAGE_CODE }}{% endif %}{% url blog_rss %}" />
+<link rel="alternate" type="application/rss+xml" title="RSS feed (any language)" href="{% if request.LANGUAGE_CODE %}/{{ request.LANGUAGE_CODE }}{% endif %}{% url blog_rss_any %}" />
+{% endblock extrahead %}

File cmsplugin_job/templates/cmsplugin_job/entry_archive_day.html

+{% extends "cmsplugin_blog/cmsplugin_blog_base.html" %}
+{% load i18n cmsplugin_blog_tags %}
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% trans "Entries for" %} {{ day|date:"d F Y" }}</h1>
+
+{% if object_list %}
+   {% include "cmsplugin_blog/entry_list_include.html" %}
+{% else %}
+	<p>{% trans "No entries for this day" %}</p>
+{% endif %}
+
+{% endblock %}
+
+{% block right-col %}
+
+{% render_author_links %}
+
+{% render_month_links %}
+
+{% render_tag_links %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/entry_archive_month.html

+{% extends "cmsplugin_blog/cmsplugin_blog_base.html" %}
+{% load i18n cmsplugin_blog_tags %}
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% trans "Entries for" %} {{ month|date:"F Y" }}</h1>
+
+{% if object_list %}
+   {% include "cmsplugin_blog/entry_list_include.html" %}
+{% else %}
+	<p>{% trans "No entries for this month" %}</p>
+{% endif %}
+
+{% endblock %}
+
+{% block right-col %}
+
+{% render_author_links %}
+
+{% render_month_links %}
+
+{% render_tag_links %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/entry_archive_year.html

+{% extends "cmsplugin_blog/cmsplugin_blog_base.html" %}
+
+{% load i18n cmsplugin_blog_tags %}
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% trans "Entries for" %} {{ year }}</h1>
+<ul>
+    {% for date in date_list %}
+        <li><a href="{% url blog_archive_month year=year month=date|date:'m'  %}">{{ date|date:"F" }}</a></li>
+    {% empty %}
+        <li>{% trans "No entries for this year" %}</li>
+    {% endfor %}
+</ul>
+
+{% endblock %}
+
+{% block right-col %}
+
+{% render_author_links %}
+
+{% render_month_links %}
+
+{% render_tag_links %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/entry_author_list.html

+{% extends "cmsplugin_blog/cmsplugin_blog_base.html" %}
+{% load i18n cmsplugin_blog_tags %}
+
+{% block extrahead %}
+{{ block.super }}
+<link rel="alternate" type="application/rss+xml" title="RSS feed for author {{ author|escape }}" href="{% if request.LANGUAGE_CODE %}/{{ request.LANGUAGE_CODE }}{% endif %}{% url blog_rss_author author %}" />
+<link rel="alternate" type="application/rss+xml" title="RSS feed for author {{ author|escape }} (any language)" href="{% if request.LANGUAGE_CODE %}/{{ request.LANGUAGE_CODE }}{% endif %}{% url blog_rss_any_author author %}" />
+{% endblock extrahead %}
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% trans "Entries by" %} {{ author }}</h1>
+
+{% if object_list %}
+   {% include "cmsplugin_blog/entry_list_include.html" %}
+{% else %}
+	<p>{% trans "No entries by" %} {{ author }}</p>
+{% endif %}
+
+{% endblock %}
+
+{% block right-col %}
+
+{% render_author_links %}
+
+{% render_month_links %}
+
+{% render_tag_links %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/entry_detail.html

+{% extends "cmsplugin_blog/cmsplugin_blog_base.html" %}
+
+{% load placeholder_tags cmsplugin_blog_tags simple_translation_tags %}
+
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% with object|get_preferred_translation_from_request:request as title %}{{ title }}{% endwith %}</h1>
+
+<p class="date"><span>{{ object.pub_date|date:"d F Y" }}</span></p>
+
+{% with object.placeholders|choose_placeholder:"job" as job %}
+    {% render_placeholder job %}
+{% endwith %}
+
+{% endblock %}
+
+{% block right-col %}
+
+{% render_author_links %}
+
+{% render_month_links %}
+
+{% render_tag_links %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/entry_list.html

+{% extends "cmsplugin_blog/cmsplugin_blog_base.html" %}
+{% load i18n cmsplugin_blog_tags %}
+
+{% block extrahead %}
+{{ block.super }}
+<link rel="alternate" type="application/rss+xml" title="RSS feed for tag &quot;{{ tag|escape }}&quot;" href="{% if request.LANGUAGE_CODE %}/{{ request.LANGUAGE_CODE }}{% endif %}{% url blog_rss_tagged tag %}" />
+<link rel="alternate" type="application/rss+xml" title="RSS feed for tag &quot;{{ tag|escape }}&quot; (any language)" href="{% if request.LANGUAGE_CODE %}/{{ request.LANGUAGE_CODE }}{% endif %}{% url blog_rss_any_tagged tag %}" />
+{% endblock extrahead %}
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% trans "Entries tagged" %} "{{ tag }}"</h1>
+
+{% if object_list %}
+   {% include "cmsplugin_blog/entry_list_include.html" %}
+{% else %}
+	<p>{% trans "No entries tagged" %} "{{ tag }}"</p>
+{% endif %}
+
+{% endblock %}
+
+{% block right-col %}
+
+{% render_author_links %}
+
+{% render_month_links %}
+
+{% render_tag_links %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/feed_author_description.html

+{% include "cmsplugin_blog/feed_entries_description.html" %}

File cmsplugin_job/templates/cmsplugin_job/feed_author_title.html

+{% include "cmsplugin_blog/feed_entries_title.html" %}

File cmsplugin_job/templates/cmsplugin_job/feed_entries_description.html

+{% load placeholder_tags cmsplugin_blog_tags %}{% with obj.entry.placeholders|choose_placeholder:"excerpt" as excerpt %}{% render_placeholder excerpt %}{% endwith %}

File cmsplugin_job/templates/cmsplugin_job/feed_entries_title.html

+{{ obj }}

File cmsplugin_job/templates/cmsplugin_job/feed_tagged_description.html

+{% include "cmsplugin_blog/feed_entries_description.html" %}

File cmsplugin_job/templates/cmsplugin_job/feed_tagged_title.html

+{% include "cmsplugin_blog/feed_entries_title.html" %}

File cmsplugin_job/templates/cmsplugin_job/job_index.html

+{% extends "cmsplugin_job/cmsplugin_job_base.html" %}
+{% load i18n %}
+
+{% block left-col %}
+{{ block.super }}
+
+<h1>{% trans "Latest jobs" %}</h1>
+
+{% with latest as object_list %}
+{% if object_list %}
+   {% include "cmsplugin_job/job_list_include.html" %}
+{% else %}
+	<p>{% trans "No jobs" %}</p>
+{% endif %}
+{% endwith %}
+
+{% endblock %}
+
+{% block right-col %}
+
+{% endblock %}

File cmsplugin_job/templates/cmsplugin_job/job_list_include.html

+
+{% load i18n placeholder_tags cmsplugin_blog_tags simple_translation_tags %}
+{% for job in object_list|annotate_with_translations %}
+    {% with job|get_preferred_translation_from_request:request as title %}
+    {% with job.placeholders|choose_placeholder:"excerpt" as excerpt %}
+    <p>{{ job.pub_date|date:"d b Y" }}<br/><a href="{{ title.get_absolute_url }}">{{ title }}</a>
+       {{ job|render_language_choices:request|safe }}
+    </p>
+    {% render_placeholder excerpt %}
+    {% endwith %}
+    {% endwith %}
+{% endfor %}

File cmsplugin_job/templates/cmsplugin_job/latest_jobs_plugin.html

+{% load i18n %}
+{% if object_list %}
+   {% include "cmsplugin_blog/entry_list_include.html" %}
+{% else %}
+	<p>{% trans "No entries" %}</p>
+{% endif %}

File cmsplugin_job/templatetags/__init__.py

Empty file added.

File cmsplugin_job/templatetags/cmsplugin_job_tags.py

+import datetime
+from django.conf import settings
+from django import template
+from django.contrib.auth import models as auth_models
+
+from tagging.models import Tag
+
+from cms.utils import get_language_from_request
+from cmsplugin_blog.models import Entry, EntryTitle
+from cms.models import Placeholder
+
+from simple_translation.translation_pool import translation_pool
+from simple_translation.utils import get_translation_filter_language
+
+register = template.Library()
+
+@register.inclusion_tag('cmsplugin_blog/month_links_snippet.html', takes_context=True)
+def render_month_links(context):
+    request = context["request"]
+    language = get_language_from_request(request)
+    kw = get_translation_filter_language(Entry, language)
+    return {
+        'dates': Entry.published.filter(**kw).dates('pub_date', 'month'),
+    }
+
+@register.inclusion_tag('cmsplugin_blog/tag_links_snippet.html', takes_context=True)
+def render_tag_links(context):
+    request = context["request"]
+    language = get_language_from_request(request)
+    kw = get_translation_filter_language(Entry, language)
+    filters = dict(is_published=True, pub_date__lte=datetime.datetime.now(), **kw)
+    return {
+        'tags': Tag.objects.usage_for_model(Entry, filters=filters)
+    }
+
+@register.inclusion_tag('cmsplugin_blog/author_links_snippet.html', takes_context=True)
+def render_author_links(context, order_by='username'):
+    request = context["request"]
+    language = get_language_from_request(request)
+    info = translation_pool.get_info(Entry)
+    model = info.translated_model
+    kw = get_translation_filter_language(Entry, language)
+    return {
+        'authors': auth_models.User.objects.filter(
+            pk__in=model.objects.filter(
+                entry__in=Entry.published.filter(**kw)
+            ).values('author')
+        ).order_by(order_by).values_list('username', flat=True)
+    }
+
+@register.filter
+def choose_placeholder(placeholders, placeholder):
+    try:
+        return placeholders.get(slot=placeholder)
+    except Placeholder.DoesNotExist:
+        return None
+
+
+@register.inclusion_tag('admin/cmsplugin_blog/admin_helpers.html')
+def admin_helpers():
+    return {
+        'use_missing': 'missing' in settings.INSTALLED_APPS,
+    }

File cmsplugin_job/test/__init__.py

Empty file added.

File cmsplugin_job/test/run_tests.py

+import sys
+import os
+import django
+
+INSTALLED_APPS = [
+    'cmsplugin_blog.test.testapp',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.admin',
+    'django.contrib.sites',        
+    'cms',
+    'cms.plugins.text',
+    'mptt',
+    'menus',
+    'tagging',
+    'simple_translation',    
+    'cmsplugin_blog',
+    'djangocms_utils',
+    'sekizai'
+]
+
+MIDDLEWARE_CLASSES = [
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.middleware.doc.XViewMiddleware',
+    'django.contrib.csrf.middleware.CsrfViewMiddleware',
+    'cms.middleware.multilingual.MultilingualURLMiddleware',
+    'cms.middleware.user.CurrentUserMiddleware',
+    'cms.middleware.page.CurrentPageMiddleware',
+    'cms.middleware.toolbar.ToolbarMiddleware',
+    'cmsplugin_blog.middleware.MultilingualBlogEntriesMiddleware'
+]
+
+TEMPLATE_CONTEXT_PROCESSORS = [
+    "django.core.context_processors.auth",
+    "django.core.context_processors.i18n",
+    "django.core.context_processors.debug",
+    "django.core.context_processors.request",
+    "django.core.context_processors.media"
+]
+
+if django.VERSION[1] < 3: # pragma: no cover
+    MIDDLEWARE_CLASSES.insert(12, 'cbv.middleware.DeferredRenderingMiddleware')
+    INSTALLED_APPS.append('staticfiles')
+    INSTALLED_APPS.append('cbv')
+    TEMPLATE_CONTEXT_PROCESSORS.append('staticfiles.context_processors.static')
+else:
+    INSTALLED_APPS.append('django.contrib.staticfiles')
+    TEMPLATE_CONTEXT_PROCESSORS.append('django.core.context_processors.static')
+    
+def run_tests():
+    
+    from django.conf import settings
+    
+    settings.configure(
+        INSTALLED_APPS=INSTALLED_APPS,
+        MIDDLEWARE_CLASSES = MIDDLEWARE_CLASSES,
+        TEMPLATE_CONTEXT_PROCESSORS = TEMPLATE_CONTEXT_PROCESSORS,
+        DATABASES = {
+            'default': {
+                'ENGINE': 'django.db.backends.sqlite3',
+                'NAME': 'blog_tests.db',
+            }
+        },
+        CMS_TEMPLATES = (
+            ('nav_playground.html', 'default'),
+        ),
+        ROOT_URLCONF='cmsplugin_blog.test.testapp.urls',
+        USE_I8N=True,
+        LANGUAGE_CODE='en',
+        LANGUAGES=(('en', 'English'),('de','German'),('nb','Norwegian'),('nn','Norwegian Nynorsk')),
+        JQUERY_UI_CSS='',
+        JQUERY_JS='',
+        JQUERY_UI_JS='',
+        STATIC_URL='/some/url/',
+        STATIC_ROOT=os.path.join(os.path.dirname(os.path.abspath(__file__)), os.path.pardir, os.path.pardir),
+        TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner',
+        TEST_OUTPUT_VERBOSE = True
+    )
+    
+    from django.test.utils import get_runner
+
+    failures = get_runner(settings)().run_tests(['cmsplugin_blog'])
+    sys.exit(failures)
+
+if __name__ == '__main__':
+    run_tests()

File cmsplugin_job/test/testapp/__init__.py

Empty file added.

File cmsplugin_job/test/testapp/models.py

Empty file added.

File cmsplugin_job/test/testapp/templates/cmsplugin_blog/cmsplugin_blog_base.html

+{% load menu_tags sekizai_tags %}
+{% render_block css %}
+{% block left-col %}{% language_chooser %}{% endblock left-col %}
+{% block right-col %}{% endblock right-col %}
+{% render_block js %}

File cmsplugin_job/test/testapp/templates/nav_playground.html

+{% load cms_tags %}
+{% placeholder "body" %}

File cmsplugin_job/test/testapp/templates/sitemap.xml

+<?xml version="1.0" encoding="UTF-8"?>
+<urlset
+  xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
+  xmlns:news="http://www.google.com/schemas/sitemap-news/0.9">
+{% spaceless %}
+{% for url in urlset %}
+  <url>
+    <loc>{{ url.location }}</loc>
+    {% if url.lastmod %}<lastmod>{{ url.lastmod|date:"Y-m-d" }}</lastmod>{% endif %}
+    {% if url.changefreq %}<changefreq>{{ url.changefreq }}</changefreq>{% endif %}
+    {% if url.priority %}<priority>{{ url.priority }}</priority>{% endif %}
+   </url>
+{% endfor %}
+{% endspaceless %}
+</urlset>

File cmsplugin_job/test/testapp/urls.py

+from django.conf.urls.defaults import *
+from django.contrib import admin
+from cmsplugin_blog.sitemaps import BlogSitemap
+
+admin.autodiscover()
+
+urlpatterns = patterns('',
+    (r'^admin/', include(admin.site.urls)),
+    (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
+)
+
+
+urlpatterns += patterns('',
+    url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {
+        'sitemaps': {
+            'blogentries': BlogSitemap
+        }
+    }),
+    url(r'^', include('cms.urls'))
+)

File cmsplugin_job/test/testcases.py

+from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from django.template.defaultfilters import slugify
+
+from cms.test_utils.testcases import CMSTestCase
+from cms.models.titlemodels import Title
+from cms.api import create_page
+
+from simple_translation.utils import get_translation_manager
+
+from cmsplugin_blog.models import Entry
+
+class BaseBlogTestCase(CMSTestCase):
+
+    def setUp(self):
+        superuser = User.objects.create_superuser('admin', 'admin@admin.com', 'admin')
+        home = create_page('home', 'nav_playground.html', 'en', published=True, created_by=superuser)
+        page = create_page( 'test-page-1', 'nav_playground.html', 'en', parent=home, published=True, created_by=superuser)
+        english_title = page.title_set.all()[0]
+        self.assertEquals(english_title.language, 'en')
+        Title.objects.create(
+            language='de',
+            title='%s DE' % english_title.title,
+            slug=english_title.slug,
+            path=english_title.path,
+            page=page
+        )
+        Title.objects.create(
+            language='nb',
+            title='%s NB' % english_title.title,
+            slug=english_title.slug,
+            path=english_title.path,
+            page=page
+        )
+        page.title_set.all().update(application_urls='BlogApphook')
+        reverse('en:blog_archive_index') # fill cache