Ticket #13559: django-13559.patch

File django-13559.patch, 11.3 KB (added by Joshua Ginsberg <jag@…>, 14 years ago)

Adds context processor, enables by default, updates docs, and implements tests

  • django/conf/global_settings.py

     
    190190# only parameter and returns a dictionary to add to the context.
    191191TEMPLATE_CONTEXT_PROCESSORS = (
    192192    'django.contrib.auth.context_processors.auth',
     193    'django.contrib.sites.context_processors.site',
    193194    'django.core.context_processors.debug',
    194195    'django.core.context_processors.i18n',
    195196    'django.core.context_processors.media',
  • django/contrib/syndication/views.py

     
    133133
    134134        for item in self.__get_dynamic_attr('items', obj):
    135135            if title_tmp is not None:
    136                 title = title_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
     136                title = title_tmp.render(RequestContext(request, {'obj': item}))
    137137            else:
    138138                title = self.__get_dynamic_attr('item_title', item)
    139139            if description_tmp is not None:
    140                 description = description_tmp.render(RequestContext(request, {'obj': item, 'site': current_site}))
     140                description = description_tmp.render(RequestContext(request, {'obj': item}))
    141141            else:
    142142                description = self.__get_dynamic_attr('item_description', item)
    143143            link = add_domain(current_site.domain, self.__get_dynamic_attr('item_link', item))
  • django/contrib/sites/tests/__init__.py

     
     1from django.contrib.sites.tests.basic import BASIC_TESTS
     2from django.contrib.sites.tests.context_processors import ContextProcessorTest
     3from django.contrib.sites.tests.context_processors import RequestSiteContextTest
     4
     5__test__ = {'BASIC_TESTS': BASIC_TESTS}
     6           
     7           
     8 No newline at end of file
  • django/contrib/sites/tests/basic.py

     
    1 """
     1BASIC_TESTS = """
    22>>> from django.contrib.sites.models import Site
    33>>> from django.conf import settings
    44>>> Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
  • django/contrib/sites/tests/urls.py

     
     1from django.conf.urls.defaults import *
     2
     3urlpatterns = patterns('',
     4    (r'^context_processors/$', 'django.views.generic.simple.direct_to_template',
     5     {'template': 'sites/context_processors_test.html'}),
     6)
  • django/contrib/sites/tests/context_processors.py

     
     1import os
     2from django.test import TestCase
     3from django.conf import settings
     4from django.core.handlers.wsgi import WSGIRequest
     5from django.contrib.sites import models as sites
     6
     7class ContextProcessorTest(TestCase):
     8    urls = 'django.contrib.sites.tests.urls'
     9   
     10    def setUp(self):
     11        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
     12        settings.TEMPLATE_DIRS = (
     13            os.path.join(
     14                os.path.dirname(__file__),
     15                'templates'
     16            )
     17        ,)
     18   
     19    def tearDown(self):
     20        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
     21   
     22    def test_context_processor(self):
     23        site_obj = sites.Site.objects.get_current()
     24        response = self.client.get('/context_processors/')
     25        self.assertEqual(response.status_code, 200)
     26        self.assertContains(response, 'site.name: %s' % site_obj.name)
     27        self.assertContains(response, 'site.domain: %s' % site_obj.domain)
     28   
     29class RequestSiteContextTest(TestCase):
     30    urls = 'django.contrib.sites.tests.urls'
     31   
     32    def setUp(self):
     33        self.old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
     34        settings.TEMPLATE_DIRS = (
     35            os.path.join(
     36                os.path.dirname(__file__),
     37                'templates'
     38            )
     39        ,)
     40        self.old_INSTALLED_APPS = settings.INSTALLED_APPS
     41        list_of_apps = list(settings.INSTALLED_APPS)
     42        list_of_apps.remove('django.contrib.sites')
     43        settings.INSTALLED_APPS = tuple(list_of_apps)
     44
     45    def tearDown(self):
     46        settings.TEMPLATE_DIRS = self.old_TEMPLATE_DIRS
     47        settings.INSTALLED_APPS = self.old_INSTALLED_APPS
     48   
     49    def test_context_processor_without_sites_framework(self):
     50        response = self.client.get('/context_processors/',
     51                                   SERVER_NAME='localhost',
     52                                   SERVER_PORT=31337)
     53        site_obj = sites.RequestSite(WSGIRequest(response.request))
     54        self.assertEqual(response.status_code, 200)
     55        self.assertContains(response, 'site.name: %s' % site_obj.name)
     56        self.assertContains(response, 'site.domain: %s' % site_obj.domain)
     57       
     58 No newline at end of file
  • django/contrib/sites/tests/templates/sites/context_processors_test.html

     
     1site.name: {{ site.name }}
     2site.domain: {{ site.domain }}
  • django/contrib/sites/tests.py

     
    1 """
    2 >>> from django.contrib.sites.models import Site
    3 >>> from django.conf import settings
    4 >>> Site(id=settings.SITE_ID, domain="example.com", name="example.com").save()
    5 
    6 # Make sure that get_current() does not return a deleted Site object.
    7 >>> s = Site.objects.get_current()
    8 >>> isinstance(s, Site)
    9 True
    10 
    11 >>> s.delete()
    12 >>> Site.objects.get_current()
    13 Traceback (most recent call last):
    14 ...
    15 DoesNotExist: Site matching query does not exist.
    16 
    17 # After updating a Site object (e.g. via the admin), we shouldn't return a
    18 # bogus value from the SITE_CACHE.
    19 >>> _ = Site.objects.create(id=settings.SITE_ID, domain="example.com", name="example.com")
    20 >>> site = Site.objects.get_current()
    21 >>> site.name
    22 u"example.com"
    23 >>> s2 = Site.objects.get(id=settings.SITE_ID)
    24 >>> s2.name = "Example site"
    25 >>> s2.save()
    26 >>> site = Site.objects.get_current()
    27 >>> site.name
    28 u"Example site"
    29 """
  • django/contrib/sites/context_processors.py

     
     1from django.contrib.sites.models import Site, RequestSite
     2from django.core.exceptions import ImproperlyConfigured
     3from django.db import models
     4
     5def site(request):
     6    """Sets in the present context information about the current site."""
     7    # CurrentSiteManager already handles prevention of spurious database calls
     8    # If the user does not have the Sites framework installed, for template
     9    # purposes, which will be read-only, a RequestSite object is an appropriate
     10    # fallback.
     11   
     12    try:
     13        site_app = models.get_app('sites')
     14        site_obj = Site.objects.get_current()
     15    except ImproperlyConfigured:
     16        site_obj = RequestSite(request)
     17    return {'site': site_obj}
  • django/contrib/auth/views.py

     
    6262    return render_to_response(template_name, {
    6363        'form': form,
    6464        redirect_field_name: redirect_to,
    65         'site': current_site,
    6665        'site_name': current_site.name,
    6766    }, context_instance=RequestContext(request))
    6867
  • docs/ref/contrib/sites.txt

     
    185185lawrence.com alerts." On LJWorld.com, the e-mail has the subject "Thanks for
    186186subscribing to LJWorld.com alerts." Same goes for the e-mail's message body.
    187187
    188 Note that an even more flexible (but more heavyweight) way of doing this would
    189 be to use Django's template system. Assuming Lawrence.com and LJWorld.com have
    190 different template directories (:setting:`TEMPLATE_DIRS`), you could simply farm out
    191 to the template system like so::
     188The current Site object is made available in the
     189:ref:`template context <ref-templates-api>` when you use
     190:class:`~django.template.context.RequestContext` and when your
     191:setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
     192``"django.contrib.sites.context_processors.site"``, which is default.
    192193
     194Using template context, an even more flexible (but more heavyweight) way of
     195sending email-notifications would be to use Django's template system::
     196
    193197    from django.core.mail import send_mail
    194     from django.template import loader, Context
     198    from django.template import loader, RequestContext
    195199
    196200    def register_for_newsletter(request):
    197201        # Check form values, etc., and subscribe the user.
    198202        # ...
    199203
    200         subject = loader.get_template('alerts/subject.txt').render(Context({}))
    201         message = loader.get_template('alerts/message.txt').render(Context({}))
     204        subject_template = loader.get_template('alerts/subject.txt')
     205        subject = subject_template.render(RequestContext(request, {}))
     206        message_template = loader.get_template('alerts/message.txt')
     207        message = message_template.render(RequestContext(request, {}))
    202208        send_mail(subject, message, 'editor@ljworld.com', [user.email])
    203209
    204210        # ...
    205211
    206212In this case, you'd have to create :file:`subject.txt` and :file:`message.txt` template
    207 files for both the LJWorld.com and Lawrence.com template directories. That
     213files that include ``{{ site.name }}`` and ``{{ site.domain }}``. That
    208214gives you more flexibility, but it's also more complex.
    209215
    210216It's a good idea to exploit the :class:`~django.contrib.sites.models.Site`
     
    358364  :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware`
    359365  checks the current :setting:`SITE_ID` in retrieving flatpages to display.
    360366
    361 * In the :mod:`syndication framework <django.contrib.syndication>`, the
    362   templates for ``title`` and ``description`` automatically have access to a
    363   variable ``{{ site }}``, which is the
    364   :class:`~django.contrib.sites.models.Site` object representing the current
    365   site. Also, the hook for providing item URLs will use the ``domain`` from
     367* In the :mod:`syndication framework <django.contrib.syndication>`, the
     368  hook for providing item URLs will use the ``domain`` from
    366369  the current :class:`~django.contrib.sites.models.Site` object if you don't
    367370  specify a fully-qualified domain.
    368371
Back to Top