migrations

This commit is contained in:
2018-03-15 12:42:13 +01:00
parent 29e19deebc
commit 25001e38c9
419 changed files with 44849 additions and 2142 deletions

View File

@@ -1 +1,75 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from cms.extensions import PageExtensionAdmin
from parler.admin import TranslatableAdmin
from django.contrib.admin.models import LogEntry, DELETION
from django.utils.html import escape
from django.core.urlresolvers import reverse
from project.models import ImageExtension, SliderItemQualification
@admin.register(ImageExtension)
class ImageExtensionAdmin(PageExtensionAdmin):
pass
@admin.register(SliderItemQualification)
class SliderItemQualificationAdmin(TranslatableAdmin):
pass
# https://djangosnippets.org/snippets/2484/
@admin.register(LogEntry)
class LogEntryAdmin(admin.ModelAdmin):
date_hierarchy = 'action_time'
readonly_fields = LogEntry._meta.get_all_field_names()
list_filter = [
'user',
'content_type',
'action_flag'
]
search_fields = [
'object_repr',
'change_message'
]
list_display = [
'action_time',
'user',
'content_type',
'object_link',
'action_flag',
'change_message',
]
def has_add_permission(self, request):
return False
def has_change_permission(self, request, obj=None):
return request.user.is_superuser and request.method != 'POST'
def has_delete_permission(self, request, obj=None):
return False
def object_link(self, obj):
if obj.action_flag == DELETION:
link = escape(obj.object_repr)
else:
ct = obj.content_type
link = u'<a href="%s">%s</a>' % (
reverse('admin:%s_%s_change' % (ct.app_label, ct.model), args=[obj.object_id]),
escape(obj.object_repr),
)
return link
object_link.allow_tags = True
object_link.admin_order_field = 'object_repr'
object_link.short_description = u'object'
def queryset(self, request):
return super(LogEntryAdmin, self).queryset(request) \
.prefetch_related('content_type')

304
src/project/cms_plugins.py Normal file
View File

@@ -0,0 +1,304 @@
# -*- coding: utf-8 -*-
from aldryn_forms.cms_plugins import FormPlugin as _FormPlugin
from cms.models.pluginmodel import CMSPlugin
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from django.conf import settings
from djangocms_picture.cms_plugins import PicturePlugin as _PicturePlugin
from djangocms_text_ckeditor.cms_plugins import TextPlugin as _TextPlugin
from django.contrib import admin
from mailchimp3 import MailChimp
from project.forms import NewsletterSubscriptionForm
from project.models import Section, Quote, SliderItem, SectionText, Video, DownloadSection, DownloadSectionFolder, \
TextSliderItem, HighlightListItem, ReferenceListItem, SocialMediaList, SocialMediaListItem, Timetable, \
TimetableItem, Partner, HighlightList, Image, TitleListItem, TitleList
@plugin_pool.register_plugin
class SectionPlugin(CMSPluginBase):
model = Section
module = 'Content'
name = 'Section'
render_template = 'project/plugins/content/section.html'
allow_children = True
child_classes = ['QuotePlugin', 'SliderPlugin', 'SpacerPlugin', 'SectionTitlePlugin', 'TitleListPlugin',
'SectionTextPlugin', 'VideoPlugin', 'DownloadSectionPlugin', 'TextSliderPlugin',
'HighlightListPlugin', 'ReferenceListPlugin', 'FormPlugin', 'PicturePlugin', 'SubPageListPlugin',
'PartnerPlugin', 'NewsletterSubscriptionPlugin', 'NewsletterArchivePlugin',
'SocialMediaListPlugin']
@plugin_pool.register_plugin
class SectionTitlePlugin(CMSPluginBase):
model = CMSPlugin
module = 'Content'
name = 'Section Title'
render_template = 'project/plugins/content/section_title.html'
plugin_pool.unregister_plugin(_TextPlugin)
@plugin_pool.register_plugin
class TextPlugin(_TextPlugin):
child_classes = ['LinkPlugin']
@plugin_pool.register_plugin
class SectionTextPlugin(CMSPluginBase):
model = SectionText
module = 'Content'
name = 'Section Text'
render_template = 'project/plugins/content/section_text.html'
allow_children = True
child_classes = ['TextPlugin']
@plugin_pool.register_plugin
class VideoPlugin(CMSPluginBase):
model = Video
module = 'Content'
name = 'Video'
render_template = 'project/plugins/content/video.html'
@plugin_pool.register_plugin
class SliderPlugin(CMSPluginBase):
model = CMSPlugin
module = 'Content'
name = 'Slider'
render_template = 'project/plugins/content/slider.html'
allow_children = True
child_classes = ['SliderItemPlugin']
@plugin_pool.register_plugin
class SliderItemPlugin(CMSPluginBase):
model = SliderItem
module = 'Slider'
name = 'Slider Item'
render_template = 'project/plugins/content/slider_item.html'
filter_horizontal = ['qualifications']
@plugin_pool.register_plugin
class QuotePlugin(CMSPluginBase):
model = Quote
module = 'Content'
name = 'Quote'
render_template = 'project/plugins/content/quote.html'
class DownloadSectionFolderInlineAdmin(admin.TabularInline):
model = DownloadSectionFolder
extra = 0
@plugin_pool.register_plugin
class DownloadSectionPlugin(CMSPluginBase):
model = DownloadSection
module = 'Content'
name = 'Download Section'
render_template = 'project/plugins/content/download_section.html'
inlines = [DownloadSectionFolderInlineAdmin]
@plugin_pool.register_plugin
class SpacerPlugin(CMSPluginBase):
model = CMSPlugin
module = 'Content'
name = 'Spacer'
render_template = 'project/plugins/content/spacer.html'
@plugin_pool.register_plugin
class TextSliderPlugin(CMSPluginBase):
model = CMSPlugin
module = 'Content'
name = 'Text Slider'
render_template = 'project/plugins/content/text_slider.html'
allow_children = True
child_classes = ['TextSliderItemPlugin']
@plugin_pool.register_plugin
class TextSliderItemPlugin(CMSPluginBase):
model = TextSliderItem
module = 'Slider'
name = 'Text Slider Item'
render_template = 'project/plugins/content/text_slider_item.html'
@plugin_pool.register_plugin
class HighlightListPlugin(CMSPluginBase):
model = HighlightList
module = 'Content'
name = 'Highlight List'
render_template = 'project/plugins/content/highlight_list.html'
allow_children = True
child_classes = ['HighlightListItemPlugin', 'SectionTitlePlugin']
@plugin_pool.register_plugin
class HighlightListItemPlugin(CMSPluginBase):
model = HighlightListItem
module = 'Slider'
name = 'Highlight List Item'
render_template = 'project/plugins/content/highlight_list_item.html'
@plugin_pool.register_plugin
class ReferenceListPlugin(CMSPluginBase):
model = CMSPlugin
module = 'Content'
name = 'Reference List'
render_template = 'project/plugins/content/reference_list.html'
allow_children = True
child_classes = ['ReferenceListItemPlugin']
@plugin_pool.register_plugin
class ReferenceListItemPlugin(CMSPluginBase):
model = ReferenceListItem
module = 'Slider'
name = 'Highlight List Item'
render_template = 'project/plugins/content/reference_list_item.html'
plugin_pool.unregister_plugin(_PicturePlugin)
@plugin_pool.register_plugin
class PicturePlugin(_PicturePlugin):
module = 'Content'
name = 'Image'
model = Image
fieldsets = [
(None, {
'fields': (
'picture',
'cropping',
('width', 'height'),
'caption_text',
)
}),
]
plugin_pool.unregister_plugin(_FormPlugin)
@plugin_pool.register_plugin
class FormPlugin(_FormPlugin):
module = 'Content'
name = 'Form'
child_classes = ['TextField', 'TextAreaField', 'EmailField', 'SubmitButton']
class SocialMediaListItemInlineAdmin(admin.TabularInline):
model = SocialMediaListItem
extra = 0
@plugin_pool.register_plugin
class SocialMediaListPlugin(CMSPluginBase):
model = SocialMediaList
module = 'Content'
name = 'Social Media List'
render_template = 'project/plugins/social/social_media_list.html'
inlines = [SocialMediaListItemInlineAdmin]
@plugin_pool.register_plugin
class JourneyCalculatorPlugin(CMSPluginBase):
module = 'Content'
name = 'Anfahrtszeit Rechner'
render_template = 'project/plugins/contact/journey_calculator.html'
allow_children = True
child_classes = ['TextPlugin']
@plugin_pool.register_plugin
class TimetablePlugin(CMSPluginBase):
model = Timetable
module = 'Timetable'
name = 'Timetable'
render_template = 'project/plugins/timetable/timetable.html'
allow_children = True
child_classes = ['TimetableItemPlugin']
@plugin_pool.register_plugin
class TimetableItemPlugin(CMSPluginBase):
model = TimetableItem
module = 'Timetable'
name = 'Timetable Item'
render_template = 'project/plugins/timetable/timetable_item.html'
@plugin_pool.register_plugin
class SubPageListPlugin(CMSPluginBase):
model = CMSPlugin
module = 'Content'
name = 'Subpage List'
render_template = 'project/plugins/content/subpage_list.html'
@plugin_pool.register_plugin
class PartnerPlugin(CMSPluginBase):
model = Partner
module = 'Content'
name = 'Partner'
render_template = 'project/plugins/content/partner.html'
@plugin_pool.register_plugin
class NewsletterSubscriptionPlugin(CMSPluginBase):
module = 'Content'
name = 'Newsletter Subscription'
render_template = 'project/newsletter/subscription_form.html'
def render(self, context, instance, placeholder):
context = super(NewsletterSubscriptionPlugin, self).render(context, instance, placeholder)
context['form'] = NewsletterSubscriptionForm
return context
@plugin_pool.register_plugin
class NewsletterArchivePlugin(CMSPluginBase):
module = 'Content'
name = 'Newsletter Archive'
render_template = 'project/newsletter/archive.html'
def render(self, context, instance, placeholder):
context = super(NewsletterArchivePlugin, self).render(context, instance, placeholder)
client = MailChimp(settings.MAILCHIMP_USERNAME, settings.MAILCHIMP_API_KEY)
campaigns = []
for raw_campaign in client.campaigns.all(get_all=True)['campaigns']:
if raw_campaign['status'] == 'sent':
campaign = {
'title': raw_campaign['settings']['title'],
'text': raw_campaign['settings']['subject_line'],
'url': raw_campaign['archive_url'],
}
campaigns.append(campaign)
context['campaigns'] = campaigns
return context
class TitleListItemInlineAdmin(admin.TabularInline):
model = TitleListItem
extra = 0
@plugin_pool.register_plugin
class TitleListPlugin(CMSPluginBase):
model = TitleList
module = 'Content'
name = 'Title List'
render_template = 'project/plugins/content/title_list.html'
inlines = [TitleListItemInlineAdmin]

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from cms.toolbar_pool import toolbar_pool
from cms.extensions.toolbar import ExtensionToolbar
from django.utils.translation import ugettext_lazy as _
from project.models import ImageExtension
@toolbar_pool.register
class ImageExtensionToolbar(ExtensionToolbar):
model = ImageExtension
def populate(self):
current_page_menu = self._setup_extension_toolbar()
if current_page_menu:
page_extension, url = self.get_page_extension_admin()
if url:
current_page_menu.add_modal_item('Seiten-Bild', url=url, disabled=not self.toolbar.edit_mode,
position=0)

View File

@@ -0,0 +1,5 @@
from haystack.forms import ModelSearchForm
def search_form(request):
return {'search_form': ModelSearchForm}

