Commit cf5967ba authored by gijs's avatar gijs

Page to buy tickets per project

parent 858eaaee
......@@ -153,7 +153,7 @@ class Event(models.Model):
published = models.BooleanField(default=True)
continuous = models.BooleanField(default=False)
show_hours = models.BooleanField(default=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='events')
event_type = models.ForeignKey(EventType, on_delete=models.SET_NULL, null=True)
venue = models.ForeignKey(Venue, on_delete=models.SET_NULL, null=True)
description_nl = models.TextField(null=True, blank=True, verbose_name="Description")
......
:root {
--white: #ffffff;
--white-alpha: #ffffffcc;
--white-transparent: #ffffff00;
--blue-moon: #445fff;
--blue-moon-alpha: #445fffcc;
--blue-moon-transparent: #445fff00;
--blue-moon-light: #9ba9ff;
--blue-moon-very-transparent: #445fff33;
--goldy: #ca9c73;
--goldy-light: #e4ccb6ff;
--goldy-alpha: #ca9c73cc;
--goldy-transparent: #ca9c7300;
--green-moon: #8ec0b8;
--green-moon-light: #bfdbd7ff;
--green-moon-alpha: #8ec0b8cc;
--green-moon-transparent: #8ec0b800;
--yellow-moon: #fff30e;
--pink: rgb(246, 103, 88);
}
body {
display: initial;
background: var(--goldy-light);
overflow: auto;
font-size: 1.1em;
line-height: 1.2em;
color: black;
}
#logo {
max-height: 75px;
max-width: 75%;
}
header, main {
max-width: 400px;
margin: 0 auto;
}
main {
border: 2px solid black;
background: white;
}
.ticket-option {
border-top: 2px solid black;
padding: 1em ;
margin: 1em 0;
}
.ticket-link {
float: right;
padding: 0 1em 0.2em 1em;
border-radius: 50%/2px;
background: var(--blue-moon);
color: white;
font-size: 70%;
display: inline-block;
font-family: "Syne";
font-weight: 600;
text-decoration: none;
}
.ticket-link:hover {
text-decoration: underline;
}
figure, picture {
margin: 0;
}
figure img {
border-radius: 50% / 3px;
max-width: 100%;
}
p {
font-family: 'Syne';
font-weight: 700;
}
p, .title {
margin: 1em;
}
.title {
font-family: 'syne', sans-serif;
font-weight: 900;
text-transform: uppercase;
}
.annotation {
font-family: 'Latin Modern', serif;
font-style: italic;
font-weight: normal;
font-size: 1.2em;
text-transform: none;
}
.date {
font-family: 'Syne', sans-serif;
font-weight: 900;
text-transform: uppercase;
letter-spacing: .03em
}
.venue, .contributor, .hour {
font-family: 'Lack', sans-serif;
}
.type {
font-family: 'Latin Modern', serif;
font-style: italic;
font-size: 1.2em;
}
.data-description-text {
position: relative;
}
@media screen and (min-width: 600px) {
[data-toggleable] .toggle {
display: none;
}
main, header {
max-width: 800px;
}
main {
display: flex;
flex-direction: row;
}
.event-description {
flex: 0 0 40%;
border-right: 2px solid black;
}
.event-ticket-options {
flex: 0 0 60%;
}
.ticket-option {
cursor: pointer;
}
.ticket-option:first-of-type {
border-top: 0;
margin-top: 0;
}
}
@media screen and (max-width: 600px) {
[data-toggleable] .toggle {
display: block;
padding-top: 3em;
padding-left: 1em;
font-family: 'Latin Modern', serif;
background: linear-gradient(to bottom, rgba(255,255,255,0), white 60%);
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
}
[data-toggleable][data-expanded="true"] .toggle {
display: block;
padding-top: 1em;
background: none;
position: relative;
}
[data-toggleable] {
position: relative;
max-height: 9em;
overflow: hidden;
}
[data-expanded="true"] {
max-height: initial;
}
.toggle .collapse-label,
[data-expanded="true"] .toggle .expand-label {
display: none
}
[data-expanded="true"] .toggle .collapse-label,
.toggle .expand-label {
display: initial;
}
}
@media screen and (max-width: 400px) {
main {
border-left: 0;
border-right: 0;
display: block;
}
}
\ No newline at end of file
{% load static contour i18n thumbnail %}
{% get_current_language as lang %}
<!DOCTYPE html>
<html lang="{{lang}}">
<head>
<link rel="stylesheet" href="{% static 'contour/css/fonts.css' %}" type="text/css" media="all">
<link rel="stylesheet" href="{% static 'contour/css/styles-tickets.css' %}" type="text/css" media="all">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="keywords" content="Contour 9, {{ project.title }}, tickets {{ project.title }}, {% for participant in project|sorted_participants %}{{participant.name}}, {% endfor %}">
<meta name="description" content="Website Contour 9 biennale 2019, {% if project.summary %}{{ project.summary|markdown|striptags }}{% else %}{{ event.project.title }}{% endif %}">
<title>Contour 9 - Tickets {{ project.title }}</title>
</head>
<body>
<header>
<a href="{% url 'contour:home' %}"><img src="{% static 'contour/images/contour9-logo.png' %}" id="logo" /></a>
</header>
<main>
<section class="event-description">
<h4 class="title" id="main-event-title">
<span class="annotation">Tickets </span>
{{ project.title }}
</h4>
{% if project|cover_image %}
{% with project|cover_image as image %}
<figure>
<img src="{% thumbnail image.image 400x150 crop upscale subject_location=image.image.subject_location %}" />
</figure>
{% endwith %}
{% endif %}
{% if project.summary %}
<section class="event-description-text" data-toggleable>
{{ project.summary|markdown }}
<section class="toggle">
<span class="expand-label">↓ {% trans "Read full description" %}</span>
<span class="collapse-label">↑ {% trans "Hide full description" %}</span>
</section>
</section>
{% endif %}
</section>
<section class="event-ticket-options">
{% for event in project|sorted_events|in_the_future %}
{% if event.show_ticket_link and event.ticket_link %}
<section class="ticket-option" data-ticket-link="{{ event.ticket_link }}">
<a href="{{ event.ticket_link }}" class="ticket-link">{% trans "Buy tickets" %}</a>
<time class="date" datetime="{{ event.start|date:'c' }}">{{ event.start|date:"j M" }}{% if event.end and event.end.date != event.start.date %} - {{ event.end|date:"j M" }}{% endif %}</time>
{% if event.show_hours %}
<span class="hour">{{ event.start|date:"H:i" }}{% if event.end %} - {{ event.end|date:"H:i" }}{% endif %}</span>
{% endif %}
<br />
<span class="type">{{ event.event_type }} </span>
<span class="venue">{% trans "at" %} {{ event.venue }}</span>
</section>
{% endif %}
{% endfor %}
</section>
</main>
<script>
document.querySelector('[data-toggleable] .toggle').addEventListener('click', function () {
var container = document.querySelector('[data-toggleable]');
container.dataset.expanded = ('expanded' in container.dataset && container.dataset.expanded == "true") ? 'false' : 'true';
});
var links = document.querySelectorAll('[data-ticket-link]');
for (var i = 0; i < links.length; i++) {
(function (link) {
link.addEventListener('click', function () {
window.location = link.dataset.ticketLink;
});
})(links[i]);
}
</script>
</body>
</html>
......@@ -8,6 +8,7 @@ from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from django.utils.encoding import force_text
from datetime import date
from contour.views import TemplateLoop, Interbellum
......@@ -16,39 +17,48 @@ register = template.Library()
@register.filter(is_safe=True)
@stringfilter
def markdown(value):
extensions = ["extra", ]
extensions = ["extra", ]
return mark_safe(md.markdown(force_text(value),
extensions=extensions))
@register.filter
def in_the_future(events):
return [event for event in events if event.start.date() >= date.today()]
@register.filter
def sorted_events(project):
return project.events.all().order_by('start')
return mark_safe(md.markdown(force_text(value),
extensions=extensions))
@register.filter
def sorted_participants(project):
return project.participants.all().order_by('projectparticipant__participant_order')
return project.participants.all().order_by('projectparticipant__participant_order')
@register.filter
def first_participant(project):
try:
return project.participants.all().order_by('projectparticipant__participant_order')[0]
except IndexError:
return None
try:
return project.participants.all().order_by('projectparticipant__participant_order')[0]
except IndexError:
return None
@register.filter
def sorted_images(project):
return project.images.all().order_by('projectimage__image_order')
return project.images.all().order_by('projectimage__image_order')
@register.filter
def first_image(project):
try:
return project.images.all().order_by('projectimage__image_order')[0]
except IndexError:
return None
try:
return project.images.all().order_by('projectimage__image_order')[0]
except IndexError:
return None
@register.filter
def cover_image(project):
try:
return project.images.filter(projectimage__cover_image=True).order_by('projectimage__image_order')[0]
except IndexError:
return None
try:
return project.images.filter(projectimage__cover_image=True).order_by('projectimage__image_order')[0]
except IndexError:
return None
@register.filter
def isTemplateLoop(candidate):
......
......@@ -10,6 +10,9 @@ urlpatterns = [
path('programme/', views.home, name='programme'),
path('home-beta/', views.homeBeta, name='homeBeta'),
path('event/<int:pk>', views.event, name='event'),
path('event/<int:pk>/', views.event, name='event'),
path('tickets/<int:pk>', views.tickets, name='tickets'),
path('tickets/<int:pk>/', views.tickets, name='tickets'),
path('contributor/', views.contributor, name='contributor'),
path('contributor/<int:pk>', views.contributor, name='contributor'),
path('contributor/<int:pk>/', views.contributor, name='contributor'),
......
from django.shortcuts import render
from .models import Loop, Event, Venue, Page, Participant
from .models import Loop, Event, Venue, Page, Participant, Project
from datetime import date, timedelta, datetime, time
from collections import namedtuple
import markdown
......@@ -261,8 +261,6 @@ def event(request, pk):
pads.append((pad, title, text))
print(pads)
images = [(key, image) for key, image in enumerate(event.project.images.all())]
documentation_images = [(key + len(images), image) for key, image in enumerate(event.documentation_image.all())]
combined_images = images + documentation_images
......@@ -275,6 +273,11 @@ def event(request, pk):
'combined_images': combined_images
})
def tickets(request, pk):
project = Project.objects.get(pk=pk, published=True)
return render(request, 'contour/tickets.html', { 'project': project })
def contributor(request, pk=None):
contributors = Participant.objects.filter(published=True)
timelineLabels = [loop.timeline_label for loop in Loop.objects.filter()]
......
......@@ -28,7 +28,9 @@ except AttributeError:
app_name = "ethertoff"
urlpatterns = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + [
urlpatterns = i18n_patterns(path('contour/', include('contour.urls')))
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + [
path('', views.home, name='home'),
path('admin/', admin.site.urls),
path('all/', views.all, name='all'), # TemplateView.as_view(template_name = 'all.html')
......@@ -52,8 +54,6 @@ urlpatterns = static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + [
urlpatterns += [re_path(r'^_nested_admin/', include('nested_admin.urls'))]
urlpatterns += i18n_patterns(path('contour/', include('contour.urls')))
urlpatterns += [re_path(r'w/(?P<slug>[^/]+)$', views.pad, name='pad-write')]
#urlpatterns = [
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment