forked from CGM_Public/pretix_original
Time machine mode [Z#23129725] (#3961)
Allows organizers to test their shop as if it were a different date and time. Implemented using a time_machine_now() function which is used instead of regular now(), which can overlay the real date time with a value from a ContextVar, assigned from a session value in EventMiddleware. For more information, see doc/development/implementation/timemachine.rst --------- Co-authored-by: Richard Schreiber <schreiber@rami.io> Co-authored-by: Raphael Michel <michel@rami.io>
This commit is contained in:
@@ -27,7 +27,7 @@ from django.urls import NoReverseMatch
|
||||
from django.utils.encoding import smart_str
|
||||
from django.utils.html import conditional_escape
|
||||
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri, mainreverse
|
||||
|
||||
register = template.Library()
|
||||
|
||||
@@ -45,11 +45,13 @@ class EventURLNode(URLNode):
|
||||
for k, v in self.kwargs.items()
|
||||
}
|
||||
view_name = self.view_name.resolve(context)
|
||||
event = self.event.resolve(context)
|
||||
event = self.event.resolve(context) if self.event is not False else False
|
||||
url = ''
|
||||
try:
|
||||
if self.absolute:
|
||||
url = build_absolute_uri(event, view_name, kwargs=kwargs)
|
||||
elif self.event is False:
|
||||
url = mainreverse(view_name, kwargs)
|
||||
else:
|
||||
url = eventreverse(event, view_name, kwargs=kwargs)
|
||||
except NoReverseMatch:
|
||||
@@ -65,21 +67,34 @@ class EventURLNode(URLNode):
|
||||
return url
|
||||
|
||||
|
||||
@register.tag
|
||||
def eventurl(parser, token, absolute=False):
|
||||
def multidomainurl(parser, token, has_event, absolute):
|
||||
"""
|
||||
Similar to {% url %} in the same way that eventreverse() is similar to reverse().
|
||||
Similar to {% url %}, but multidomain-aware. Used by eventurl, abseventurl and absmainurl.
|
||||
|
||||
Takes an event or organizer object, an url name and optional keyword arguments
|
||||
If has_event=True, takes an event or organizer object as first template tag parameter.
|
||||
Always takes an url name and optional keyword arguments after that.
|
||||
|
||||
Returns an absolute URL in the following cases:
|
||||
- absolute=True
|
||||
- has_event=True and the event has a custom domain
|
||||
Returns a relative URL otherwise.
|
||||
"""
|
||||
bits = token.split_contents()
|
||||
if len(bits) < 3:
|
||||
raise TemplateSyntaxError("'%s' takes at least two arguments, an event and the name of a url()." % bits[0])
|
||||
viewname = parser.compile_filter(bits[2])
|
||||
event = parser.compile_filter(bits[1])
|
||||
tagname = bits[0]
|
||||
if has_event:
|
||||
if len(bits) < 3:
|
||||
raise TemplateSyntaxError("'%s' takes at least two arguments, an event and the name of a url()." % tagname)
|
||||
viewname = parser.compile_filter(bits[2])
|
||||
event = parser.compile_filter(bits[1])
|
||||
bits = bits[3:]
|
||||
else:
|
||||
if len(bits) < 2:
|
||||
raise TemplateSyntaxError("'%s' takes at least one arguments, the name of a url()." % tagname)
|
||||
viewname = parser.compile_filter(bits[1])
|
||||
event = False
|
||||
bits = bits[2:]
|
||||
kwargs = {}
|
||||
asvar = None
|
||||
bits = bits[3:]
|
||||
if len(bits) >= 2 and bits[-2] == 'as':
|
||||
asvar = bits[-1]
|
||||
bits = bits[:-2]
|
||||
@@ -88,16 +103,26 @@ def eventurl(parser, token, absolute=False):
|
||||
for bit in bits:
|
||||
match = kwarg_re.match(bit)
|
||||
if not match:
|
||||
raise TemplateSyntaxError("Malformed arguments to eventurl tag")
|
||||
raise TemplateSyntaxError("Malformed arguments to %s tag" % tagname)
|
||||
name, value = match.groups()
|
||||
if name:
|
||||
kwargs[name] = parser.compile_filter(value)
|
||||
else:
|
||||
raise TemplateSyntaxError('Event urls only have keyword arguments.')
|
||||
raise TemplateSyntaxError('Multidomain urls only have keyword arguments.')
|
||||
|
||||
return EventURLNode(event, viewname, kwargs, asvar, absolute)
|
||||
|
||||
|
||||
@register.tag
|
||||
def eventurl(parser, token):
|
||||
"""
|
||||
Similar to {% url %} in the same way that eventreverse() is similar to reverse().
|
||||
|
||||
Takes an event or organizer object, an url name and optional keyword arguments
|
||||
"""
|
||||
return multidomainurl(parser, token, has_event=True, absolute=False)
|
||||
|
||||
|
||||
@register.tag
|
||||
def abseventurl(parser, token):
|
||||
"""
|
||||
@@ -105,4 +130,12 @@ def abseventurl(parser, token):
|
||||
|
||||
Returns an absolute URL.
|
||||
"""
|
||||
return eventurl(parser, token, absolute=True)
|
||||
return multidomainurl(parser, token, has_event=True, absolute=True)
|
||||
|
||||
|
||||
@register.tag
|
||||
def absmainurl(parser, token):
|
||||
"""
|
||||
Like {% url %}, but always returns an absolute URL on the main domain.
|
||||
"""
|
||||
return multidomainurl(parser, token, has_event=False, absolute=True)
|
||||
|
||||
@@ -180,7 +180,7 @@ def build_absolute_uri(obj, urlname, kwargs=None):
|
||||
"""
|
||||
Works similar to ``eventreverse`` but always returns an absolute URL.
|
||||
|
||||
:param obj: An ``Event`` or ``Organizer`` object
|
||||
:param obj: An ``Event`` or ``Organizer`` object, or ``False`` to generate main domain URLs
|
||||
:param name: The name of the URL route
|
||||
:type name: str
|
||||
:param kwargs: A dictionary of additional keyword arguments that should be used. You do not
|
||||
@@ -188,7 +188,10 @@ def build_absolute_uri(obj, urlname, kwargs=None):
|
||||
needed.
|
||||
:returns: An absolute URL (including scheme and host) as a string
|
||||
"""
|
||||
reversedurl = eventreverse(obj, urlname, kwargs)
|
||||
if obj is False:
|
||||
reversedurl = mainreverse(urlname, kwargs)
|
||||
else:
|
||||
reversedurl = eventreverse(obj, urlname, kwargs)
|
||||
if '://' in reversedurl:
|
||||
return reversedurl
|
||||
return urljoin(settings.SITE_URL, reversedurl)
|
||||
|
||||
Reference in New Issue
Block a user