49
src/project/forms.py Normal file
View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
from django.utils.translation import ugettext_lazy as _, get_language
from django import forms
from django.conf import settings
from mailchimp3 import MailChimp
client = MailChimp(settings.MAILCHIMP_USERNAME, settings.MAILCHIMP_API_KEY)
field_names = [_('First Name'), _('Last Name')]
class NewsletterSubscriptionForm(forms.Form):
email = forms.EmailField(max_length=254, label=_('E-Mail'),
widget=forms.TextInput(attrs={'placeholder': _('E-Mail')}))
def __init__(self, *args, **kwargs):
super(NewsletterSubscriptionForm, self).__init__(*args, **kwargs)
merge_fields = client.lists.merge_fields.all(list_id=settings.MAILCHIMP_LIST_ID, get_all=True)
for field in merge_fields['merge_fields']:
if field['type'] == 'text':
self.fields[field['tag']] = forms.CharField(
label=field['name'], required=field['required'],
widget=forms.TextInput(
attrs={'placeholder': _(field['name'])}
)
)
def clean(self):
cleaned_data = super(NewsletterSubscriptionForm, self).clean()
if not self._errors:
merge_data = cleaned_data.copy()
merge_data.pop('email')
try:
client.lists.members.create(settings.MAILCHIMP_LIST_ID, {
'email_address': cleaned_data['email'],
'language': get_language(),
'status': 'subscribed',
'merge_fields': merge_data,
})
except Exception as err:
json_err = err.response.json()
if json_err['title'] == 'Member Exists':
raise forms.ValidationError(
_('Diese E-Mail-Adresse wurde bereits registriert.')
)
else:
raise forms.ValidationError(
_('Leider ist ein Fehler aufgetreten, bitte versuchen sie es später nochmals.')
)

View File

@@ -0,0 +1,297 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-02-06 01:53
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import djangocms_text_ckeditor.fields
import filer.fields.folder
import filer.fields.image
import fontawesome.fields
import parler.models
class Migration(migrations.Migration):
initial = True
dependencies = [
('cms', '0018_pagenode'),
migrations.swappable_dependency(settings.FILER_IMAGE_MODEL),
('filer', '0007_auto_20161016_1055'),
]
operations = [
migrations.CreateModel(
name='DownloadSection',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_downloadsection', serialize=False, to='cms.CMSPlugin')),
],
options={
'verbose_name': 'Download Section',
'verbose_name_plural': 'Download Sections',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='DownloadSectionFolder',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ordering', models.IntegerField(default=5, verbose_name='Sortierung')),
('download_section', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='folders', to='project.DownloadSection', verbose_name='Download Section')),
('folder', filer.fields.folder.FilerFolderField(on_delete=django.db.models.deletion.CASCADE, to='filer.Folder', verbose_name='Ordner')),
],
options={
'ordering': ['ordering'],
},
),
migrations.CreateModel(
name='HighlightList',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_highlightlist', serialize=False, to='cms.CMSPlugin')),
('full_width', models.BooleanField(default=False, verbose_name='Volle Breite')),
],
options={
'verbose_name': 'Highlight List',
'verbose_name_plural': 'Highlight Lists',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='HighlightListItem',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_highlightlistitem', serialize=False, to='cms.CMSPlugin')),
('icon', fontawesome.fields.IconField(blank=True, max_length=60, null=True, verbose_name='Icon')),
('animated_icon', models.CharField(blank=True, choices=[('strength', 'Stärken'), ('learning', 'Lernen'), ('creativity', 'Kreativität'), ('curiosity', 'Neugierde'), ('education', 'Bildung'), ('happiness', 'Glücklichkeit')], max_length=256, null=True, verbose_name='Animiertes Icon')),
('title', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Titel')),
('text', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Text')),
],
options={
'verbose_name': 'Highlight List Item',
'verbose_name_plural': 'Highlight List Items',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='ImageExtension',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extended_object', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, to='cms.Page')),
('image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild')),
('public_extension', models.OneToOneField(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='draft_extension', to='project.ImageExtension')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='Partner',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_partner', serialize=False, to='cms.CMSPlugin')),
('name', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Titel')),
('text', djangocms_text_ckeditor.fields.HTMLField(blank=True, null=True, verbose_name='Text')),
('url', models.URLField(blank=True, null=True, verbose_name='URL')),
('logo', filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild')),
],
options={
'verbose_name': 'Slider Item',
'verbose_name_plural': 'Slider Items',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='Quote',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_quote', serialize=False, to='cms.CMSPlugin')),
('content', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Inhalt')),
('source', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Quelle')),
('image', filer.fields.image.FilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild')),
],
options={
'verbose_name': 'Quote',
'verbose_name_plural': 'Quotes',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='ReferenceListItem',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_referencelistitem', serialize=False, to='cms.CMSPlugin')),
('vimeo_id', models.IntegerField(help_text='e.g. https://vimeo.com/<b>131766159</b>', verbose_name='Vimeo ID')),
('thumbnail', filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Vorschaubild')),
],
options={
'verbose_name': 'Reference List Item',
'verbose_name_plural': 'Reference List Items',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='Section',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_section', serialize=False, to='cms.CMSPlugin')),
('title', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Titel')),
],
options={
'verbose_name': 'Section',
'verbose_name_plural': 'Sections',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='SectionText',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_sectiontext', serialize=False, to='cms.CMSPlugin')),
('columns', models.BooleanField(default=False, verbose_name='Spalten')),
],
options={
'verbose_name': 'Section Text',
'verbose_name_plural': 'Section Texts',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='SliderItem',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_slideritem', serialize=False, to='cms.CMSPlugin')),
('title', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Titel')),
('subline', djangocms_text_ckeditor.fields.HTMLField(blank=True, null=True, verbose_name='Untertitel')),
('text', djangocms_text_ckeditor.fields.HTMLField(blank=True, null=True, verbose_name='Text')),
('email', models.EmailField(blank=True, max_length=254, null=True, verbose_name='E-Mail')),
('image', filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild')),
],
options={
'verbose_name': 'Slider Item',
'verbose_name_plural': 'Slider Items',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='SliderItemQualification',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('ordering', models.IntegerField(default=5, verbose_name='Sortierung')),
],
options={
'ordering': ['ordering'],
},
bases=(parler.models.TranslatableModelMixin, models.Model),
),
migrations.CreateModel(
name='SliderItemQualificationTranslation',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')),
('name', models.CharField(max_length=256, verbose_name='name')),
('master', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='project.SliderItemQualification')),
],
options={
'db_table': 'project_slideritemqualification_translation',
'default_permissions': (),
'managed': True,
'verbose_name': 'slider item qualification Translation',
'db_tablespace': '',
},
),
migrations.CreateModel(
name='SocialMediaList',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_socialmedialist', serialize=False, to='cms.CMSPlugin')),
],
options={
'verbose_name': 'Social Media List',
'verbose_name_plural': 'Social Media Lists',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='SocialMediaListItem',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('icon', fontawesome.fields.IconField(blank=True, max_length=60, verbose_name='Icon')),
('url', models.URLField(verbose_name='URL')),
('ordering', models.IntegerField(default=5, verbose_name='Sortierung')),
('social_media_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='social_media_list_items', to='project.SocialMediaList', verbose_name='Social Media List')),
],
options={
'ordering': ['ordering'],
},
),
migrations.CreateModel(
name='TextSliderItem',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_textslideritem', serialize=False, to='cms.CMSPlugin')),
('text', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Text')),
],
options={
'verbose_name': 'Text Slider Item',
'verbose_name_plural': 'Text Slider Items',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='Timetable',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_timetable', serialize=False, to='cms.CMSPlugin')),
('introduction', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Einleitung')),
('start_image', filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Startbild')),
],
options={
'verbose_name': 'Timetable',
'verbose_name_plural': 'Timetables',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='TimetableItem',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_timetableitem', serialize=False, to='cms.CMSPlugin')),
('time', models.TimeField(verbose_name='Zeit')),
('title', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Titel')),
('text', djangocms_text_ckeditor.fields.HTMLField(verbose_name='Text')),
('image', filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild')),
],
options={
'verbose_name': 'Timetable Item',
'verbose_name_plural': 'Timetables Items',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='Video',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_video', serialize=False, to='cms.CMSPlugin')),
('vimeo_id', models.IntegerField(help_text='e.g. https://vimeo.com/<b>131766159</b>', verbose_name='Vimeo ID')),
('thumbnail', filer.fields.image.FilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Vorschaubild')),
],
options={
'verbose_name': 'Video',
'verbose_name_plural': 'Videos',
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.AddField(
model_name='slideritem',
name='qualifications',
field=models.ManyToManyField(blank=True, null=True, to='project.SliderItemQualification', verbose_name='Qualifikationen'),
),
migrations.AlterUniqueTogether(
name='slideritemqualificationtranslation',
unique_together=set([('language_code', 'master')]),
),
]

View File

@@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-02-14 13:15
from __future__ import unicode_literals
import cms.models.fields
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import djangocms_attributes_field.fields
import image_cropping.fields
import project.utils
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.FILER_IMAGE_MODEL),
('cms', '0018_pagenode'),
('filer', '0007_auto_20161016_1055'),
('project', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Image',
fields=[
('template', models.CharField(choices=[('default', 'Default')], default='default', max_length=255, verbose_name='Template')),
('external_picture', models.URLField(blank=True, help_text='If provided, overrides the embedded image. Certain options such as cropping are not applicable to external images.', max_length=255, verbose_name='External image')),
('width', models.PositiveIntegerField(blank=True, help_text='The image width as number in pixels. Example: "720" and not "720px".', null=True, verbose_name='Width')),
('height', models.PositiveIntegerField(blank=True, help_text='The image height as number in pixels. Example: "720" and not "720px".', null=True, verbose_name='Height')),
('alignment', models.CharField(blank=True, choices=[('left', 'Align left'), ('right', 'Align right'), ('center', 'Align center')], help_text='Aligns the image according to the selected option.', max_length=255, verbose_name='Alignment')),
('caption_text', models.TextField(blank=True, help_text='Provide a description, attribution, copyright or other information.', verbose_name='Caption text')),
('attributes', djangocms_attributes_field.fields.AttributesField(blank=True, default=dict, verbose_name='Attributes')),
('link_url', models.URLField(blank=True, help_text='Wraps the image in a link to an external URL.', max_length=2040, verbose_name='External URL')),
('link_target', models.CharField(blank=True, choices=[('_blank', 'Open in new window'), ('_self', 'Open in same window'), ('_parent', 'Delegate to parent'), ('_top', 'Delegate to top')], max_length=255, verbose_name='Link target')),
('link_attributes', djangocms_attributes_field.fields.AttributesField(blank=True, default=dict, verbose_name='Link attributes')),
('use_automatic_scaling', models.BooleanField(default=True, help_text='Uses the placeholder dimenstions to automatically calculate the size.', verbose_name='Automatic scaling')),
('use_no_cropping', models.BooleanField(default=False, help_text='Outputs the raw image without cropping.', verbose_name='Use original image')),
('use_crop', models.BooleanField(default=False, help_text='Crops the image according to the thumbnail settings provided in the template.', verbose_name='Crop image')),
('use_upscale', models.BooleanField(default=False, help_text='Upscales the image to the size of the thumbnail settings in the template.', verbose_name='Upscale image')),
('cmsplugin_ptr', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_image', serialize=False, to='cms.CMSPlugin')),
('cropping', image_cropping.fields.ImageRatioField('picture', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping')),
('link_page', cms.models.fields.PageField(blank=True, help_text='Wraps the image in a link to an internal (page) URL.', null=True, on_delete=django.db.models.deletion.CASCADE, to='cms.Page', verbose_name='Internal URL')),
('picture', project.utils.CroppableFilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.FILER_IMAGE_MODEL, verbose_name='Bild')),
('thumbnail_options', models.ForeignKey(blank=True, help_text='Overrides width, height, and crop; scales up to the provided preset dimensions.', null=True, on_delete=django.db.models.deletion.CASCADE, to='filer.ThumbnailOption', verbose_name='Thumbnail options')),
],
options={
'abstract': False,
},
bases=('cms.cmsplugin',),
),
migrations.AddField(
model_name='imageextension',
name='cropping',
field=image_cropping.fields.ImageRatioField('image', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='partner',
name='cropping',
field=image_cropping.fields.ImageRatioField('logo', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='quote',
name='cropping',
field=image_cropping.fields.ImageRatioField('image', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='referencelistitem',
name='cropping',
field=image_cropping.fields.ImageRatioField('thumbnail', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='slideritem',
name='cropping',
field=image_cropping.fields.ImageRatioField('image', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='timetable',
name='cropping',
field=image_cropping.fields.ImageRatioField('start_image', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='timetableitem',
name='cropping',
field=image_cropping.fields.ImageRatioField('image', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AddField(
model_name='video',
name='cropping',
field=image_cropping.fields.ImageRatioField('thumbnail', '1000x1000', adapt_rotation=False, allow_fullsize=False, free_crop=True, help_text=None, hide_image_field=False, size_warning=False, verbose_name='cropping'),
),
migrations.AlterField(
model_name='imageextension',
name='image',
field=project.utils.CroppableFilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild'),
),
migrations.AlterField(
model_name='partner',
name='logo',
field=project.utils.CroppableFilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild'),
),
migrations.AlterField(
model_name='quote',
name='image',
field=project.utils.CroppableFilerImageField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild'),
),
migrations.AlterField(
model_name='referencelistitem',
name='thumbnail',
field=project.utils.CroppableFilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Vorschaubild'),
),
migrations.AlterField(
model_name='slideritem',
name='image',
field=project.utils.CroppableFilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild'),
),
migrations.AlterField(
model_name='timetable',
name='start_image',
field=project.utils.CroppableFilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Startbild'),
),
migrations.AlterField(
model_name='timetableitem',
name='image',
field=project.utils.CroppableFilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Bild'),
),
migrations.AlterField(
model_name='video',
name='thumbnail',
field=project.utils.CroppableFilerImageField(on_delete=django.db.models.deletion.CASCADE, to=settings.FILER_IMAGE_MODEL, verbose_name='Vorschaubild'),
),
]

View File

@@ -0,0 +1,42 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.13 on 2018-02-14 13:48
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cms', '0018_pagenode'),
('project', '0002_auto_20180214_1315'),
]
operations = [
migrations.CreateModel(
name='TitleList',
fields=[
('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='project_titlelist', serialize=False, to='cms.CMSPlugin')),
],
options={
'verbose_name_plural': 'Title Lists',
'abstract': False,
'verbose_name': 'Title List',
},
bases=('cms.cmsplugin',),
),
migrations.CreateModel(
name='TitleListItem',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=256, null=True, verbose_name='Title')),
('text', models.TextField(verbose_name='Text')),
('ordering', models.IntegerField(default=5, verbose_name='Sortierung')),
('title_list', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='title_list_items', to='project.TitleList', verbose_name='Title List')),
],
options={
'ordering': ['ordering'],
},
),
]

View File

@@ -1 +1,287 @@
# -*- coding: utf-8 -*-
from cms.models.pluginmodel import CMSPlugin
from django.db import models
from itertools import chain
from djangocms_picture.models import AbstractPicture
from djangocms_text_ckeditor.fields import HTMLField
from filer.fields.folder import FilerFolderField
from cms.extensions import PageExtension
from cms.extensions.extension_pool import extension_pool
from fontawesome.fields import IconField
from parler.models import TranslatableModel, TranslatedFields
from project.utils import CroppableFilerImageField
from image_cropping import ImageRatioField
from project.utils import AbstractClassWithoutFieldsNamed as without
class ImageExtension(PageExtension):
image = CroppableFilerImageField(verbose_name='Bild', null=True, blank=True)
cropping = ImageRatioField('image', '1000x1000', free_crop=True)
extension_pool.register(ImageExtension)
class Section(CMSPlugin):
title = HTMLField(verbose_name='Titel', configuration='CKEDITOR_SETTINGS_SECTION_TITLE')
class Meta(CMSPlugin.Meta):
verbose_name = 'Section'
verbose_name_plural = 'Sections'
def __str__(self):
return self.title
class SectionText(CMSPlugin):
columns = models.BooleanField(verbose_name='Spalten', default=False)
class Meta(CMSPlugin.Meta):
verbose_name = 'Section Text'
verbose_name_plural = 'Section Texts'
class Video(CMSPlugin):
vimeo_id = models.IntegerField(verbose_name='Vimeo ID', help_text='e.g. https://vimeo.com/<b>131766159</b>')
thumbnail = CroppableFilerImageField(verbose_name='Vorschaubild')
cropping = ImageRatioField('thumbnail', '1000x1000', free_crop=True)
class Meta(CMSPlugin.Meta):
verbose_name = 'Video'
verbose_name_plural = 'Videos'
def __str__(self):
return str(self.vimeo_id)
class SliderItemQualification(TranslatableModel):
translations = TranslatedFields(
name=models.CharField('name', max_length=256)
)
ordering = models.IntegerField(verbose_name='Sortierung', default=5)
class Meta:
ordering = ['ordering']
def __str__(self):
return self.name
class SliderItem(CMSPlugin):
image = CroppableFilerImageField(verbose_name='Bild')
cropping = ImageRatioField('image', '1000x1000', free_crop=True)
title = HTMLField(verbose_name='Titel', configuration='CKEDITOR_SETTINGS_SLIDER_TITLE')
subline = HTMLField(verbose_name='Untertitel', configuration='CKEDITOR_SETTINGS_SLIDER_TEXT', blank=True, null=True)
text = HTMLField(verbose_name='Text', configuration='CKEDITOR_SETTINGS_SLIDER_TEXT', blank=True, null=True)
qualifications = models.ManyToManyField(SliderItemQualification, verbose_name='Qualifikationen', blank=True,
null=True)
email = models.EmailField(verbose_name='E-Mail', blank=True, null=True)
class Meta(CMSPlugin.Meta):
verbose_name = 'Slider Item'
verbose_name_plural = 'Slider Items'
def __str__(self):
return self.title
def copy_relations(self, oldinstance):
self.qualifications = oldinstance.qualifications.all()
class TextSliderItem(CMSPlugin):
text = HTMLField(verbose_name='Text', configuration='CKEDITOR_SETTINGS_TEXT_SLIDER_TEXT')
class Meta(CMSPlugin.Meta):
verbose_name = 'Text Slider Item'
verbose_name_plural = 'Text Slider Items'
def __str__(self):
return self.text
class Quote(CMSPlugin):
content = HTMLField(verbose_name='Inhalt', configuration='CKEDITOR_SETTINGS_QUOTE_CONTENT')
source = HTMLField(verbose_name='Quelle', configuration='CKEDITOR_SETTINGS_QUOTE_SOURCE')
image = CroppableFilerImageField(verbose_name='Bild', null=True, blank=True)
cropping = ImageRatioField('image', '1000x1000', free_crop=True)
class Meta(CMSPlugin.Meta):
verbose_name = 'Quote'
verbose_name_plural = 'Quotes'
def __str__(self):
return self.content
class DownloadSection(CMSPlugin):
class Meta(CMSPlugin.Meta):
verbose_name = 'Download Section'
verbose_name_plural = 'Download Sections'
def copy_relations(self, oldinstance):
self.folders.all().delete()
for folder in oldinstance.folders.all():
folder.pk = None
folder.download_section = self
folder.save()
@property
def items(self):
items = []
for folder in self.folders.all():
items = chain(items, folder.folder.files)
return list(items)
class DownloadSectionFolder(models.Model):
download_section = models.ForeignKey(DownloadSection, verbose_name='Download Section', related_name='folders')
folder = FilerFolderField(verbose_name='Ordner')
ordering = models.IntegerField(verbose_name='Sortierung', default=5)
class Meta:
ordering = ['ordering']
class HighlightList(CMSPlugin):
full_width = models.BooleanField(verbose_name='Volle Breite', default=False)
class Meta(CMSPlugin.Meta):
verbose_name = 'Highlight List'
verbose_name_plural = 'Highlight Lists'
ANIMATED_ICON_CHOICES = (
('strength', 'Stärken'),
('learning', 'Lernen'),
('creativity', 'Kreativität'),
('curiosity', 'Neugierde'),
('education', 'Bildung'),
('happiness', 'Glücklichkeit'),
)
class HighlightListItem(CMSPlugin):
icon = IconField(verbose_name='Icon', null=True, blank=True)
animated_icon = models.CharField(verbose_name='Animiertes Icon', max_length=256, choices=ANIMATED_ICON_CHOICES,
null=True, blank=True)
title = HTMLField(verbose_name='Titel', configuration='CKEDITOR_SETTINGS_HIGHLIGHT_LIST_ITEM_TITLE')
text = HTMLField(verbose_name='Text', configuration='CKEDITOR_SETTINGS_HIGHLIGHT_LIST_ITEM_TEXT')
class Meta(CMSPlugin.Meta):
verbose_name = 'Highlight List Item'
verbose_name_plural = 'Highlight List Items'
def __str__(self):
return self.title
class ReferenceListItem(CMSPlugin):
vimeo_id = models.IntegerField(verbose_name='Vimeo ID', help_text='e.g. https://vimeo.com/<b>131766159</b>')
thumbnail = CroppableFilerImageField(verbose_name='Vorschaubild')
cropping = ImageRatioField('thumbnail', '1000x1000', free_crop=True)
class Meta(CMSPlugin.Meta):
verbose_name = 'Reference List Item'
verbose_name_plural = 'Reference List Items'
def __str__(self):
return str(self.vimeo_id)
class SocialMediaList(CMSPlugin):
class Meta(CMSPlugin.Meta):
verbose_name = 'Social Media List'
verbose_name_plural = 'Social Media Lists'
def copy_relations(self, oldinstance):
self.social_media_list_items.all().delete()
for social_media_list_item in oldinstance.social_media_list_items.all():
social_media_list_item.pk = None
social_media_list_item.social_media_list = self
social_media_list_item.save()
class SocialMediaListItem(models.Model):
social_media_list = models.ForeignKey(SocialMediaList, verbose_name='Social Media List',
related_name='social_media_list_items')
icon = IconField(verbose_name='Icon')
url = models.URLField(verbose_name='URL')
ordering = models.IntegerField(verbose_name='Sortierung', default=5)
class Meta:
ordering = ['ordering']
class Timetable(CMSPlugin):
start_image = CroppableFilerImageField(verbose_name='Startbild')
cropping = ImageRatioField('start_image', '1000x1000', free_crop=True)
introduction = HTMLField(verbose_name='Einleitung', configuration='CKEDITOR_SETTINGS_INPUT')
class Meta(CMSPlugin.Meta):
verbose_name = 'Timetable'
verbose_name_plural = 'Timetables'
def __str__(self):
return self.introduction
class TimetableItem(CMSPlugin):
time = models.TimeField(verbose_name='Zeit')
image = CroppableFilerImageField(verbose_name='Bild')
cropping = ImageRatioField('image', '1000x1000', free_crop=True)
title = HTMLField(verbose_name='Titel', configuration='CKEDITOR_SETTINGS_TIMETABLE_ITEM_TITLE')
text = HTMLField(verbose_name='Text', configuration='CKEDITOR_SETTINGS_TIMETABLE_ITEM_TEXT')
class Meta(CMSPlugin.Meta):
verbose_name = 'Timetable Item'
verbose_name_plural = 'Timetables Items'
def __str__(self):
return '%s | %s' % (self.time, self.title)
class Partner(CMSPlugin):
logo = CroppableFilerImageField(verbose_name='Bild')
cropping = ImageRatioField('logo', '1000x1000', free_crop=True)
name = HTMLField(verbose_name='Titel', configuration='CKEDITOR_SETTINGS_SLIDER_TITLE')
text = HTMLField(verbose_name='Text', configuration='CKEDITOR_SETTINGS_SLIDER_TEXT', blank=True, null=True)
url = models.URLField(verbose_name='URL', blank=True, null=True)
class Meta(CMSPlugin.Meta):
verbose_name = 'Slider Item'
verbose_name_plural = 'Slider Items'
def __str__(self):
return self.name
class Image(without(AbstractPicture, 'picture')):
picture = CroppableFilerImageField(verbose_name='Bild', blank=True, null=True, on_delete=models.SET_NULL,
related_name='+')
cropping = ImageRatioField('picture', '1000x1000', free_crop=True)
class TitleList(CMSPlugin):
class Meta(CMSPlugin.Meta):
verbose_name = 'Title List'
verbose_name_plural = 'Title Lists'
def copy_relations(self, oldinstance):
self.title_list_items.all().delete()
for title_list_item in oldinstance.title_list_items.all():
title_list_item.pk = None
title_list_item.title_list = self
title_list_item.save()
class TitleListItem(models.Model):
title_list = models.ForeignKey(TitleList, verbose_name='Title List', related_name='title_list_items')
title = models.CharField(verbose_name='Title', max_length=256, null=True, blank=True)
text = models.TextField(verbose_name='Text')
ordering = models.IntegerField(verbose_name='Sortierung', default=5)
class Meta:
ordering = ['ordering']

17
src/project/search.py Normal file
View File

@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from aldryn_search.base import AldrynIndexBase
from haystack import indexes
from haystack.utils.highlighting import Highlighter as _Highlighter
class SearchIndex(AldrynIndexBase):
text = indexes.NgramField(document=True, use_template=False)
class Highlighter(_Highlighter):
def render_html(self, highlight_locations=None, start_offset=None, end_offset=None):
return super(Highlighter, self).render_html(
highlight_locations=highlight_locations,
start_offset=max(0, start_offset - 20),
end_offset=end_offset + 20
)

21
src/project/templates/404.html Normal file → Executable file
View File

@@ -1,6 +1,19 @@
{% extends 'main.html' %}
{% load i18n %}
{% extends 'project/content.html' %}
{% load i18n cms_tags %}
{% block content %}
<h1>Error 404</h1>
{% block title %}{% trans 'Seite nicht gefunden' %}{% endblock %}
{% block content_intro %}
{% trans 'Seite nicht gefunden' as error %}
{% include 'project/includes/content_intro.html' with content_title=error %}
{% endblock %}
{% block content_main %}
<p class="section__text reveal_self reveal reveal_animation">
{% trans 'Die Seite wurde leider nicht gefunden.' %}
<br><br>
<a href="/{{ LANGUAGE_CODE }}/">{% trans 'Zurück zur Startseite' %}</a><br>
<a href="{% url 'search' %}">{% trans 'Zur Suche' %}</a><br>
<a href="{% page_url 'contact' %}">{% trans 'Nehmen Sie mit uns Kontakt auf' %}</a>
</p>
{% endblock %}

22
src/project/templates/500.html Normal file → Executable file
View File

@@ -1,6 +1,20 @@
{% extends 'main.html' %}
{% load i18n %}
{% extends 'project/content.html' %}
{% load i18n cms_tags %}
{% block content %}
<h1>Error 500</h1>
{% block title %}{% trans 'Ein Fehler ist aufgetreten' %}{% endblock %}
{% block content_intro %}
{% trans 'Ein Fehler ist aufgetreten' as error %}
{% include 'project/includes/content_intro.html' with content_title=error %}
{% endblock %}
{% block content_main %}
<p class="section__text reveal_self reveal reveal_animation">
{% trans 'Beim Aufrufen der Seite ist ein Fehler aufgetreten.' %}
<br><br>
<a href="{{ request.get_current_url }}">{% trans 'Seite neu laden' %}</a><br>
<a href="/{{ LANGUAGE_CODE }}/">{% trans 'Zurück zur Startseite' %}</a><br>
<a href="{% url 'search' %}">{% trans 'Zur Suche' %}</a><br>
<a href="{% page_url 'contact' %}">{% trans 'Nehmen Sie mit uns Kontakt auf' %}</a>
</p>
{% endblock %}

View File

@@ -1,33 +1,82 @@
{% load static i18n cms_tags sekizai_tags %}<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>{% block title %}{% page_attribute page_title %}{% endblock %}</title>
<meta name="description" content="{% block description %}{% page_attribute 'meta_description' %}{% endblock %}">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% load static i18n cms_tags sekizai_tags fontawesome %}<!DOCTYPE html>
<html class="r" lang="{{ LANGUAGE_CODE }}">
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>{% block title %}{% page_attribute page_title %}{% endblock %} | Tagesschule Elementa Zug</title>
<meta name="description" content="{% block description %}{% page_attribute 'meta_description' %}{% endblock %}">
<meta name="viewport" content="width=device-width, initial-scale=1">
{% block extra_meta %}
{% endblock %}
{% block extra_meta %}
{% endblock %}
<link rel="stylesheet" href="{% static 'css/main.css' %}">
<link rel="shortcut icon" href="{% static 'img/favicon.ico' %}" type="image/x-icon">
<link rel="icon" href="{% static 'img/favicon.ico' %}" type="image/x-icon">
{% render_block "css" %}
{{ ALDRYN_SNAKE.render_head }}
</head>
<body>
{% cms_toolbar %}
<link rel="icon" type="image/png" sizes="16x16" href="{% static 'img/favicon-16x16.png' %}">
<link rel="icon" type="image/png" sizes="32x32" href="{% static 'img/favicon-32x32.png' %}">
<link rel="icon" type="image/png" sizes="96x96" href="{% static 'img/favicon-96x96.png' %}">
<link rel="icon" type="image/png" sizes="192x192" href="{% static 'img/favicon-192x192.png' %}">
{% block content %}
{% placeholder 'content' %}
{% endblock %}
<meta name="theme-color" content="#98C53A"/>
<script type="text/javascript" src="{% static 'js/lib.js' %}"></script>
<script type="text/javascript" src="{% static 'js/main.js' %}"></script>
<link rel="stylesheet" href="{% static 'css/main.css' %}">
{% block extra_body %}{% endblock %}
{% fontawesome_stylesheet %}
{% render_block "css" %}
{{ ALDRYN_SNAKE.render_head }}
</head>
<body class="{% block body_class %}{% endblock %}">
{% cms_toolbar %}
{% render_block "js" %}
{{ ALDRYN_SNAKE.render_tail }}
</body>
<a href="/{{ LANGUAGE_CODE }}/" class="header__logo reveal reveal_animation">
<img src="{% static 'img/tagesschule-elementa.svg' %}" width="100" height="100">
</a>
<a href="#" class="navigation__close">
<span class="header__button header__button--close">
<span class="header__button__icon">
{% include 'project/assets/close.svg' %}
</span>
{% trans 'Schliessen' %}
</span>
</a>
<div id="navigation">
{% include 'project/includes/navigation.html' %}
</div>
<div id="search">
{% include 'project/includes/search_form.html' %}
</div>
<div id="canvas">
<div class="header reveal reveal_animation data_delay_2">
<span class="header__slogan">{% trans 'Stärken stärken. Lernen lernen.' %}</span>
<a href="#" class="header__button header__button--search">
{% trans 'Suche' %}
<span class="header__button__icon">
{% include 'project/assets/search.svg' %}
</span>
</a>
<a href="#" class="header__button header__button--navigation">
{% trans 'Menü' %}
<span class="header__button__icon">
{% include 'project/assets/menu.svg' %}
</span>
</a>
</div>
{% block content %}
{% placeholder 'content' %}
{% endblock %}
</div>
<script type="text/javascript" src="{% static 'js/lib.js' %}"></script>
<script type="text/javascript" src="{% static 'js/main.js' %}"></script>
{% block extra_body %}{% endblock %}
{% render_block "js" %}
{{ ALDRYN_SNAKE.render_tail }}
</body>
</html>

View File

@@ -0,0 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M31.4366634,9.44202305 C32.0209679,8.85475847 32.9707124,8.85235889 33.557977,9.43666344 C34.1452415,10.020968 34.1476411,10.9707124 33.5633366,11.557977 L18.6389421,26.557977 C18.0546323,27.1452468 17.1048775,27.1476404 16.517615,26.5633231 L1.44200954,11.5633232 C0.85475238,10.9790112 0.852364866,10.0292667 1.43667688,9.44200954 C2.02098889,8.85475238 2.97073336,8.85236487 3.55799051,9.43667688 L17.5702593,23.3786729 L31.4366634,9.44202305 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 626 B

View File

@@ -0,0 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M26.557977,31.4366634 C27.1452415,32.0209679 27.1476411,32.9707124 26.5633366,33.557977 C25.979032,34.1452415 25.0292876,34.1476411 24.442023,33.5633366 L9.44202305,18.6389421 C8.85475319,18.0546323 8.85235962,17.1048775 9.43667688,16.517615 L24.4366768,1.44200954 C25.0209888,0.85475238 25.9707333,0.852364866 26.5579905,1.43667688 C27.1452476,2.02098889 27.1476351,2.97073336 26.5633231,3.55799051 L12.6213271,17.5702593 L26.557977,31.4366634 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 625 B

View File

@@ -0,0 +1,6 @@
<svg width="50px" height="35px" viewBox="0 0 50 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M32.442023,3.56333662 C31.8547585,2.97903206 31.8523589,2.02928763 32.4366634,1.44202305 C33.020968,0.854758464 33.9707124,0.852358886 34.557977,1.43666344 L49.557977,16.3610579 C50.1452468,16.9453677 50.1476404,17.8951225 49.5633231,18.482385 L34.5633232,33.5579905 C33.9790112,34.1452476 33.0292667,34.1476351 32.4420095,33.5633231 C31.8547524,32.9790111 31.8523649,32.0292666 32.4366769,31.4420095 L46.3786729,17.4297407 L32.442023,3.56333662 Z"
id="arrow" fill-rule="nonzero"></path>
<rect id="line" x="0" y="16" width="48" height="3" rx="1.5"></rect>
</svg>

After

Width:  |  Height:  |  Size: 739 B

View File

@@ -0,0 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M9.44202305,3.56333662 C8.85475847,2.97903206 8.85235889,2.02928763 9.43666344,1.44202305 C10.020968,0.854758465 10.9707124,0.852358887 11.557977,1.43666344 L26.557977,16.3610579 C27.1452468,16.9453677 27.1476404,17.8951225 26.5633231,18.482385 L11.5633232,33.5579905 C10.9790112,34.1452476 10.0292667,34.1476351 9.44200954,33.5633231 C8.85475238,32.9790111 8.85236487,32.0292666 9.43667688,31.4420095 L23.3786729,17.4297407 L9.44202305,3.56333662 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 628 B

View File

@@ -0,0 +1,127 @@
<svg class="timetable__clock__design" width="476px" height="476px" viewBox="0 0 476 476" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M241.017,24.508 C241.017,26.446 239.447,28.017 237.509,28.017 C235.571,28.017 234,26.446 234,24.508 C234,22.571 235.571,21 237.509,21 C239.447,21 241.017,22.571 241.017,24.508"
class="dot"></path>
<path d="M242.018,451.509 C242.018,453.447 240.447,455.018 238.509,455.018 C236.571,455.018 235,453.447 235,451.509 C235,449.572 236.571,448 238.509,448 C240.447,448 242.018,449.572 242.018,451.509"
class="dot"></path>
<path d="M134.547736,51.7547356 C135.516736,53.4327356 134.941736,55.5787356 133.263736,56.5477356 C131.585736,57.5167356 129.439736,56.9417356 128.470736,55.2637356 C127.501736,53.5857356 128.076736,51.4397356 129.754736,50.4707356 C131.432736,49.5017356 133.578736,50.0767356 134.547736,51.7547356"
class="dot"></path>
<path d="M348.547736,420.754954 C349.517736,422.432954 348.942736,424.578954 347.263736,425.547954 C345.585736,426.516954 343.439736,425.941954 342.470736,424.263954 C341.501736,422.584954 342.076736,420.439954 343.754736,419.470954 C345.433736,418.501954 347.578736,419.075954 348.547736,420.754954"
class="dot"></path>
<path d="M55.2637356,128.470736 C56.9417356,129.439736 57.5167356,131.585736 56.5477356,133.263736 C55.5787356,134.941736 53.4327356,135.516736 51.7547356,134.547736 C50.0767356,133.578736 49.5017356,131.432736 50.4707356,129.754736 C51.4397356,128.076736 53.5857356,127.501736 55.2637356,128.470736"
class="dot"></path>
<path d="M425.264482,341.470954 C426.942482,342.439954 427.517482,344.584954 426.548482,346.263954 C425.579482,347.941954 423.433482,348.516954 421.755482,347.547954 C420.077482,346.578954 419.501482,344.432954 420.470482,342.754954 C421.440482,341.075954 423.585482,340.501954 425.264482,341.470954"
class="dot"></path>
<path d="M24.508,235 C26.446,235 28.017,236.571 28.017,238.509 C28.017,240.447 26.446,242.018 24.508,242.018 C22.571,242.018 21,240.447 21,238.509 C21,236.571 22.571,235 24.508,235"
class="dot"></path>
<path d="M451.509,234 C453.447,234 455.018,235.571 455.018,237.509 C455.018,239.447 453.447,241.017 451.509,241.017 C449.572,241.017 448,239.447 448,237.509 C448,235.571 449.572,234 451.509,234"
class="dot"></path>
<path d="M51.7547356,341.470736 C53.4327356,340.501736 55.5787356,341.076736 56.5477356,342.754736 C57.5167356,344.433736 56.9417356,346.578736 55.2637356,347.547736 C53.5857356,348.517736 51.4397356,347.942736 50.4707356,346.263736 C49.5017356,344.585736 50.0767356,342.439736 51.7547356,341.470736"
class="dot"></path>
<path d="M420.754954,127.470736 C422.432954,126.501736 424.578954,127.076736 425.547954,128.754736 C426.516954,130.432736 425.941954,132.578736 424.263954,133.547736 C422.584954,134.516736 420.439954,133.941736 419.470954,132.263736 C418.501954,130.585736 419.075954,128.439736 420.754954,127.470736"
class="dot"></path>
<path d="M128.470736,420.7557 C129.439736,419.0767 131.585736,418.5017 133.263736,419.4707 C134.941736,420.4407 135.516736,422.5857 134.547736,424.2647 C133.578736,425.9427 131.432736,426.5177 129.754736,425.5487 C128.076736,424.5797 127.501736,422.4337 128.470736,420.7557"
class="dot"></path>
<path d="M341.470954,50.7547356 C342.439954,49.0767356 344.584954,48.5017356 346.263954,49.4707356 C347.941954,50.4397356 348.516954,52.5857356 347.547954,54.2637356 C346.578954,55.9417356 344.432954,56.5167356 342.754954,55.5477356 C341.075954,54.5787356 340.501954,52.4327356 341.470954,50.7547356"
class="dot"></path>
<polygon class="line" fill-rule="nonzero"
points="261.718053 453.939 259.729 454.147967 259 447.208967 260.989053 447"></polygon>
<polygon class="line" fill-rule="nonzero"
points="216.719058 28.95 214.73 29.1589226 214 22.2089226 215.989058 22"></polygon>
<polygon class="line" fill-rule="nonzero"
points="284.406262 449.819 282.45 450.234982 281 443.415982 282.956262 443"></polygon>
<polygon class="line" fill-rule="nonzero"
points="195.40615 31.81 193.45 32.2265076 192 25.4165076 193.95615 25"></polygon>
<polygon class="line" fill-rule="nonzero"
points="306.050729 443.6 304.149 444.219215 302 437.619215 303.901729 437"></polygon>
<polygon class="line" fill-rule="nonzero"
points="174.05192 37.61 172.15 38.2286276 170 31.6186276 171.90192 31"></polygon>
<polygon class="line" fill-rule="nonzero"
points="326.656839 435.351 324.83 436.165038 322 429.814038 323.826839 429"></polygon>
<polygon class="line" fill-rule="nonzero"
points="153.656792 45.35 151.83 46.164145 149 39.814145 150.826792 39"></polygon>
<polygon class="line" fill-rule="nonzero"
points="365.727374 412.659 364.109 413.834102 360 408.175102 361.618374 407"></polygon>
<polygon class="line" fill-rule="nonzero"
points="115.71871 67.65 114.1 68.8246392 110 63.1746392 111.61871 62"></polygon>
<polygon class="line" fill-rule="nonzero"
points="384.175167 398.2 382.69 399.539507 378 394.339507 379.485167 393"></polygon>
<polygon class="line" fill-rule="nonzero"
points="98.1665883 81.2 96.68 82.5379295 92 77.3379295 93.4865883 76"></polygon>
<polygon class="line" fill-rule="nonzero"
points="399.539507 382.69 398.2 384.175167 393 379.485167 394.339507 378"></polygon>
<polygon class="line" fill-rule="nonzero"
points="82.5379295 96.68 81.2 98.1665883 76 93.4865883 77.3379295 92"></polygon>
<polygon class="line" fill-rule="nonzero"
points="413.834102 365.109 412.659 366.727374 407 362.618374 408.175102 361"></polygon>
<polygon class="line" fill-rule="nonzero"
points="68.8265136 114.11 67.65 115.727348 62 111.617348 63.1765136 110"></polygon>
<polygon class="line" fill-rule="nonzero"
points="436.165038 324.83 435.351 326.656839 429 323.826839 429.814038 322"></polygon>
<polygon class="line" fill-rule="nonzero"
points="46.164145 151.83 45.35 153.656792 39 150.826792 39.814145 149"></polygon>
<polygon class="line" fill-rule="nonzero"
points="444.219215 304.149 443.6 306.050729 437 303.901729 437.619215 302"></polygon>
<polygon class="line" fill-rule="nonzero"
points="38.2286276 172.15 37.61 174.05192 31 171.90192 31.6186276 170"></polygon>
<polygon class="line" fill-rule="nonzero"
points="450.234982 282.45 449.819 284.406262 443 282.956262 443.415982 281"></polygon>
<polygon class="line" fill-rule="nonzero"
points="32.2265076 193.45 31.81 195.40615 25 193.95615 25.4165076 192"></polygon>
<polygon class="line" fill-rule="nonzero"
points="454.147967 259.729 453.939 261.718053 447 260.989053 447.208967 259"></polygon>
<polygon class="line" fill-rule="nonzero"
points="29.1589226 214.73 28.95 216.719058 22 215.989058 22.2089226 214"></polygon>
<polygon class="line" fill-rule="nonzero"
points="453.939 214 454.14825 215.989023 447.20925 216.719023 447 214.73"></polygon>
<polygon class="line" fill-rule="nonzero"
points="28.94 259 29.1489369 260.989056 22.2089369 261.718056 22 259.729"></polygon>
<polygon class="line" fill-rule="nonzero"
points="449.819 192 450.234982 193.956262 443.415982 195.406262 443 193.45"></polygon>
<polygon class="line" fill-rule="nonzero"
points="31.82 281 32.2359233 282.956274 25.4159233 284.406274 25 282.45"></polygon>
<polygon class="line" fill-rule="nonzero"
points="443.6 170 444.219475 171.901644 437.619475 174.051644 437 172.15"></polygon>
<polygon class="line" fill-rule="nonzero"
points="37.6 302 38.2192145 303.901729 31.6192145 306.050729 31 304.149"></polygon>
<polygon class="line" fill-rule="nonzero"
points="435.351 149 436.165038 150.826839 429.814038 153.656839 429 151.83"></polygon>
<polygon class="line" fill-rule="nonzero"
points="45.35 322 46.164145 323.826792 39.814145 326.656792 39 324.83"></polygon>
<polygon class="line" fill-rule="nonzero"
points="412.659 110 413.834289 111.618239 408.175289 115.728239 407 114.11"></polygon>
<polygon class="line" fill-rule="nonzero"
points="67.66 361 68.8349658 362.618473 63.1749658 366.727473 62 365.109"></polygon>
<polygon class="line" fill-rule="nonzero"
points="398.2 92 399.539507 93.4851673 394.339507 98.1751673 393 96.69"></polygon>
<polygon class="line" fill-rule="nonzero"
points="81.2 378 82.5395067 379.485167 77.3395067 384.175167 76 382.69"></polygon>
<polygon class="line" fill-rule="nonzero"
points="382.69 76 384.175167 77.3395067 379.485167 82.5395067 378 81.2"></polygon>
<polygon class="line" fill-rule="nonzero"
points="96.69 393 98.1751673 394.339507 93.4851673 399.539507 92 398.2"></polygon>
<polygon class="line" fill-rule="nonzero"
points="364.109 62 365.727473 63.1749658 361.618473 68.8349658 360 67.66"></polygon>
<polygon class="line" fill-rule="nonzero"
points="114.11 407 115.728239 408.175289 111.618239 413.834289 110 412.659"></polygon>
<polygon class="line" fill-rule="nonzero"
points="324.83 39 326.656792 39.814145 323.826792 46.164145 322 45.35"></polygon>
<polygon class="line" fill-rule="nonzero"
points="151.83 429 153.656839 429.814038 150.826839 436.165038 149 435.351"></polygon>
<polygon class="line" fill-rule="nonzero"
points="304.149 31 306.050729 31.6192145 303.901729 38.2192145 302 37.6"></polygon>
<polygon class="line" fill-rule="nonzero"
points="172.15 437 174.051644 437.619475 171.901644 444.219475 170 443.6"></polygon>
<polygon class="line" fill-rule="nonzero"
points="282.45 25 284.406274 25.4159233 282.956274 32.2359233 281 31.82"></polygon>
<polygon class="line" fill-rule="nonzero"
points="193.45 443 195.406262 443.415982 193.956262 450.234982 192 449.819"></polygon>
<polygon class="line" fill-rule="nonzero"
points="259.729 22 261.718056 22.2089369 260.989056 29.1489369 259 28.94"></polygon>
<polygon class="line" fill-rule="nonzero"
points="214.73 447 216.719023 447.20925 215.989023 454.14825 214 453.939"></polygon>
<path d="M470,238 C470,109.866854 366.133146,6 238,6 C236.274439,6 234.899325,6.01375114 233.556133,6.0494748 C107.305506,8.4121637 6,111.520129 6,238 C6,366.133146 109.866854,470 238,470 C366.133146,470 470,366.133146 470,238 Z M476,238 C476,369.446854 369.446854,476 238,476 C106.553146,476 0,369.446854 0,238 C0,108.248743 103.9253,2.47437121 233.420028,0.0510660981 C234.800675,0.014248859 236.225561,0 238,0 C369.446854,0 476,106.553146 476,238 Z"
class="border" fill-rule="nonzero"></path>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -0,0 +1,7 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M8.80761184,6.1862915 L29.3137085,26.6923882 C29.8994949,27.2781746 29.8994949,28.2279221 29.3137085,28.8137085 C28.7279221,29.3994949 27.7781746,29.3994949 27.1923882,28.8137085 L6.6862915,8.30761184 C6.10050506,7.72182541 6.10050506,6.77207794 6.6862915,6.1862915 C7.27207794,5.60050506 8.22182541,5.60050506 8.80761184,6.1862915 Z"
class="line-left"></path>
<path d="M6.6862915,26.6923882 L27.1923882,6.1862915 C27.7781746,5.60050506 28.7279221,5.60050506 29.3137085,6.1862915 C29.8994949,6.77207794 29.8994949,7.72182541 29.3137085,8.30761184 L8.80761184,28.8137085 C8.22182541,29.3994949 7.27207794,29.3994949 6.6862915,28.8137085 C6.10050506,28.2279221 6.10050506,27.2781746 6.6862915,26.6923882 Z"
class="line-right"></path>
</svg>

After

Width:  |  Height:  |  Size: 925 B

View File

@@ -0,0 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M15.9996412,16.8783208 L15.9996412,7.5 C15.9996412,6.67157288 16.671214,6 17.4996412,6 C18.3280683,6 18.9996412,6.67157288 18.9996412,7.5 L18.9996412,16.8790385 L21.4393398,14.4393398 C22.0251263,13.8535534 22.9748737,13.8535534 23.5606602,14.4393398 C24.1464466,15.0251263 24.1464466,15.9748737 23.5606602,16.5606602 L18.5606602,21.5606602 C17.9748737,22.1464466 17.0251263,22.1464466 16.4393398,21.5606602 L11.4393398,16.5606602 C10.8535534,15.9748737 10.8535534,15.0251263 11.4393398,14.4393398 C12.0251263,13.8535534 12.9748737,13.8535534 13.5606602,14.4393398 L15.9996412,16.8783208 Z M10.5,28 C9.67157288,28 9,27.3284271 9,26.5 C9,25.6715729 9.67157288,25 10.5,25 L24.5,25 C25.3284271,25 26,25.6715729 26,26.5 C26,27.3284271 25.3284271,28 24.5,28 L10.5,28 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 942 B

View File

@@ -0,0 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M6.12132034,9 L17.5,20.3786797 L28.8786797,9 L6.12132034,9 Z M31,11.1213203 L18.5606602,23.5606602 C17.9748737,24.1464466 17.0251263,24.1464466 16.4393398,23.5606602 L4,11.1213203 L4,26 L31,26 L31,11.1213203 Z M2.5,6 L32.5,6 C33.3284271,6 34,6.67157288 34,7.5 L34,27.5 C34,28.3284271 33.3284271,29 32.5,29 L2.5,29 C1.67157288,29 1,28.3284271 1,27.5 L1,7.5 C1,6.67157288 1.67157288,6 2.5,6 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 569 B

View File

@@ -0,0 +1,6 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<rect class="line-top" x="4" y="6" width="28" height="3" rx="1.5"></rect>
<rect class="line-middle" x="4" y="16" width="28" height="3" rx="1.5"></rect>
<rect class="line-bottom" x="4" y="26" width="28" height="3" rx="1.5"></rect>
</svg>

After

Width:  |  Height:  |  Size: 398 B

View File

@@ -0,0 +1,4 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M9,30.6571365 L31.5466546,17.5217649 L9,4.38624411 L9,30.6571365 Z M8.06559183,3.82372129 C8.11385613,3.86213396 8.16060259,3.89389381 8.20583948,3.91964378 L8.06559183,3.82372129 Z M8.4983486,31.0038586 C8.46934226,31.0038586 8.4665067,31.0040799 8.49521517,31.0097894 C8.51358323,31.0044274 8.51354824,31.0038586 8.4983486,31.0038586 Z M9.82181934,1.39303795 L33.7559217,15.3368759 L33.9349236,15.4593044 C34.5868249,15.9781407 35,16.6468541 35,17.5216878 C35,18.4257399 34.5132392,19.2516282 33.7559217,19.7064998 L9.82726706,33.6443539 C9.66667195,33.7505899 9.49940323,33.8345151 9.31683935,33.8949975 C9.0236245,33.992138 8.86416284,34.0038586 8.4983486,34.0038586 C8.24745197,34.0038586 8.14898904,33.9995939 7.95603549,33.9612019 C7.73137005,33.9165001 7.55145108,33.8463643 7.32902093,33.7352886 L7.18821849,33.6649755 L7.06507641,33.566969 C6.41317513,33.0481327 6,32.3794194 6,31.5045856 L6,3.53879008 C6,2.63473804 6.4867608,1.80884967 7.22662515,1.3643049 C7.99391167,0.903283625 9.03327302,0.844492269 9.82181934,1.39303795 Z"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,7 @@
<svg width="35px" height="35px" viewBox="0 0 35 35" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M15,22 C18.8659932,22 22,18.8659932 22,15 C22,11.1340068 18.8659932,8 15,8 C11.1340068,8 8,11.1340068 8,15 C8,18.8659932 11.1340068,22 15,22 Z M15,25 C9.4771525,25 5,20.5228475 5,15 C5,9.4771525 9.4771525,5 15,5 C20.5228475,5 25,9.4771525 25,15 C25,20.5228475 20.5228475,25 15,25 Z"
class="circle" fill-rule="nonzero"></path>
<rect class="line" transform="translate(25.303301, 25.303301) rotate(45.000000) translate(-25.303301, -25.303301) "
x="19.3033009" y="23.8033009" width="12" height="3" rx="1.5"></rect>
</svg>

After

Width:  |  Height:  |  Size: 704 B

View File

@@ -0,0 +1,24 @@
{% extends 'main.html' %}
{% load i18n cms_tags thumbnail %}
{% block content %}
<div class="contact reveal_container">
<div class="contact__frame">
<div class="contact__map reveal reveal_animation data_delay_1" id="map"></div>
<div class="contact__content">
<div class="contact__content__main reveal reveal_animation data_delay_3">
<h1>{% page_attribute 'page_title' %}</h1>
{% placeholder 'contact' %}
{% static_placeholder 'social_media' %}
</div>
<div class="contact__content__backdrop reveal reveal_animation data_delay_5"></div>
</div>
</div>
</div>
{% endblock %}
{% block extra_body %}
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBUwU4LCIx7cvecUmrM-fkUzN-joMYs65w&libraries=places&callback=init_map">
</script>
{% endblock %}

View File

@@ -1,5 +1,31 @@
{% extends 'main.html' %}
{% load i18n %}
{% load i18n cms_tags %}
{% block content %}
<div class="content__frame">
{% block content_intro %}
{% include 'project/includes/content_intro.html' %}
{% endblock %}
<div class="content__container">
<div class="content__navigation reveal_self reveal reveal_animation data_delay_3">
<div class="content__navigation__frame">
<div class="content__navigation__main">
<div class="content__navigation__progress">
<span class="content__navigation__progress__fill"></span>
</div>
<ul class="content__navigation__list"></ul>
</div>
</div>
</div>
<div class="content__main">
<div class="content__wrap">
<div class="content">
{% block content_main %}
{% placeholder 'content' %}
{% endblock %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,16 @@
{% load i18n cms_tags thumbnail %}
<div class="content__intro reveal_container reveal_self reveal reveal_animation{% if request.current_page.imageextension.image %} image{% endif %}">
<h1 class="reveal reveal_animation">
{% if content_title %}
{{ content_title }}
{% else %}
{% page_attribute page_title %}
{% endif %}
</h1>
{% if request.current_page.imageextension.image %}
{% thumbnail request.current_page.imageextension.image 1600x800 box=request.current_page.imageextension.cropping crop detail as thumb %}
<div class="content__intro__image scroll reveal reveal_animation" data-ease-multiplier="-2"
style="background-image: url({{ thumb.url }})"></div>
{% endif %}
</div>

View File

@@ -0,0 +1,25 @@
{% load i18n cms_tags menu_tags %}
<div class="navigation">
<div class="navigation__lists">
<ul class="navigation__list__main">
{% show_menu 0 1 100 1 %}
</ul>
<ul class="navigation__list__meta navigation__list__meta--top">
{% show_menu_below_id 'meta' 0 0 0 0 %}
</ul>
<ul class="navigation__list__meta navigation__list__meta--bottom">
{% show_menu_below_id 'footer' 0 0 0 0 %}
</ul>
</div>
<ul class="navigation__languages">
{% for lang in LANGUAGES %}
<li class="{% if lang.0 == LANGUAGE_CODE %}active{% endif %}">
<a href="{% page_language_url lang.0 %}">{{ lang.0 }}</a>
</li>
{% endfor %}
</ul>
{% static_placeholder 'social_media' %}
</div>

View File

@@ -0,0 +1,40 @@
{% load i18n highlight thumbnail cms_tags %}
{% if not search and not title and not text %}
{% page_attribute 'page_title' page as title %}
{% page_attribute 'meta_description' page as text %}
{% endif %}
<li class="page_item__frame{% if subpage %} subpage{% endif %}{% if index != Null %} reveal_self reveal reveal_animation data_delay_{{ index }}{% endif %}">
<a href="{% if url %}{{ url }}{% else %}{{ page.url|default:page.get_public_url }}{% endif %}" class="page_item"
{% if target %}target="{{ target }}"{% endif %}>
<div class="page_item__image">
{% if image %}
{% thumbnail image 1000x600 box=cropping crop detail as thumb %}
<div class="page_item__image__main scroll" data-ease-multiplier="-2"
style="background-image: url({{ thumb.url }})"></div>
{% endif %}
<span class="page_item__image__title">{% if search %}{{ page.title }}{% else %}{{ title }}{% endif %}</span>
</div>
<div class="page_item__content">
{% if subpage %}
<h3 class="h2">{% if search %}{{ page.title }}{% else %}{{ title }}{% endif %}</h3>
{% else %}
<h2>{% if search %}{{ page.title }}{% else %}{{ title }}{% endif %}</h2>
{% endif %}
{% if search %}
<p>{% highlight page.text with request.GET.q %}</p>
{% else %}
<p>{{ text }}</p>
{% endif %}
<div class="page_item__button">
<span class="button">
<span class="button__icon">{% include 'project/assets/arrow-right-long.svg' %}</span>
<span class="button__text">{% trans 'Mehr' %}</span>
</span>
</div>
</div>
</a>
</li>

View File

@@ -0,0 +1,29 @@
{% load i18n spurl %}
{% if page_obj.has_other_pages %}
<div class="pagenav">
{% with from=page_obj.start_index until=page_obj.end_index count=page_obj.paginator.count %}
<p>{% blocktrans %}{{ from }} {{ until }} of {{ count }} {{ obj_string }} are displayed{% endblocktrans %}</p>
{% endwith %}
<ul>
{% if page_obj.has_previous %}
<li class="prev"><a href="{% spurl base='' query=request.GET set_query='page={{ page_obj.previous_page_number }}' %}">&laquo; {% trans "previous" %}</a></li>
{% endif %}
{% for page_num in page_obj.page_range %}
{% if page_num %}
{% if page_obj.number == page_num %}
<li class="page active"><span>{{ page_num }}</span></li>
{% else %}
<li class="page"><a href="{% spurl base='' query=request.GET set_query='page={{ page_num }}' %}">{{ page_num }}</a></li>
{% endif %}
{% else %}
<li class="jumper"><span>...</span></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="prev"><a href="{% spurl base='' query=request.GET set_query='page={{ page_obj.next_page_number }}' %}">{% trans "next" %} &raquo;</a></li>
{% endif %}
</ul>
</div>
{% endif %}

View File

@@ -0,0 +1,55 @@
{% load i18n cms_tags %}
<div class="content__frame">
{% url 'search' as search_url %}
{% with request.get_full_path as current_url %}
<a href="{% if search_url in current_url %}/{{ LANGUAGE_CODE }}/{% else %}{{ current_url }}{% endif %}"
class="search__close header__button header__button--close">
<span class="header__button__icon">
{% include 'project/assets/close.svg' %}
</span>
{% trans 'Schliessen' %}
</a>
{% endwith %}
<div class="content__container">
<div class="content__main">
<div class="search__content">
<div class="search__content__main">
<form action="{% url 'search' %}" method="get" class="search__form">
<input id="search__query" type="text" name="{{ search_form.q.html_name }}"
placeholder="{% trans 'Elementa entdecken...' %}" autocomplete="off"
{% if search_form.q.value %}value="{{ search_form.q.value }}"{% endif %}>
<button type="submit">
{% include 'project/assets/search.svg' %}
{% trans 'Suchen' %}
</button>
</form>
<div class="search__results">
<p class="section__text search__results__amount">
{% if page_obj.object_list|length > 0 %}
{% blocktrans with amount=page_obj.object_list|length q=search_form.q.value %}
{{ amount }} Resultate für «{{ q }}»:
{% endblocktrans %}
{% else %}
<strong>
{% blocktrans with q=search_form.q.value %}
Leider wurden keine Resultate mit dem Begriff «{{ q }}» gefunden.<br>
Sie erreichen uns auch über andere Kanäle:
{% endblocktrans %}
<a href="{% page_url 'contact' %}">{% trans 'Zum Kontakt' %}</a>
</strong>
{% endif %}
</p>
<ul>
{% for page in page_obj.object_list %}
{% include "project/includes/page_item.html" with search=True image=page.object.page.imageextension.image cropping=page.object.page.imageextension.cropping %}
{% endfor %}
</ul>
{# {% include "project/includes/pagination.html" with obj_string=_('results') %}#}
</div>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,21 @@
{% extends 'main.html' %}
{% load i18n cms_tags thumbnail %}
{% block content %}
<div class="content__frame">
{% include 'project/includes/content_intro.html' %}
<div class="content__container">
<div class="content__main">
<div class="page_list">
<ul>
{% for page in request.current_page.get_child_pages %}
{% if page.get_public_url %}
{% include "project/includes/page_item.html" with image=page.imageextension.image cropping=page.imageextension.cropping index=forloop.counter0 %}
{% endif %}
{% endfor %}
</ul>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,7 @@
<div class="subpage_list">
<ul>
{% for campaign in campaigns %}
{% include "project/includes/page_item.html" with title=campaign.title text=campaign.text url=campaign.url target='_blank' image=False index=forloop.counter0 subpage=True %}
{% endfor %}
</ul>
</div>

View File

@@ -0,0 +1,5 @@
{% extends 'project/content.html' %}
{% block content_main %}
{% include 'project/newsletter/subscription_form.html' %}
{% endblock %}

View File

@@ -0,0 +1,48 @@
{% load i18n %}
<form method="post" id="newsletter_subscription" action="{% url 'newsletter_subscription' %}" class="form">
{% if success %}
<p class="section__text form__success">
{% blocktrans %}
Ihre Angaben wurden erfolgreich übermittelt. Vielen Dank!
{% endblocktrans %}
</p>
{% else %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<p class="form__errors">{{ error }}</p>
{% endfor %}
{% endif %}
{% for field in form %}
<div class="form__field reveal_self reveal reveal_animation">
{{ field }}
{% if field.errors %}
<p class="form__field__errors">
{% for error in field.errors %}
{{ error }}{% if not forloop.last %}<br>{% endif %}
{% endfor %}
</p>
{% endif %}
{% if field.help_text %}
<p class="form__field__help_text">{{ field.help_text }}</p>
{% endif %}
</div>
{% endfor %}
{% csrf_token %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
<div class="form__submit reveal_self reveal reveal_animation">
<button type="submit" class="button">
<span class="button__icon">{% include 'project/assets/arrow-right-long.svg' %}</span>
<span class="button__text">{% trans 'Absenden' %}</span>
</button>
</div>
{% endif %}
</form>

View File

@@ -0,0 +1,16 @@
{% load i18n cms_tags %}
<div class="journey_calculator">
<p class="section__text">
{% for plugin in instance.child_plugin_instances %}
{% render_plugin plugin %}
{% endfor %}
</p>
<div class="journey_calculator__input">
<input id="journey_calculator__input" type="text" placeholder="{% trans 'Ihr Wohnort' %}">
<div class="journey_calculator__result" data-label="{% trans 'Min' %}"></div>
</div>
<p class="journey_calculator__message">
{% trans 'Bitte wählen Sie einen der vorgeschlagenen Orte aus.' %}
</p>
</div>

View File

@@ -0,0 +1,18 @@
<ul class="downloads">
{% for item in instance.items %}
<li class="reveal_self reveal reveal_animation data_delay_{{ forloop.counter0 }}">
<a href="{{ item.url }}" target="_blank" class="download__item">
<span class="download__item__file">
<span class="download__item__file__icon">{{ item.extension }}</span>
</span>
<span class="download__item__title">{{ item.label }}</span>
{% if item.description %}
<span class="download__item__description">{{ item.description }}</span>
{% endif %}
<span class="download__item__icon">
{% include 'project/assets/download.svg' %}
</span>
</a>
</li>
{% endfor %}
</ul>

View File

@@ -0,0 +1,15 @@
{% load cms_tags %}
<div class="highlight_list{% if instance.full_width %} full{% endif %}">
<div class="highlight_list__content">
{% for plugin in instance.child_plugin_instances %}
{% if plugin.plugin_type == 'HighlightListItemPlugin' %}
<div class="highlight_list__item__frame reveal_self reveal reveal_animation data_delay_{{ forloop.counter0 }}">
{% render_plugin plugin %}
</div>
{% else %}
{% render_plugin plugin %}
{% endif %}
{% endfor %}
</div>
</div>

View File

@@ -0,0 +1,14 @@
{% load fontawesome %}
<div class="highlight_list__item">
<div class="highlight_list__item__icon">
{% if instance.animated_icon %}
<div class="highlight_list__item__icon__animated animated_icon" data-icon="{{ instance.animated_icon }}">
</div>
{% else %}
{% fontawesome_icon instance.icon large=True %}
{% endif %}
</div>
<h3 class="highlight_list__item__title">{{ instance.title }}</h3>
<p class="highlight_list__item__text">{{ instance.text }}</p>
</div>

View File

@@ -0,0 +1,16 @@
{% load thumbnail %}
<div class="partner reveal_self reveal reveal_animation">
<div class="partner__logo">
{% thumbnail instance.logo 500x300 box=instance.cropping detail as thumb %}
<img src="{{ thumb.url }}">
</div>
<h3 class="section__text">{{ instance.name }}</h3>
<p class="section__text">
{{ instance.text }}
{% if instance.url %}
<br><br>
<a href="{{ instance.url }}">{{ instance.url|cut:'https://'|cut:'http://' }}</a>
{% endif %}
</p>
</div>

View File

@@ -0,0 +1,17 @@
{% load thumbnail %}
<div class="quote reveal_container{% if instance.image %} image{% endif %}">
<p class="quote__content reveal reveal_animation">{{ instance.content }}</p>
{% if instance.image %}
<div class="quote__image__frame reveal reveal_animation data_delay_2">
<div class="quote__image__main">
{% thumbnail instance.image 460x576 box=instance.cropping crop detail as thumb %}
<img class="quote__image scroll" data-ease-multiplier="-1"
src="{{ thumb.url }}" width="{{ thumb.width }}" height="{{ thumb.height }}">
</div>
<p class="quote__source reveal reveal_animation data_delay_4">{{ instance.source }}</p>
</div>
{% else %}
<p class="quote__source reveal reveal_animation data_delay_2">{{ instance.source }}</p>
{% endif %}
</div>

View File

@@ -0,0 +1,26 @@
{% load cms_tags %}
<div class="reference_list reveal_container">
<div class="reference_list__frame">
<div class="reference_list__content">
{% for plugin in instance.child_plugin_instances %}
<div class="reference_list__item__frame reveal reveal_animation data_delay_{{ forloop.counter0 }}"
data-id="{{ forloop.counter0 }}">
{% render_plugin plugin %}
</div>
{% endfor %}
<div class="reference_list__item__frame reference_list__item__frame--close" data-id="x">
{% include 'project/plugins/content/reference_list_item.html' %}
</div>
</div>
</div>
<div class="reference_list__videos">
<div class="reference_list__video__content">
{% for plugin in instance.child_plugin_instances %}
<div class="reference_list__video__item data_id_{{ forloop.counter0 }}">
{% include 'project/plugins/content/video.html' with instance=plugin %}
</div>
{% endfor %}
</div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
{% load i18n thumbnail %}
<a href="#" class="reference_list__item">
<div class="reference_list__item__image__main">
{% if instance.thumbnail %}
{% thumbnail instance.thumbnail 460x576 box=instance.cropping crop detail as thumb %}
<img class="reference_list__item__image scroll" data-ease-multiplier="-1"
src="{{ thumb.url }}" width="{{ thumb.width }}" height="{{ thumb.height }}">
{% endif %}
</div>
{% if instance.vimeo_id %}
<span class="video__play">
{% include 'project/assets/play.svg' %}
{% trans 'Video Abspielen' %}
</span>
{% endif %}
</a>

View File

@@ -0,0 +1,8 @@
{% load cms_tags %}
<div id="{{ instance.title|slugify }}" class="section">
<h2 class="reveal_self reveal reveal_animation">{{ instance.title }}</h2>
{% for plugin in instance.child_plugin_instances %}
{% render_plugin plugin %}
{% endfor %}
</div>

View File

@@ -0,0 +1,7 @@
{% load cms_tags %}
<p class="section__text reveal_self reveal reveal_animation{% if instance.columns %} columns{% endif %}">
{% for plugin in instance.child_plugin_instances %}
{% render_plugin plugin %}
{% endfor %}
</p>

View File

@@ -0,0 +1,6 @@
<div class="section__title reveal_self reveal reveal_animation">
<div class="section__title__main">
<div class="section__title__content scroll" data-scroll-mod="horizontal"
data-ease-multiplier="5"></div>
</div>
</div>

View File

@@ -0,0 +1,36 @@
{% load cms_tags i18n thumbnail %}
<div class="slider reveal_container" data-active="0" data-last="{{ instance.child_plugin_instances|length|add:'-1' }}">
<div class="slider__content">
<div class="slider__images__frame reveal reveal_animation">
<div class="slider__images scroll" data-ease-multiplier="-2">
{% for plugin in instance.child_plugin_instances %}
{% thumbnail plugin.image 1000x700 box=plugin.cropping crop detail as thumb %}
<div class="slider__image__item data_id_{{ forloop.counter0 }}"
style="background-image: url({{ thumb.url }})"></div>
{% endfor %}
</div>
</div>
<div class="slider__texts reveal reveal_animation data_delay_2">
<div class="slider__texts__frame">
<div class="slider__texts__content">
{% for plugin in instance.child_plugin_instances %}
<div class="slider__text__item data_id_{{ forloop.counter0 }}">
{% render_plugin plugin %}
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% if instance.child_plugin_instances|length > 1 %}
<a href="#" class="slider__navigation slider__navigation--next reveal reveal_animation data_delay_5">
{% include 'project/assets/arrow-right.svg' %}
{% trans 'Nächster Slide' %}
</a>
<a href="#" class="slider__navigation slider__navigation--prev reveal reveal_animation data_delay_4">
{% include 'project/assets/arrow-left.svg' %}
{% trans 'Vorheriger Slide' %}
</a>
{% endif %}
</div>

View File

@@ -0,0 +1,24 @@
{% load i18n %}
<div class="slider__text__item__content{% if instance.email %} email{% endif %}">
<h3 class="slider__text__item__title">{{ instance.title }}</h3>
{% if instance.subline %}
<p class="slider__text__item__subline">{{ instance.subline }}</p>
{% endif %}
{% if instance.text %}
<p class="slider__text__item__text">{{ instance.text }}</p>
{% endif %}
{% if instance.qualifications.count > 0 %}
<h4 class="slider__text__item__qualifications__title">{% trans 'Qualifikationen' %}:</h4>
<ul class="slider__text__item__qualifications">
{% for qualification in instance.qualifications.all %}
<li>{{ qualification.name }}</li>
{% endfor %}
</ul>
{% endif %}
{% if instance.email %}
<a href="mailto:{{ instance.email }}" class="slider__text__item__email">
{% include 'project/assets/mail.svg' %}
</a>
{% endif %}
</div>

View File

@@ -0,0 +1 @@
<div class="spacer"></div>

View File

@@ -0,0 +1,9 @@
<div class="subpage_list">
<ul>
{% for page in request.current_page.get_child_pages %}
{% if page.get_public_url %}
{% include "project/includes/page_item.html" with image=page.imageextension.image cropping=page.imageextension.cropping index=forloop.counter0 subpage=True %}
{% endif %}
{% endfor %}
</ul>
</div>

View File

@@ -0,0 +1,24 @@
{% load cms_tags i18n %}
<div class="text_slider reveal_container" data-active="0"
data-last="{{ instance.child_plugin_instances|length|add:'-1' }}">
<div class="text_slider__frame reveal reveal_animation data_delay_2">
<div class="text_slider__content">
<div class="text_slider__container">
{% for plugin in instance.child_plugin_instances %}
<div class="text_slider__item data_id_{{ forloop.counter0 }}">
{% render_plugin plugin %}
</div>
{% endfor %}
</div>
</div>
</div>
<a href="#" class="slider__navigation slider__navigation--next reveal reveal_animation data_delay_4">
{% include 'project/assets/arrow-right.svg' %}
{% trans 'Nächster Slide' %}
</a>
<a href="#" class="slider__navigation slider__navigation--prev reveal reveal_animation">
{% include 'project/assets/arrow-left.svg' %}
{% trans 'Vorheriger Slide' %}
</a>
</div>

View File

@@ -0,0 +1,3 @@
<p class="text_slider__text">
{{ instance.text }}
</p>

View File

@@ -0,0 +1,10 @@
{% load fontawesome %}
<ul class="section__text title_list reveal_self reveal reveal_animation">
{% for item in instance.title_list_items.all %}
<li>
<b>{{ item.title }}</b>
{{ item.text }}
</li>
{% endfor %}
</ul>

View File

@@ -0,0 +1,14 @@
{% load i18n thumbnail %}
<div class="video reveal_container">
<iframe class="video__frame" src="https://player.vimeo.com/video/{{ instance.vimeo_id }}" width="640" height="360" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
<a href="#" class="video__thumbnail reveal reveal_animation">
<span class="video__play">
{% include 'project/assets/play.svg' %}
{% trans 'Video Abspielen' %}
</span>
{% thumbnail instance.thumbnail 1000x1000 box=instance.cropping crop detail as thumb %}
<div class="video__thumbnail__image scroll" data-ease-multiplier="-2"
style="background-image: url({{ thumb.url }})"></div>
</a>
</div>

View File

@@ -0,0 +1,11 @@
{% load fontawesome %}
<ul class="social_media">
{% for item in instance.social_media_list_items.all %}
<li>
<a href="{{ item.url }}" target="_blank" class="social_media__item">
{% fontawesome_icon item.icon large=True %}
</a>
</li>
{% endfor %}
</ul>

View File

@@ -0,0 +1,59 @@
{% load i18n cms_tags thumbnail %}
<div id="timetable" data-active="0" data-last="{{ instance.child_plugin_instances|length }}">
<div class="timetable__clock__frame">
<div class="timetable__clock__main">
<div class="timetable__start reveal reveal_animation data_delay_8"></div>
<div class="timetable__clock reveal reveal_animation data_delay_12">
<svg class="timetable__clock__progress" width="500" height="500" viewBox="0 0 500 500">
<circle id="timetable__clock__progress" cx="250" cy="250" r="237.5" fill="none" stroke="#98C53A"
stroke-width="25" stroke-dasharray="1492.26" stroke-dashoffset="1492.26"/>
</svg>
{% include 'project/assets/clock.svg' %}
<div class="timetable__clock__digital">
<span class="timetable__clock__digital__intro">{{ instance.introduction }}</span>
<div id="timetable__clock__digital__time">
{{ instance.child_plugin_instances.0.time|time:'H' }}
<span>:</span>
{{ instance.child_plugin_instances.0.time|time:'i' }}
</div>
</div>
</div>
</div>
</div>
<div class="timetable__start__door timetable__start__door--left"></div>
<div class="timetable__start__door timetable__start__door--right"></div>
<a href="#" class="timetable__next reveal reveal_animation data_delay_23">
<span></span>
</a>
{% thumbnail instance.start_image 2110x1200 box=instance.cropping crop detail as thumb %}
<div class="timetable__start__background reveal reveal_animation data_delay_1"
style="background-image: url({{ thumb.url }})"></div>
<div class="timetable__intro__placeholder"></div>
{% for plugin in instance.child_plugin_instances %}
<div class="timetable__item {% cycle 'odd' 'even' %} data_id_{{ forloop.counter }}"
data-hour="{{ plugin.time|time:'H' }}"
data-minute="{{ plugin.time|time:'i' }}"
data-id="{{ forloop.counter }}">
{% render_plugin plugin %}
</div>
<div class="timetable__item__after {% if forloop.last %}last{% endif %}" data-id="{{ forloop.counter }}"></div>
{% endfor %}
<div class="timetable__titles">
{% for plugin in instance.child_plugin_instances %}
<div class="section__title data_id_{{ forloop.counter }}">
<div class="section__title__main">
<div class="section__title__content" data-ease-multiplier="2" data-scroll-mod="horizontal">
{{ plugin.title }}
</div>
</div>
</div>
{% endfor %}
</div>
</div>

View File

@@ -0,0 +1,17 @@
{% load thumbnail %}
<div class="timetable__item__main reveal reveal_animation">
<div class="timetable__item__image">
<div class="timetable__item__image__frame">
{% thumbnail instance.image 960x648 box=instance.cropping crop detail as thumb %}
<div class="timetable__item__image__main scroll" data-ease-multiplier="-2"
style="background-image: url({{ thumb.url }})"></div>
</div>
</div>
<div class="timetable__item__content">
<div class="timetable__item__content__frame">
<h2 class="timetable__item__title">{{ instance.title }}</h2>
<p class="section__text timetable__item__text">{{ instance.text }}</p>
</div>
</div>
</div>

View File

@@ -0,0 +1,13 @@
{% extends 'main.html' %}
{% load i18n %}
{% block body_class %}_search search_open {% if search_form.q.value %}search_results{% endif %}{% endblock %}
{% block title %}{% trans 'Suche' %}{% endblock %}
{% block extra_meta %}
<meta name="robots" content="noindex">
{% endblock %}
{% block content %}
{% endblock %}

View File

@@ -0,0 +1,6 @@
{% extends 'main.html' %}
{% load i18n cms_tags %}
{% block content %}
{% placeholder 'timetable' %}
{% endblock %}

View File

@@ -1 +1,14 @@
# -*- coding: utf-8 -*-
from django.conf.urls import url
from django.utils.translation import ugettext_lazy as _
from django.views.generic.base import TemplateView
from project.views import SearchView, NewsletterSubscriptionView
urlpatterns = [
url(_(r'^suche/'), SearchView.as_view(), kwargs={'search': True}, name='search'),
url(r'^newsletter/subscription/$', NewsletterSubscriptionView.as_view(), name='newsletter_subscription'),
url(r'^newsletter/subscription/success/$',
TemplateView.as_view(template_name='project/newsletter/subscription.html'), kwargs={'success': True},
name='newsletter_subscription_success'),
]

49
src/project/utils.py Normal file
View File

@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
from filer.fields.image import AdminImageWidget, AdminImageFormField, FilerImageField
from filer.models import File
# https://stackoverflow.com/questions/27033485/how-to-crop-an-image-selected-with-django-filer-in-django-admin
class CroppableImageWidget(AdminImageWidget):
def render(self, name, value, attrs=None):
if value:
file_obj = File.objects.get(pk=value)
attrs = attrs or {}
attrs.update({
'class': 'crop-thumb',
'data-thumbnail-url':
file_obj.thumbnails['admin_sidebar_preview'],
'data-field-name': name,
'data-org-width': file_obj.width,
'data-org-height': file_obj.height,
})
return super().render(name, value, attrs)
class Media:
js = [
'filer/js/addons/popup_handling.js',
'cms/js/libs/jquery.min.js',
'image_cropping/js/jquery.Jcrop.min.js',
'image_cropping/image_cropping.js',
]
css = {'all': ('image_cropping/css/jquery.Jcrop.min.css', 'image_cropping/css/admin_fix.css')}
class CroppableFormField(AdminImageFormField):
widget = CroppableImageWidget
class CroppableFilerImageField(FilerImageField):
default_form_class = CroppableFormField
# https://gist.github.com/specialunderwear/9d917ddacf3547b646ba
def AbstractClassWithoutFieldsNamed(cls, *excl):
if cls._meta.abstract:
remove_fields = [f for f in cls._meta.local_fields if f.name in excl]
for f in remove_fields:
cls._meta.local_fields.remove(f)
return cls
else:
raise Exception("Not an abstract model")

View File

@@ -1 +1,23 @@
# -*- coding: utf-8 -*-
from aldryn_search.views import AldrynSearchView
from django.core.urlresolvers import reverse_lazy
from django.views.generic.edit import FormView
from project.forms import NewsletterSubscriptionForm
class SearchView(AldrynSearchView):
template_name = 'project/search.html'
def get_context_data(self, **kwargs):
context = super(SearchView, self).get_context_data(**kwargs)
search_form = context['form']
context['search_form'] = search_form
del context['form']
return context
class NewsletterSubscriptionView(FormView):
template_name = 'project/newsletter/subscription.html'
form_class = NewsletterSubscriptionForm
success_url = reverse_lazy('newsletter_subscription_success')