diff --git a/app/settings.py b/app/settings.py index c21af58..d1bb97a 100644 --- a/app/settings.py +++ b/app/settings.py @@ -102,6 +102,7 @@ STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'pipeline.finders.PipelineFinder', ) + PIPELINE_COMPILERS = ( 'pipeline.compilers.less.LessCompiler', ) @@ -165,6 +166,7 @@ MIDDLEWARE_CLASSES = ( 'cms.middleware.language.LanguageCookieMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', 'country_segment.middleware.ResolveCountryCodeMiddleware', + 'promo.middleware.cookies.PageHistoryMiddleware', ) TEMPLATE_CONTEXT_PROCESSORS = ( @@ -270,10 +272,12 @@ INSTALLED_APPS = ( 'blog', 'aldryn_bootstrap3', -#'debug_toolbar', + # 'debug_toolbar', 'djangocms_forms', 'smartsnippets', 'easy_select2', + + 'promo', ) SOUTH_MIGRATION_MODULES = { diff --git a/app/urls.py b/app/urls.py index 82b3ec1..cf4d94a 100644 --- a/app/urls.py +++ b/app/urls.py @@ -9,7 +9,11 @@ from django.conf import settings admin.autodiscover() urlpatterns = i18n_patterns('', + # url(r'^', include('cms.urls')), + url(r'^promo/', include('promo.urls', namespace='promo')), + url(r'^', include('djangocms_forms.urls')), + url(r'^admin/', include(admin.site.urls)), # NOQA url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': {'cmspages': CMSSitemap}}), @@ -17,6 +21,7 @@ urlpatterns = i18n_patterns('', url(r'^', include('cms.urls')), url(r'^taggit_autosuggest/', include('taggit_autosuggest.urls')), + ) diff --git a/service/__init__.py b/promo/__init__.py similarity index 100% rename from service/__init__.py rename to promo/__init__.py diff --git a/promo/admin.py b/promo/admin.py new file mode 100644 index 0000000..4028319 --- /dev/null +++ b/promo/admin.py @@ -0,0 +1,24 @@ +#-*- coding: utf-8 -*- +from django.contrib import admin + +from admin_enhancer.admin import EnhancedModelAdminMixin +# from cms.admin.placeholderadmin import PlaceholderAdminMixin, FrontendEditableAdminMixin +# from copy import deepcopy +# from django.contrib import admin +# from django.conf import settings +# from django.contrib.auth import get_user_model +from parler.admin import TranslatableAdmin + +from .models import Promo + + +class PromoAdmin(EnhancedModelAdminMixin, TranslatableAdmin): + fieldsets = [ + (None, { + 'fields': ['title', 'page_link', 'text'], + }), + ] + list_display = ('title',) + search_fields = ['title', 'text'] + +admin.site.register(Promo, PromoAdmin) diff --git a/promo/apps.py b/promo/apps.py new file mode 100644 index 0000000..fa815a0 --- /dev/null +++ b/promo/apps.py @@ -0,0 +1,7 @@ +#-*- coding: utf-8 -*- +from django.apps import AppConfig + + +class PromoConfig(AppConfig): + name = 'promo' + verbose_name = "Promo" \ No newline at end of file diff --git a/promo/cms_plugins.py b/promo/cms_plugins.py new file mode 100644 index 0000000..db472c4 --- /dev/null +++ b/promo/cms_plugins.py @@ -0,0 +1,84 @@ +# # -*- coding: utf-8 -*- + +from cms.plugin_base import CMSPluginBase +from cms.plugin_pool import plugin_pool +from django.utils.translation import ugettext as _ +from .models import Promo + +class PromoPluginPublisher(CMSPluginBase): + # model = PollPluginModel # model where plugin data are saved + module = _("Promos") + name = _("Promo Plugin") # name of the plugin in the interface + render_template = "promo/index.html" + + def render(self, context, instance, placeholder): + request = context['request'] + + history = request.session['history'] + + context.update({ + 'instance': Promo.objects.filter(page_link_id__in=history).order_by('?')[0], + 'history': history + }) + return context + +plugin_pool.register_plugin(PromoPluginPublisher) # register the plugin + + +# from django.utils.translation import ugettext_lazy as _ + +# from cms.models.pluginmodel import CMSPlugin +# from cms.plugin_base import CMSPluginBase +# from cms.plugin_pool import plugin_pool + +# from .models import ContextServicePlugin +# from .forms import ContextServiceForm +# from .settings import get_setting + + +# class SevicePlugin(CMSPluginBase): +# module = 'Sevice' + + +# class SeviceContextPlugin(SevicePlugin): +# """ +# Non cached plugin which returns the latest posts taking into account the +# user / toolbar state +# """ +# render_template = 'sevice/plugins/context_services.html' +# name = _('Context Services') +# model = ContextServicePlugin +# form = ContextServiceForm +# filter_horizontal = ('categories',) +# cache = False + +# def render(self, context, instance, placeholder): +# context = super(SeviceContextPlugin, self).render(context, instance, placeholder) +# context['services_list'] = instance.get_services(context['request']) + +# if instance.categories.exists(): +# context['category'] = instance.categories.all()[0].slug +# else: +# context['category'] = "all" + +# return context + + +# class SeviceContextPluginCached(SevicePlugin): +# """ +# Cached plugin which returns the latest published posts +# """ +# render_template = 'sevice/plugins/context_services.html' +# name = _('Context Services') +# model = ContextServicePlugin +# form = ContextServiceForm +# filter_horizontal = ('categories',) + +# def render(self, context, instance, placeholder): +# context = super(SeviceContextPluginCached, self).render(context, instance, placeholder) +# context['posts_list'] = instance.get_posts() + +# return context + + +# plugin_pool.register_plugin(SeviceContextPlugin) diff --git a/promo/middleware/__init__.py b/promo/middleware/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/promo/middleware/cookies.py b/promo/middleware/cookies.py new file mode 100644 index 0000000..acd0aee --- /dev/null +++ b/promo/middleware/cookies.py @@ -0,0 +1,17 @@ +#-*- coding: utf-8 -*- + + +class PageHistoryMiddleware(object): + """ + If the URLs are stale, reload them. + """ + def process_request(self, request): + if 'history' not in request.session: + request.session['history'] = [] + + history = request.session['history'] + + page = request.current_page.id + if page not in history: + history = history + [page] + request.session['history'] = history diff --git a/promo/migrations/0001_initial.py b/promo/migrations/0001_initial.py new file mode 100644 index 0000000..e316032 --- /dev/null +++ b/promo/migrations/0001_initial.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.db.models.deletion +import parler.models +import djangocms_text_ckeditor.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('cms', '0014_auto_20160404_1908'), + ] + + operations = [ + migrations.CreateModel( + name='Promo', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('title', models.CharField(max_length=200)), + ('page_link', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, blank=True, to='cms.Page', help_text='A link to a page has priority over a text link.', null=True, verbose_name='page')), + ], + options={ + 'abstract': False, + }, + bases=(parler.models.TranslatableModelMixin, models.Model), + ), + migrations.CreateModel( + name='PromoTranslation', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('language_code', models.CharField(max_length=15, verbose_name='Language', db_index=True)), + ('title', models.CharField(max_length=255, verbose_name='Title')), + ('text', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Text')), + ('master', models.ForeignKey(related_name='translations', editable=False, to='promo.Promo', null=True)), + ], + options={ + 'managed': True, + 'db_table': 'promo_promo_translation', + 'db_tablespace': '', + 'default_permissions': (), + 'verbose_name': 'promo Translation', + }, + bases=(models.Model,), + ), + migrations.AlterUniqueTogether( + name='promotranslation', + unique_together=set([('language_code', 'master')]), + ), + ] diff --git a/promo/migrations/__init__.py b/promo/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/promo/models.py b/promo/models.py new file mode 100644 index 0000000..7c6b97b --- /dev/null +++ b/promo/models.py @@ -0,0 +1,38 @@ +#-*- coding: utf-8 -*- +from django.db import models + +from cms.models import Page +from django.utils.translation import ugettext_lazy as _ +from parler.models import TranslatableModel, TranslatedFields +from djangocms_text_ckeditor.fields import HTMLField +# from parler.managers import TranslationManager + + +class Promo(TranslatableModel): + title = models.CharField(max_length=200) + + page_link = models.ForeignKey( + Page, + verbose_name=_('page'), + blank=True, + null=True, + help_text=_('A link to a page has priority over a text link.'), + on_delete=models.SET_NULL + ) + + translations = TranslatedFields( + # title=models.CharField(_('Title'), max_length=255), + text=HTMLField(_('Text')) + ) + + # objects = TranslationManager() + + class Meta: + verbose_name = _('promo') + verbose_name_plural = _('promos') + + def __unicode__(self): # Python 3: def __str__(self): + return self.title + + def __str__(self): + return self.title diff --git a/promo/templates/promo/base.html b/promo/templates/promo/base.html new file mode 100644 index 0000000..1dcc39a --- /dev/null +++ b/promo/templates/promo/base.html @@ -0,0 +1,2 @@ +{% block promo_content %} +{% endblock %} \ No newline at end of file diff --git a/promo/templates/promo/index.html b/promo/templates/promo/index.html new file mode 100644 index 0000000..160a791 --- /dev/null +++ b/promo/templates/promo/index.html @@ -0,0 +1,10 @@ + +{% extends 'promo/base.html' %} + +{% block promo_content %} +{% if instance %} + {{ instance.text }} +{% else %} +

No promo are available.

+{% endif %} +{% endblock %} \ No newline at end of file diff --git a/promo/urls.py b/promo/urls.py new file mode 100644 index 0000000..6fdcfe8 --- /dev/null +++ b/promo/urls.py @@ -0,0 +1,10 @@ +#-*- coding: utf-8 -*- + +from django.conf.urls import patterns, url + +from . import views + + +urlpatterns = patterns('', + url(r'^$', views.IndexView.as_view(), name='index'), +) diff --git a/promo/views.py b/promo/views.py new file mode 100644 index 0000000..3f1ab86 --- /dev/null +++ b/promo/views.py @@ -0,0 +1,16 @@ +#-*- coding: utf-8 -*- + +# from django.core.urlresolvers import reverse +# from django.http import HttpResponseRedirect +# from django.shortcuts import get_object_or_404, render +from django.views import generic + +from .models import Promo + + +class IndexView(generic.ListView): + template_name = 'promo/index.html' + context_object_name = 'random_promo' + + def get_queryset(self): + return Promo.objects.all().order_by('?')[0] diff --git a/service/cms_app.py b/service/cms_app.py deleted file mode 100644 index cd9ea32..0000000 --- a/service/cms_app.py +++ /dev/null @@ -1,15 +0,0 @@ -# -*- coding: utf-8 -*- -from aldryn_apphooks_config.app_base import CMSConfigApp -from cms.apphook_pool import apphook_pool -from django.utils.translation import ugettext_lazy as _ - -from .models import ServiceConfig - - -class BlogApp(CMSConfigApp): - app_config = ServiceConfig - name = _('Service') - urls = ['service.urls'] - app_name = 'service' - -apphook_pool.register(ServiceApp) diff --git a/service/cms_appconfig.py b/service/cms_appconfig.py deleted file mode 100644 index 1fd6305..0000000 --- a/service/cms_appconfig.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- - -from __future__ import unicode_literals - -from django import forms -from django.conf import settings -from django.db import models -from django.utils.translation import ugettext_lazy as _ - -from aldryn_apphooks_config.utils import setup_config -from aldryn_apphooks_config.models import AppHookConfig -from app_data import AppDataForm -from parler.models import TranslatableModel -from parler.models import TranslatedFields - -from cms.models.fields import PlaceholderField - - -class ServiceConfig(TranslatableModel, AppHookConfig): - """Adds some translatable, per-app-instance fields.""" - translations = TranslatedFields( - app_title=models.CharField(_('application title'), max_length=234), - ) - - category_slug = models.CharField( - _('Category slug'), - blank=True, - max_length=255, - help_text=_('Only category to display')) - - placeholder_base_top = PlaceholderField( - 'service_base_top', - related_name='service_base_top', - ) - - placeholder_base_sidebar = PlaceholderField( - 'service_base_sidebar', - related_name='service_base_sidebar', - ) - - placeholder_list_top = PlaceholderField( - 'service_list_top', - related_name='service_list_top', - ) - - placeholder_list_footer = PlaceholderField( - 'service_list_footer', - related_name='service_list_footer', - ) - - placeholder_detail_top = PlaceholderField( - 'service_detail_top', - related_name='service_detail_top', - ) - - placeholder_detail_bottom = PlaceholderField( - 'service_detail_bottom', - related_name='service_detail_bottom', - ) - - placeholder_detail_footer = PlaceholderField( - 'service_detail_footer', - related_name='service_detail_footer', - ) - - def get_app_title(self): - return getattr(self, 'app_title', _('untitled')) - - -class SeviceConfigForm(AppDataForm): - default_published = forms.BooleanField( - label=_(u'Post published by default'), required=False, - initial=getattr(settings, 'service_DEFAULT_PUBLISHED', True)) - -setup_config(ServiceConfigForm, ServiceConfig) diff --git a/service/cms_plugins.py b/service/cms_plugins.py deleted file mode 100644 index 5a7302f..0000000 --- a/service/cms_plugins.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from django.utils.translation import ugettext_lazy as _ - -from cms.models.pluginmodel import CMSPlugin -from cms.plugin_base import CMSPluginBase -from cms.plugin_pool import plugin_pool - -from .models import ContextServicePlugin -from .forms import ContextServiceForm -from .settings import get_setting - - -class SevicePlugin(CMSPluginBase): - module = 'Sevice' - - -class SeviceContextPlugin(SevicePlugin): - """ - Non cached plugin which returns the latest posts taking into account the - user / toolbar state - """ - render_template = 'sevice/plugins/context_services.html' - name = _('Context Services') - model = ContextServicePlugin - form = ContextServiceForm - filter_horizontal = ('categories',) - cache = False - - def render(self, context, instance, placeholder): - context = super(SeviceContextPlugin, self).render(context, instance, placeholder) - context['services_list'] = instance.get_services(context['request']) - - if instance.categories.exists(): - context['category'] = instance.categories.all()[0].slug - else: - context['category'] = "all" - - return context - - -class SeviceContextPluginCached(SevicePlugin): - """ - Cached plugin which returns the latest published posts - """ - render_template = 'sevice/plugins/context_services.html' - name = _('Context Services') - model = ContextServicePlugin - form = ContextServiceForm - filter_horizontal = ('categories',) - - def render(self, context, instance, placeholder): - context = super(SeviceContextPluginCached, self).render(context, instance, placeholder) - context['posts_list'] = instance.get_posts() - - return context - - -plugin_pool.register_plugin(SeviceContextPlugin) diff --git a/service/urls.py b/service/urls.py deleted file mode 100644 index 9b8cd5e..0000000 --- a/service/urls.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -from django.conf.urls import patterns, include, url - -from .views import (ServiceDetailView) - - -urlpatterns = patterns( - '', - url(r'^(?P[\w\.@+-]+)/$', ServiceDetailView.as_view(), name='service-detail'), -) diff --git a/service/views.py b/service/views.py deleted file mode 100644 index 914172c..0000000 --- a/service/views.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -from django.contrib.auth import get_user_model -from django.core.urlresolvers import resolve -from django.utils.timezone import now -from django.utils.translation import get_language -from django.views.generic import ListView, DetailView - -from parler.views import ViewUrlMixin, TranslatableSlugMixin - -from aldryn_apphooks_config.mixins import AppConfigMixin - -from .models import Service, ServiceCategory, SERVICE_CURRENT_SERVICE_IDENTIFIER -from .settings import get_setting - -User = get_user_model() - - -class BaseServiceView(ViewUrlMixin, AppConfigMixin): - - def get_queryset(self): - language = get_language() - queryset = self.model._default_manager.active_translations(language_code=language) - - - if self.config and self.config.category_slug: - self._category = ServiceCategory.objects.active_translations(get_language(), slug=self.config.category_slug).latest('pk') - queryset = queryset.filter(categories=self._category.pk) - - if not getattr(self.request, 'toolbar', False) or not self.request.toolbar.edit_mode: - queryset = queryset.published() - - return queryset.on_site() - - def render_to_response(self, context, **response_kwargs): - response_kwargs['current_app'] = resolve(self.request.path).namespace - return super(BaseServiceView, self).render_to_response(context, **response_kwargs) - - -class ServiceDetailView(TranslatableSlugMixin, BaseServiceView, DetailView): - model = Service - context_object_name = 'post' - template_name = 'service/service_detail.html' - slug_field = 'slug' - view_url_name = 'service:service-detail' - - def get_context_data(self, **kwargs): - context = super(PostDetailView, self).get_context_data(**kwargs) - context['meta'] = self.get_object().as_meta() - context['use_placeholder'] = get_setting('USE_PLACEHOLDER') - setattr(self.request, SERVICE_CURRENT_SERVICE_IDENTIFIER, self.get_object()) - return context -