Last active
August 29, 2015 13:57
-
-
Save kaedroho/9537074 to your computer and use it in GitHub Desktop.
PR144 description
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
# This gist describes the changes I have made in PR #144 | |
# Add AJAX template (1cb7dcb0b29bd2d20016515b922cfc9ca8de9be4) | |
# ============================================================ | |
# The first of my changes is allowing ajax templates to be specified as an attribute to the page class. | |
# I created a method called get_template() which finds the best template to use for a particular request. | |
# This function is overridable so a developer can have a more advanced configuration if they want. | |
# If this is not filled out, the ajax template will fall back to the standard template. | |
# This addresses a very common pattern in the RCA source. | |
# Example: https://github.com/torchbox/verdant-rca/blob/master/django-verdant/rca/models.py#L2473-L2482 | |
# Heres an example of how this will be used (quite obvious really): | |
class BlogIndex(Page): | |
... | |
ajax_template = 'blog_listing.html' | |
# Add get_context method (16db4fdc7e47a04389c195124ce471ff83109adb) | |
# ================================================================= | |
# Instead of overriding the serve method, I think in most cases | |
# developers should really be overriding a get_context method. | |
# The one major advantage this change brings is that it makes it much easier for a | |
# subclass to extend a superclasses context variables | |
# Heres an example | |
class Restraunt(Page): | |
def get_context(self, request): | |
# Get context of superclass | |
context = super(Restraunt, self).get_context(request) | |
# Add some context variables to the restraunt template | |
context['foo'] = request.GET.get('foo', None) | |
context['bar'] = "Bar" | |
return context | |
class ItalianRestraunt(Restraunt): | |
def get_context(self, request): | |
# Get context of restraunt | |
context = super(Restraunt, self).get_context(request) | |
# Add a variable specific to italian restraunts | |
context['serves_pizza'] = True | |
return context | |
# Add process_request method (7b88d2c1bf4f3ea33c865cf7f23146479e8fa0fa) | |
# ===================================================================== | |
# This new method gets called at every step in the URL resolution. | |
# For example, if somebody requested "/blog/hello-world/" the process_request | |
# method will be run on the pages in the following order: | |
# - The root page | |
# - The blog index at "/blog/" | |
# - The blog entry at "/blog/hello-world/" (where it returns a response) | |
# It works in a very similar way to Django middleware works (hence the name) -- the | |
# first one of these pages to return a response will be the page thats rendered. | |
# This method is only called when the page is live. | |
# This change gives two (pretty small, but I think warranted) advantages: | |
# 1. It provides a place where a page can add data to a request object for a subpage to read. | |
# This is beneficial in cases where you want to reliably work out which index page a blog post is in. | |
class BlogIndex(Page): | |
def process_request(self, request, path): | |
# Add reference to blog index to the request object | |
request.blog_index = self | |
return super(BlogIndex, self).process_request(request, path) | |
class BlogEntry(Page): | |
def get_context(self, request): | |
context = super(BlogEntry, self).get_context() | |
# Add blog index to context | |
context['blog_index'] = request.blog_index | |
return context | |
# 2. (I think) Calling process_request directly is better than calling route directly. | |
# I think this because process_request will either return a response for the current page or None | |
# which makes generating page previews and testing much easier when custom routing is being used. | |
# Also, overriding route will require the developer to remember to put an "if page.live == True" check | |
# into their code. | |
# Added SuperPage class (2da651abf05091e5b0cccfbd2cfbb770649fd874) | |
# ================================================================ | |
# I'm not decided on the name yet, or on whether or not this should be in the main Page class. | |
# This class allows a developer to embed a urlconf into a page. This makes custom routing much easier. | |
# It includes methods for both resolving and reversing urls on a page object. | |
# Heres an example of how subpages are configured on "SuperPages": | |
class TestSuperPage(SuperPage): | |
def get_subpage_urls(self): | |
return [ | |
self.subpage_url(r'^$', self.serve, name='main'), | |
self.subpage_url(r'^blog/$', self.blog_index, name='blog_index'), | |
self.subpage_url(r'^blog/(\w+)$', self.blog_entry, name='blog_entry'), | |
] | |
def blog_index(self, request): | |
return render(request, 'blog_index.html') | |
def blog_entry(self, request, name): | |
blog = get_object_or_404(BlogEntry, name=name) | |
return render(request, 'blog_entry.html', { | |
'blog': blog, | |
}) | |
# You can reverse urls on SuperPages by using the "reverse_subpage" method. | |
# For example, lets say we created an instance of the above class at "/test/" | |
>>> page.reverse_subpage('main') | |
'/test/' | |
>>> page.reverse_subpage('blog_index') | |
'/test/blog/' | |
>>> page.reverse_subpage('blog_index', 'hello') | |
'/test/blog/hello/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment