Ticket #10944: 10944_v3.diff

File 10944_v3.diff, 7.6 KB (added by Christopher Medrela, 12 years ago)
  • new file django/contrib/sites/templatetags/__init__.py

    diff --git a/django/contrib/sites/templatetags/__init__.py b/django/contrib/sites/templatetags/__init__.py
    new file mode 100644
    index 0000000..8b13789
    - +  
     1
  • new file django/contrib/sites/templatetags/sites.py

    diff --git a/django/contrib/sites/templatetags/sites.py b/django/contrib/sites/templatetags/sites.py
    new file mode 100644
    index 0000000..cc408aa
    - +  
     1from django import template
     2from django.contrib.sites.models import Site
     3from django.conf import settings
     4from django.template.base import Node, Token
     5from django.template.defaulttags import url
     6
     7
     8register = template.Library()
     9
     10
     11@register.tag
     12def site_url(parser, token):
     13    #import ipdb; ipdb.set_trace()
     14    bits = token.split_contents()
     15    if len(bits) < 2:
     16        raise TemplateSyntaxError("'%s' needs an argument describing "
     17                                  "path to a view." % bits[0])
     18    site = parser.compile_filter(bits[1])
     19
     20    # handle "site_url site using https"
     21    protocol = 'http'
     22    if len(bits) > 2 and bits[2] == 'using':
     23        if len(bits) < 4:
     24            raise TemplateSyntaxError("'%s' needs a protocol after "
     25                                      "'using' word." % bits[0])
     26        protocol = bits[3]
     27        del bits[2:4] # delete "using <protocol>"
     28    del bits[1] # delete site argument
     29
     30    content = " ".join(bits)
     31    new_token = Token(token.token_type, content)
     32    url_node = url(parser, new_token)
     33    return SiteURLNode(protocol, site, url_node)
     34
     35
     36class SiteURLNode(Node):
     37    def __init__(self, protocol, site, url_node):
     38        self._protocol = protocol
     39        self._url_node = url_node
     40        self._site = site
     41
     42    def render(self, context):
     43        relative_path = self._url_node.render(context) # "/view"
     44        domain = self._site.resolve(context, True).domain # "example.com"
     45        return self._protocol + "://" + domain + relative_path
     46
  • docs/ref/contrib/sites.txt

    diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt
    index 8fc434b..e7e2dd3 100644
    a b fallback for cases where it is not installed.  
    174174.. function:: get_current_site(request)
    175175
    176176    Checks if contrib.sites is installed and returns either the current
    177     :class:`~django.contrib.sites.models.Site` object or a 
     177    :class:`~django.contrib.sites.models.Site` object or a
    178178    :class:`~django.contrib.sites.models.RequestSite` object based on
    179179    the request.
    180180
    gives you more flexibility, but it's also more complex.  
    240240It's a good idea to exploit the :class:`~django.contrib.sites.models.Site`
    241241objects as much as possible, to remove unneeded complexity and redundancy.
    242242
    243 Getting the current domain for full URLs
    244 ----------------------------------------
     243``site_url`` tag for building full URLs
     244---------------------------------------
     245
     246Django's ``get_absolute_url()`` convention is nice for getting your
     247objects' URL without the domain name, but in some cases you might want
     248to display the full URL -- with ``http://`` and the domain and
     249everything -- for an object.  To do this, you can use ``site_url`` tag
     250which behave in similar way to ``url`` tag except there must be site
     251specified as first argument::
     252
     253    {% site_url site 'myapp.views.viewname' %}
    245254
    246 Django's ``get_absolute_url()`` convention is nice for getting your objects'
    247 URL without the domain name, but in some cases you might want to display the
    248 full URL -- with ``http://`` and the domain and everything -- for an object.
    249 To do this, you can use the sites framework. A simple example::
     255The result of rendering that template is
     256``http://example.com/path/to/view``.
     257
     258If you want you can also specify another protocol (the default is
     259``http``). To do this add ``using`` and protocol after site argument,
     260see example::
     261
     262    {% site_url site using https 'myapp.views.viewname' %}
    250263
    251     >>> from django.contrib.sites.models import Site
    252     >>> obj = MyModel.objects.get(id=3)
    253     >>> obj.get_absolute_url()
    254     '/mymodel/objects/3/'
    255     >>> Site.objects.get_current().domain
    256     'example.com'
    257     >>> 'http://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())
    258     'http://example.com/mymodel/objects/3/'
    259264
    260265Caching the current ``Site`` object
    261266===================================
    fallback when the database-backed sites framework is not available.  
    437442
    438443        Sets the ``name`` and ``domain`` attributes to the value of
    439444        :meth:`~django.http.HttpRequest.get_host`.
    440        
     445
    441446
    442447A :class:`~django.contrib.sites.models.RequestSite` object has a similar
    443448interface to a normal :class:`~django.contrib.sites.models.Site` object, except
  • tests/regressiontests/sites_framework/tests.py

    diff --git a/tests/regressiontests/sites_framework/tests.py b/tests/regressiontests/sites_framework/tests.py
    index 8e664fd..764dac2 100644
    a b from __future__ import absolute_import  
    22
    33from django.conf import settings
    44from django.contrib.sites.models import Site
     5from django.template import Context, Template
    56from django.test import TestCase
    67
    78from .models import (SyndicatedArticle, ExclusiveArticle, CustomArticle,
    from .models import (SyndicatedArticle, ExclusiveArticle, CustomArticle,  
    910
    1011
    1112class SitesFrameworkTestCase(TestCase):
     13    urls = 'regressiontests.sites_framework.urls'
     14
    1215    def setUp(self):
    1316        Site.objects.get_or_create(id=settings.SITE_ID, domain="example.com", name="example.com")
    1417        Site.objects.create(id=settings.SITE_ID+1, domain="example2.com", name="example2.com")
    class SitesFrameworkTestCase(TestCase):  
    3639    def test_invalid_field_type(self):
    3740        article = ConfusedArticle.objects.create(title="More Bad News!", site=settings.SITE_ID)
    3841        self.assertRaises(TypeError, ConfusedArticle.on_site.all)
     42
     43    def test_site_url_tag(self):
     44        site = Site.objects.get(domain='example2.com')
     45        template = Template(
     46            "{% load sites %}"
     47            "{% site_url site 'regressiontests.sites_framework.views.view' %}")
     48        rendered = template.render(Context({'site':site}))
     49        self.assertEquals(rendered, "http://example2.com/lala")
     50
     51    def test_site_url_tag_without_sites_framework_installed(self):
     52        Site._meta.installed = False
     53        self.test_site_url_tag()
     54
     55    def test_site_url_tag_with_https(self):
     56        site = Site.objects.get(domain='example2.com')
     57        template = Template(
     58            "{% load sites %}"
     59            "{% site_url site using https "
     60            "'regressiontests.sites_framework.views.view' %}")
     61        rendered = template.render(Context({'site':site}))
     62        self.assertEquals(rendered, "https://example2.com/lala")
     63
     64    def test_site_url_tag_with_https_without_sites_framework_installed(self):
     65        Site._meta.installed = False
     66        self.test_site_url_tag_with_https()
  • new file tests/regressiontests/sites_framework/urls.py

    diff --git a/tests/regressiontests/sites_framework/urls.py b/tests/regressiontests/sites_framework/urls.py
    new file mode 100644
    index 0000000..4eccd1e
    - +  
     1# coding: utf-8
     2from __future__ import absolute_import, unicode_literals
     3from django.conf.urls import patterns
     4
     5from . import views
     6
     7
     8urlpatterns = patterns('',
     9    # Test urls for testing reverse lookups
     10    (r'^lala$', views.view),
     11)
     12
  • new file tests/regressiontests/sites_framework/views.py

    diff --git a/tests/regressiontests/sites_framework/views.py b/tests/regressiontests/sites_framework/views.py
    new file mode 100644
    index 0000000..2c1e8e8
    - +  
     1def view(request):
     2    pass
Back to Top