Last active
December 17, 2015 04:18
-
-
Save anhtran/5548975 to your computer and use it in GitHub Desktop.
In some cases, you don't want to use the middleware. These tags will be useful to navigate users to HTTPS or not. I modified them from Django source files.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.template import Library, TemplateSyntaxError | |
from django.template.defaulttags import kwarg_re | |
from django.template.base import Node | |
from django.utils.encoding import smart_str | |
from django.conf import settings | |
from django.contrib.sites.models import Site | |
register = Library() | |
""" | |
Example: {% secure_url "admin:index" %} or {% unsecure_url "homepage" as home %} | |
""" | |
class URLNode(Node): | |
def __init__(self, view_name, args, kwargs, asvar, legacy_view_name=True, secure=True): | |
self.view_name = view_name | |
self.legacy_view_name = legacy_view_name | |
self.args = args | |
self.kwargs = kwargs | |
self.asvar = asvar | |
self.secure = secure | |
def render(self, context): | |
from django.core.urlresolvers import reverse, NoReverseMatch | |
args = [arg.resolve(context) for arg in self.args] | |
kwargs = dict([(smart_str(k, 'ascii'), v.resolve(context)) | |
for k, v in self.kwargs.items()]) | |
view_name = self.view_name | |
if not self.legacy_view_name: | |
view_name = view_name.resolve(context) | |
# Try to look up the URL twice: once given the view name, and again | |
# relative to what we guess is the "main" app. If they both fail, | |
# re-raise the NoReverseMatch unless we're using the | |
# {% url ... as var %} construct in which cause return nothing. | |
url = '' | |
try: | |
url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app) | |
except NoReverseMatch, e: | |
if settings.SETTINGS_MODULE: | |
project_name = settings.SETTINGS_MODULE.split('.')[0] | |
try: | |
url = reverse(project_name + '.' + view_name, | |
args=args, kwargs=kwargs, | |
current_app=context.current_app) | |
except NoReverseMatch: | |
if self.asvar is None: | |
# Re-raise the original exception, not the one with | |
# the path relative to the project. This makes a | |
# better error message. | |
raise e | |
else: | |
if self.asvar is None: | |
raise e | |
current_site = Site.objects.get_current() | |
if self.secure: | |
s = "https://%(site)s%(url)s" % {'url': url, 'site': current_site} | |
else: | |
s = "http://%(site)s%(url)s" % {'url': url, 'site': current_site} | |
if self.asvar: | |
context[self.asvar] = s | |
return '' | |
else: | |
return s | |
@register.tag | |
def secure_url(parser, token): | |
bits = token.split_contents() | |
if len(bits) < 2: | |
raise TemplateSyntaxError("'%s' takes at least one argument" | |
" (path to a view)" % bits[0]) | |
viewname = parser.compile_filter(bits[1]) | |
args = [] | |
kwargs = {} | |
asvar = None | |
bits = bits[2:] | |
if len(bits) >= 2 and bits[-2] == 'as': | |
asvar = bits[-1] | |
bits = bits[:-2] | |
if len(bits): | |
for bit in bits: | |
match = kwarg_re.match(bit) | |
if not match: | |
raise TemplateSyntaxError("Malformed arguments to url tag") | |
name, value = match.groups() | |
if name: | |
kwargs[name] = parser.compile_filter(value) | |
else: | |
args.append(parser.compile_filter(value)) | |
if settings.DEBUG: | |
return URLNode(viewname, args, kwargs, asvar, legacy_view_name=False, secure=False) | |
return URLNode(viewname, args, kwargs, asvar, legacy_view_name=False, secure=True) | |
@register.tag | |
def unsecure_url(parser, token): | |
bits = token.split_contents() | |
if len(bits) < 2: | |
raise TemplateSyntaxError("'%s' takes at least one argument" | |
" (path to a view)" % bits[0]) | |
viewname = parser.compile_filter(bits[1]) | |
args = [] | |
kwargs = {} | |
asvar = None | |
bits = bits[2:] | |
if len(bits) >= 2 and bits[-2] == 'as': | |
asvar = bits[-1] | |
bits = bits[:-2] | |
if len(bits): | |
for bit in bits: | |
match = kwarg_re.match(bit) | |
if not match: | |
raise TemplateSyntaxError("Malformed arguments to url tag") | |
name, value = match.groups() | |
if name: | |
kwargs[name] = parser.compile_filter(value) | |
else: | |
args.append(parser.compile_filter(value)) | |
return URLNode(viewname, args, kwargs, asvar, legacy_view_name=False, secure=False) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment