forked from CGM_Public/pretix_original
* Vendor vue.js * Refactor item_group_by_category to support vouchers * Widget: Show product list * Widget: free prices * Widget: pictures and loading indicator * Widget: First iframe steps * Widget: Do not rerender iframe * Widget: Error handling * Improve widget * Widget: localization tech * Fix invoice style * Voucher attribute and waiting list * Add some iframe chrome * First step to namespaced carts * More isolation steps * More cart isolation things * More cart isolation things * Mobile stuff * Show cart on checkout pages * PayPal and Stripe support * Enable downloads * Locale handling * change text "save URL to this exact page" * Widget: voucher redemption * Widget: CSS * CSS: Responsive * Widget: CSS improvements * Widget: Add embedding code generator * Widget: Error messages and SSL check * First tests * Widget: tests * Don't use IDs in widgets * Widget: static files caching
This commit is contained in:
@@ -4,13 +4,13 @@ from django.core.exceptions import ValidationError
|
||||
from django.core.validators import RegexValidator
|
||||
from django.db.models import Q
|
||||
from django.utils.timezone import get_current_timezone_name
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
|
||||
from i18nfield.forms import I18nFormField, I18nTextarea
|
||||
from pytz import common_timezones, timezone
|
||||
|
||||
from pretix.base.forms import I18nModelForm, PlaceholderValidator, SettingsForm
|
||||
from pretix.base.models import Event, Organizer, TaxRule
|
||||
from pretix.base.models.event import EventMetaValue
|
||||
from pretix.base.models.event import EventMetaValue, SubEvent
|
||||
from pretix.base.reldate import RelativeDateField, RelativeDateTimeField
|
||||
from pretix.control.forms import (
|
||||
ExtFileField, SlugWidget, SplitDateTimePickerWidget,
|
||||
@@ -897,3 +897,44 @@ class TaxRuleForm(I18nModelForm):
|
||||
class Meta:
|
||||
model = TaxRule
|
||||
fields = ['name', 'rate', 'price_includes_tax', 'eu_reverse_charge', 'home_country']
|
||||
|
||||
|
||||
class WidgetCodeForm(forms.Form):
|
||||
subevent = forms.ModelChoiceField(
|
||||
label=pgettext_lazy('subevent', "Date"),
|
||||
required=True,
|
||||
queryset=SubEvent.objects.none()
|
||||
)
|
||||
language = forms.ChoiceField(
|
||||
label=_("Language"),
|
||||
required=True,
|
||||
choices=settings.LANGUAGES
|
||||
)
|
||||
voucher = forms.CharField(
|
||||
label=_("Pre-selected voucher"),
|
||||
required=False,
|
||||
help_text=_("If set, the widget will show products as if this voucher has been entered and when a product is "
|
||||
"bought via the widget, this voucher will be used. This can for example be used to provide "
|
||||
"widgets that give discounts or unlock secret products.")
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.event = kwargs.pop('event')
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
if self.event.has_subevents:
|
||||
self.fields['subevent'].queryset = self.event.subevents.all()
|
||||
else:
|
||||
del self.fields['subevent']
|
||||
|
||||
self.fields['language'].choices = [(l, n) for l, n in settings.LANGUAGES if l in self.event.settings.locales]
|
||||
|
||||
def clean_voucher(self):
|
||||
v = self.cleaned_data.get('voucher')
|
||||
if not v:
|
||||
return
|
||||
|
||||
if not self.event.vouchers.filter(code=v).exists():
|
||||
raise ValidationError(_('The given voucher code does not exist.'))
|
||||
|
||||
return v
|
||||
|
||||
@@ -75,6 +75,11 @@
|
||||
{% trans "Permissions" %}
|
||||
</a>
|
||||
</li>
|
||||
<li {% if "event.settings.widget" == url_name %}class="active"{% endif %}>
|
||||
<a href="{% url 'control:event.settings.widget' organizer=request.event.organizer.slug event=request.event.slug %}">
|
||||
{% trans "Widget" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% for nav in nav_event_settings %}
|
||||
<li {% if nav.active %}class="active"{% endif %}>
|
||||
|
||||
63
src/pretix/control/templates/pretixcontrol/event/widget.html
Normal file
63
src/pretix/control/templates/pretixcontrol/event/widget.html
Normal file
@@ -0,0 +1,63 @@
|
||||
{% extends "pretixcontrol/event/settings_base.html" %}
|
||||
{% load i18n %}
|
||||
{% load staticfiles %}
|
||||
{% load bootstrap3 %}
|
||||
{% load eventurl %}
|
||||
{% block inside %}
|
||||
<legend>{% trans "Widget" %}</legend>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
The pretix widget is a way to embed your ticket shop into your event website. This way, your visitors can
|
||||
buy their ticket right away without leaving your website.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% if valid %}
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
To embed the widget onto your website, simply copy the following code to the <code><head></code>
|
||||
section of your website:
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<pre><link rel="stylesheet" type="text/css" href="{% abseventurl request.event "presale:event.widget.css" %}">
|
||||
<script type="text/javascript" src="{{ urlprefix }}{% url "presale:widget.js" lang=form.cleaned_data.language %}" async></script></pre>
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Then, copy the following code to the place of your website where you want the widget to show up:
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% if form.cleaned_data.subevent %}
|
||||
{% abseventurl request.event "presale:event.index" subevent=form.cleaned_data.subevent.pk as indexurl %}
|
||||
{% else %}
|
||||
{% abseventurl request.event "presale:event.index" as indexurl %}
|
||||
{% endif %}
|
||||
<pre><pretix-widget event="http://192.168.0.10:8000/democon/"{% if form.cleaned_data.subevent %} subevent="{{ form.cleaned_data.subevent.pk }}"{% endif %}{% if form.cleaned_data.voucher %} voucher="{{ form.cleaned_data.voucher }}"{% endif %}></pretix-widget>
|
||||
<noscript>
|
||||
<div class="pretix-widget">
|
||||
<div class="pretix-widget-info-message">
|
||||
{% blocktrans trimmed with a_attr='target="_blank" href="'|add:indexurl|add:'"'|safe %}
|
||||
JavaScript is disabled in your browser. To access our ticket shop without javascript,
|
||||
please <a {{ a_attr }}>click here</a>.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
</pre>
|
||||
{% else %}
|
||||
<p>
|
||||
{% blocktrans trimmed %}
|
||||
Using this form, you can generate a code to copy and paste to your website source.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% bootstrap_form form layout="control" %}
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-3 col-md-9">
|
||||
<button type="submit" class="btn btn-primary btn-save">
|
||||
{% trans "Generate widget code" %}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -75,6 +75,7 @@ urlpatterns = [
|
||||
url(r'^settings/tax/(?P<rule>\d+)/$', event.TaxUpdate.as_view(), name='event.settings.tax.edit'),
|
||||
url(r'^settings/tax/add$', event.TaxCreate.as_view(), name='event.settings.tax.add'),
|
||||
url(r'^settings/tax/(?P<rule>\d+)/delete$', event.TaxDelete.as_view(), name='event.settings.tax.delete'),
|
||||
url(r'^settings/widget$', event.WidgetSettings.as_view(), name='event.settings.widget'),
|
||||
url(r'^subevents/$', subevents.SubEventList.as_view(), name='event.subevents'),
|
||||
url(r'^subevents/(?P<subevent>\d+)/$', subevents.SubEventUpdate.as_view(), name='event.subevent'),
|
||||
url(r'^subevents/(?P<subevent>\d+)/delete$', subevents.SubEventDelete.as_view(),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
@@ -36,10 +37,12 @@ from pretix.control.forms.event import (
|
||||
CommentForm, DisplaySettingsForm, EventMetaValueForm, EventSettingsForm,
|
||||
EventUpdateForm, InvoiceSettingsForm, MailSettingsForm,
|
||||
PaymentSettingsForm, ProviderForm, TaxRuleForm, TicketSettingsForm,
|
||||
WidgetCodeForm,
|
||||
)
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.control.signals import nav_event_settings
|
||||
from pretix.helpers.urls import build_absolute_uri
|
||||
from pretix.multidomain.urlreverse import get_domain
|
||||
from pretix.presale.style import regenerate_css
|
||||
|
||||
from . import CreateView, UpdateView
|
||||
@@ -989,3 +992,31 @@ class TaxDelete(EventSettingsViewMixin, EventPermissionRequiredMixin, DeleteView
|
||||
context = super().get_context_data(*args, **kwargs)
|
||||
context['possible'] = self.object.allow_delete()
|
||||
return context
|
||||
|
||||
|
||||
class WidgetSettings(EventSettingsViewMixin, EventPermissionRequiredMixin, FormView):
|
||||
template_name = 'pretixcontrol/event/widget.html'
|
||||
permission = 'can_change_event_settings'
|
||||
form_class = WidgetCodeForm
|
||||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['event'] = self.request.event
|
||||
return kwargs
|
||||
|
||||
def form_valid(self, form):
|
||||
ctx = self.get_context_data()
|
||||
ctx['form'] = form
|
||||
ctx['valid'] = True
|
||||
return self.render_to_response(ctx)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super().get_context_data(**kwargs)
|
||||
ctx['urlprefix'] = settings.SITE_URL
|
||||
domain = get_domain(self.request.organizer)
|
||||
if domain:
|
||||
siteurlsplit = urlsplit(settings.SITE_URL)
|
||||
if siteurlsplit.port and siteurlsplit.port not in (80, 443):
|
||||
domain = '%s:%d' % (domain, siteurlsplit.port)
|
||||
ctx['urlprefix'] = '%s://%s' % (siteurlsplit.scheme, domain)
|
||||
return ctx
|
||||
|
||||
Reference in New Issue
Block a user