Commit 8d7f03b0 authored by Thom Wiggers's avatar Thom Wiggers 📐
Browse files

Merge branch 'feature/partners' into 'master'

Add first implementation of partners

Fix issue #5.

See merge request !38
parents 1e056a78 5969a09b
......@@ -4,3 +4,5 @@ Pillow
django-static-precompiler>=1.4,<2
django-sendfile==0.3.10
django-template-check # This should be in dev-requirements somehow
bleach==1.4.3
django-tinymce==2.3.0
from django.contrib import admin
from utils.translation import TranslatedModelAdmin
from partners.models import (
Partner,
PartnerImage,
VacancyCategory,
Vacancy,
)
class PartnerImageInline(admin.StackedInline):
model = PartnerImage
@admin.register(Partner)
class PartnerAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("name",)}
list_display = ('name', 'is_active', 'is_main_partner',)
inlines = (PartnerImageInline,)
fieldsets = (
(None, {
'fields': (
'is_active', 'is_main_partner', 'name', 'slug', 'link',
'company_profile', 'logo', 'site_header'
)
}),
('Address', {
'fields': ('address', 'zip_code', 'city')
}),
)
@admin.register(VacancyCategory)
class VacancyCategoryAdmin(TranslatedModelAdmin):
prepopulated_fields = {"slug": ("name_en",)}
fields = ['name', 'slug']
@admin.register(Vacancy)
class VacancyAdmin(admin.ModelAdmin):
list_display = ('title', 'partner', 'company_name',)
fieldsets = (
(None, {
'fields': ('title', 'description', 'link')
}),
('Existing Partner', {
'fields': ('partner',)
}),
('Other Partner', {
'fields': ('company_name', 'company_logo',)
}),
('Categories', {
'fields': ('categories', )
}),
)
from django.apps import AppConfig
class PartnersConfig(AppConfig):
name = 'partners'
from random import shuffle
from partners.models import Partner
def showcased_partners(request):
if 'partner_sequence' not in request.session:
partner_ids = [p.id for p in Partner.objects.filter(is_active=True)]
shuffle(partner_ids)
request.session['partner_sequence'] = partner_ids
sequence = request.session['partner_sequence']
chosen, rest = sequence[:2], sequence[2:]
request.session['partner_sequence'] = rest + chosen
partners = tuple(Partner.objects.get(id=id) for id in chosen)
return {'showcased_partners': partners}
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2016-08-13 12:02+0200\n"
"PO-Revision-Date: 2016-08-13 12:03+0200\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 1.8.7.1\n"
#: templates/partners/index.html:6
msgid "Our partners"
msgstr "Onze partners"
#: templates/partners/index.html:8
msgid ""
"Als studievereniging doen we ontzettend ons best om leuke evenementen en "
"activiteiten te organiseren voor de studenten die lid zijn van Thalia. "
"Voorbeelden van deze evenementen en activiteiten zijn symposia, borrels en "
"programmeerwedstrijden. Verder organiseren wij ook lunchlezingen, workshops "
"en brengen we vijf keer per jaar de Thabloid uit (het studieblad van "
"Thalia). Voor financiering van deze activiteiten zijn wij afhankelijk van "
"het bedrijfsleven. Wij staat dan ook ten alle tijden open voor nieuwe "
"samenwerkingsmogelijkheden. Mocht u concrete interesse hebben om deze "
"bruisende studievereniging financieel te ondersteunen of bent u benieuwd "
"naar samenwerkingsmogelijkheden, dan kunt u een e-mail versturen naar de "
"commissaris externe betrekkingen, die te bereiken is via <a href=\"mailto:"
"samenwerking@thalia.nu\">samenwerking@thalia.nu</a>."
msgstr ""
"Als studievereniging doen we ontzettend ons best om leuke evenementen en "
"activiteiten te organiseren voor de studenten die lid zijn van Thalia. "
"Voorbeelden van deze evenementen en activiteiten zijn symposia, borrels en "
"programmeerwedstrijden. Verder organiseren wij ook lunchlezingen, workshops "
"en brengen we vijf keer per jaar de Thabloid uit (het studieblad van "
"Thalia). Voor financiering van deze activiteiten zijn wij afhankelijk van "
"het bedrijfsleven. Wij staat dan ook ten alle tijden open voor nieuwe "
"samenwerkingsmogelijkheden. Mocht u concrete interesse hebben om deze "
"bruisende studievereniging financieel te ondersteunen of bent u benieuwd "
"naar samenwerkingsmogelijkheden, dan kunt u een e-mail versturen naar de "
"commissaris externe betrekkingen, die te bereiken is via <a href=\"mailto:"
"samenwerking@thalia.nu\">samenwerking@thalia.nu</a>."
#: templates/partners/index.html:25 templates/partners/partner.html:22
msgid "Main Partner"
msgstr "Hoofdsponsor"
#: templates/partners/index.html:38 templates/partners/index.html:65
#: templates/partners/partner.html:81 templates/partners/vacancies.html:53
#: templates/partners/vacancies.html:58 templates/partners/vacancies.html:89
msgid "Learn more"
msgstr "Lees meer"
#: templates/partners/partner.html:8
#, python-format
msgid "About %(name)s"
msgstr "Over %(name)s"
#: templates/partners/partner.html:45
msgid "Information"
msgstr "Informatie"
#: templates/partners/partner.html:46
msgid "Street"
msgstr "Straatnaam"
#: templates/partners/partner.html:48
msgid "Zip Code"
msgstr "Postcode"
#: templates/partners/partner.html:50
msgid "City"
msgstr "Plaatsnaam"
#: templates/partners/partner.html:55
msgid "Website"
msgstr "Website"
#: templates/partners/partner.html:67 templates/partners/vacancies.html:5
msgid "Vacancies"
msgstr "Vacatures"
#: templates/partners/vacancies.html:7
msgid ""
"Je bent student en je hebt het maar krap. De politiek wil de studenten ook "
"al niet een handje toesteken. Gelukkig hebben we bedrijven die bij ons "
"vacatures aanbieden. Dus zit je krap en wil je wat bijverdienen, of ben je "
"(bijna) afgestudeerd en wil je eens wat rondkijken, op deze pagina staan al "
"onze openstaande vacatures. Wil je als bedrijf een vacature plaatsen op onze "
"website, dan kun je contact opnemen met de voorzitter van onze "
"sponsorcommissie via <a href=\"mailto:sponsor@thalia.nu\" target=\"_blank"
"\">sponsor@thalia.nu</a>."
msgstr ""
"Je bent student en je hebt het maar krap. De politiek wil de studenten ook "
"al niet een handje toesteken. Gelukkig hebben we bedrijven die bij ons "
"vacatures aanbieden. Dus zit je krap en wil je wat bijverdienen, of ben je "
"(bijna) afgestudeerd en wil je eens wat rondkijken, op deze pagina staan al "
"onze openstaande vacatures. Wil je als bedrijf een vacature plaatsen op onze "
"website, dan kun je contact opnemen met de voorzitter van onze "
"sponsorcommissie via <a href=\"mailto:sponsor@thalia.nu\" target=\"_blank"
"\">sponsor@thalia.nu</a>."
#: templates/partners/vacancies.html:22
msgid "Everything"
msgstr "Alles"
#: templates/partners/vacancies.html:69
msgid "All vacancies"
msgstr "Alle vacatures"
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-06 18:42
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Partner',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('is_active', models.BooleanField(default=False)),
('is_main_partner', models.BooleanField(default=False)),
('name', models.CharField(max_length=255)),
('slug', models.SlugField()),
('link', models.CharField(blank=True, max_length=255, validators=[django.core.validators.URLValidator()])),
('company_profile', models.TextField(blank=True, max_length=3072)),
('logo', models.ImageField(upload_to='public/partners/logos/')),
('site_header', models.ImageField(blank=True, null=True, upload_to='public/partners/headers/')),
('address', models.CharField(max_length=100, validators=[django.core.validators.RegexValidator(message='Enter a valid address', regex='^([1-9][e][\\s])*([ëéÉËa-zA-Z]+(([\\.][\\s])|([\\s]))?)+[1-9][0-9]*(([-][1-9][0-9]*)|([\\s]?[ëéÉËa-zA-Z]+))?$')])),
('zip_code', models.CharField(max_length=12, validators=[django.core.validators.RegexValidator(message='Enter a valid zip code', regex='^[1-9][0-9]{3}[\\s]?[A-Za-z]{2}$')])),
('city', models.CharField(max_length=100)),
],
),
migrations.CreateModel(
name='PartnerImage',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('image', models.ImageField(upload_to='public/partners/images/')),
('partner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='partners.Partner')),
],
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-10 17:33
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('partners', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='VacancyCategory',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('slug', models.SlugField()),
('name_en', models.CharField(max_length=30, verbose_name='name (EN)')),
('name_nl', models.CharField(max_length=30, verbose_name='name (NL)')),
],
options={
'verbose_name_plural': 'Vanancy Categories',
},
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-13 08:47
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('partners', '0002_vacancycategory'),
]
operations = [
migrations.CreateModel(
name='Vacancy',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('description', models.TextField(max_length=3072)),
('link', models.CharField(blank=True, max_length=255, validators=[django.core.validators.URLValidator()])),
('company_name', models.CharField(blank=True, max_length=255)),
('company_logo', models.ImageField(blank=True, null=True, upload_to='public/partners/vacancy-logos/')),
('categories', models.ManyToManyField(blank=True, to='partners.VacancyCategory')),
('partner', models.ForeignKey(blank=True, help_text='When you use a partner, the company name and logo below will not be used.', null=True, on_delete=django.db.models.deletion.PROTECT, to='partners.Partner')),
],
options={
'verbose_name_plural': 'Vacancies',
},
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2016-08-13 11:20
from __future__ import unicode_literals
from django.db import migrations
import tinymce.models
class Migration(migrations.Migration):
dependencies = [
('partners', '0003_vacancy'),
]
operations = [
migrations.AlterField(
model_name='partner',
name='company_profile',
field=tinymce.models.HTMLField(blank=True),
),
migrations.AlterField(
model_name='vacancy',
name='description',
field=tinymce.models.HTMLField(blank=True),
),
]
from django.db import models
from django.core.validators import RegexValidator, URLValidator
from utils.translation import MultilingualField, ModelTranslateMeta
from tinymce.models import HTMLField
class Partner(models.Model):
is_active = models.BooleanField(default=False)
is_main_partner = models.BooleanField(default=False)
name = models.CharField(max_length=255)
slug = models.SlugField()
link = models.CharField(
max_length=255,
blank=True,
validators=[URLValidator()]
)
company_profile = HTMLField(blank=True)
logo = models.ImageField(upload_to='public/partners/logos/')
site_header = models.ImageField(
upload_to='public/partners/headers/',
null=True,
blank=True
)
address = models.CharField(max_length=100, validators=[
RegexValidator(
regex=(r'^([1-9][e][\s])*([ëéÉËa-zA-Z]'
'+(([\.][\s])|([\s]))?)+[1-9][0-9]'
'*(([-][1-9][0-9]*)|([\s]?[ëéÉËa-zA-Z]+))?$'),
message='Enter a valid address')
])
zip_code = models.CharField(max_length=12, validators=[
RegexValidator(
regex=r'^[1-9][0-9]{3}[\s]?[A-Za-z]{2}$',
message='Enter a valid zip code'
)
])
city = models.CharField(max_length=100)
def save(self, *args, **kwargs):
if self.is_main_partner:
self._reset_main_partner()
super(Partner, self).save(*args, **kwargs)
def _reset_main_partner(self):
try:
current_main_partner = Partner.objects.get(is_main_partner=True)
if self != current_main_partner:
current_main_partner.is_main_partner = False
current_main_partner.save()
except Partner.DoesNotExist:
pass
def __str__(self):
return self.name
class PartnerImage(models.Model):
partner = models.ForeignKey(
Partner,
on_delete=models.CASCADE,
related_name="images"
)
image = models.ImageField(upload_to='public/partners/images/')
def __str__(self):
return 'image of {}'.format(self.partner.name)
class VacancyCategory(models.Model, metaclass=ModelTranslateMeta):
name = MultilingualField(models.CharField, max_length=30)
slug = models.SlugField()
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'Vanancy Categories'
class Vacancy(models.Model):
title = models.CharField(max_length=255)
description = HTMLField(blank=True)
link = models.CharField(
max_length=255,
blank=True,
validators=[URLValidator()]
)
partner = models.ForeignKey(
Partner,
on_delete=models.PROTECT,
null=True,
blank=True,
help_text="When you use a partner, the company name and logo " +
"below will not be used."
)
company_name = models.CharField(max_length=255, blank=True)
company_logo = models.ImageField(
upload_to='public/partners/vacancy-logos/',
null=True,
blank=True
)
categories = models.ManyToManyField(VacancyCategory, blank=True)
def get_company_name(self):
if self.partner:
return self.partner.name
return self.company_name
def get_company_logo(self):
if self.partner:
return self.partner.logo
return self.company_logo
def __str__(self):
return self.get_company_name() + ' - ' + self.title
class Meta:
verbose_name_plural = 'Vacancies'
{% extends 'base.html' %}
{% load i18n %}
{% block body %}
<h1>{% trans "Our partners" %}</h1>
<p class="tcenter">
{% blocktrans trimmed %}
Als studievereniging doen we ontzettend ons best om leuke evenementen en activiteiten te organiseren
voor de studenten die lid zijn van Thalia.
Voorbeelden van deze evenementen en activiteiten zijn symposia, borrels en programmeerwedstrijden.
Verder organiseren wij ook lunchlezingen, workshops en brengen we vijf keer per jaar de Thabloid
uit (het studieblad van Thalia).
Voor financiering van deze activiteiten zijn wij afhankelijk van het bedrijfsleven.
Wij staat dan ook ten alle tijden open voor nieuwe samenwerkingsmogelijkheden.
Mocht u concrete interesse hebben om deze bruisende studievereniging financieel te ondersteunen of
bent u benieuwd naar samenwerkingsmogelijkheden, dan kunt u een e-mail versturen naar de commissaris
externe betrekkingen, die te bereiken is via
<a href="mailto:samenwerking@thalia.nu">samenwerking@thalia.nu</a>.
{% endblocktrans %}
</p>
<div id="careerpage">
<div>
<h3>{% trans "Main Partner" %}</h3>
{% if main_partner %}
<div class="th_hoofdpartner_wrapper">
<div class="th_hoofdpartner_logo alignleft">
<img src="{{ main_partner.logo.url }}" />
</div>
<h4>{{ main_partner.name }}</h4>
<p>{{ main_partner.company_profile|striptags|truncatechars:425 }}</p>
<p>
<a href="{% url "partners:partner" main_partner.slug %}" class="link-style3">
{% trans "Learn more" %} &raquo;
</a>
</p>
</div>
{% endif %}
</div>
<?php endif; ?>
<!-- .portfolio-posts -->
<div class="portfolio portfolio-isotope">
<ul class="portfolio-posts row">
{% for partner in partners %}
<li class="post span4 has-overlay">
<div class="post-inner">
<div class="th_partner_logo">
{% if partner.logo %}
<img src="{{ partner.logo.url }}" alt="Logo {{ partner.name }}"/>
{% else %}
<h2>{{ partner.name }}</h2>
{% endif %}
</div>
<div class="post-body"></div>
<div class="post-overlay">
<a href="{% url 'partners:partner' partner.slug %}">
<div class="post-overlay-meta">
<h2>{{ partner.name }}</h2>
<p>{{ partner.company_profile|striptags|truncatechars:180 }}</p>
<span class="partner-logo-overlay-readmore">{% trans "Learn more" %} &raquo; </span>
</div>
<div class="klikbaar"></div>
</a>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endblock body %}
\ No newline at end of file
{% extends "base.html" %}
{% load i18n bleach_tags %}
{% block header_image %}{% spaceless %}
{% if partner.site_header %}
{{ partner.site_header.url }}
{% else %}
{{ block.super }}
{% endif %}
{% endspaceless %}{% endblock header_image %}
{% block body %}
<h1>{{ partner.name }}</h1>
<h3>{% blocktrans with name=partner.name %}About {{ name }}{% endblocktrans %}</h3>
<div class="row">
<div class="span8">
<div id="bedrijfsomschrijving">
{{ partner.company_profile|bleach }}
</div>
</div>
<div class="span4">
<div id="partner_images">
<div class="partner_image_item possibly_main_partner">
{% if partner.logo %}
{% if partner.is_main_partner %}
<div class="ribbon-wrapper-basiskleur">
<div class="ribbon-basiskleur">{% trans "Main Partner" %}</div>
</div>
{% endif %}
{% endif %}
<img src="{{ partner.logo.url }}" alt="Logo {{ partner.name }}" />
</div>
{% for image in partner.images.all %}
<div class="partner_image_item">
<a class="gallery-box"
data-download="{{ image.image.url }}"
href="{{ image.image.url }}"
rel="partner-images"
>
<img src="{{ image.image.url }}" />
</a>
</div>
{% endfor %}
</div>
</div>
</div>