July 21, 2018, 8:36 p.m. wschaub
I wanted to make a private blog post so I could share a future blog post with someone for review before publishing. Turns out that the implementation of this blog software prevents the page privacy settings from working out of the box.
I would like to say I figured this out myself but all of the credit goes to Mattwestcott on the wagtailcms slack server.
As far as I understand it the implementation of the BlogPost model changes the URL routing for a PostPage which renders the privacy checks useless.
The following diff shows the changes I made based on his help.
The first change is to the BlogPage model itself. I'm not 100% sure what the hook is doing but it does seem to remove the prepended date for private pages which allows the protection to kick in which is what I want.
@@ -13,6 +13,7 @@ from django.utils.dateformat import DateFormat from django.utils.formats import date_format import wagtail +from wagtail.core import hooks from wagtail.core.models import Page from wagtail.core.fields import RichTextField @@ -58,7 +59,7 @@ class BlogPage(RoutablePageMixin, Page): return context def get_posts(self): - return PostPage.objects.descendant_of(self).live().order_by('-date') + return PostPage.objects.descendant_of(self).live().public().order_by('-date') @route(r'^(\d{4})/$') @route(r'^(\d{4})/(\d{2})/$') @@ -81,6 +82,10 @@ class BlogPage(RoutablePageMixin, Page): post_page = self.get_posts().filter(slug=slug).first() if not post_page: raise Http404 + for fn in hooks.get_hooks('before_serve_page'): + result = fn(post_page, request, args, kwargs) + if isinstance(result, HttpResponse): + return result return Page.serve(post_page, request, *args, **kwargs) @route(r'^tag/(?P<tag>[-\w]+)/$')
The for fn in hooks.get_hooks(... bit is what was suggested. The change return PostPage.objects.descendant_of(self).live().public().order_by('-date') in the get_posts method is my change to be sure private pages do not show up in the Blog index. I could probably fix this at the template layer instead and I intend to look into that later.
Now on to a few other changes that I've added:
This is the suggested template from the wagtail docs nothing special we refer back to it in settings.py later on.
+++ b/longearsforlife/blog/templates/blog/password_required.html @@ -0,0 +1,26 @@ +<!DOCTYPE HTML> +<html> + <head> + <title>Password required</title> + </head> + <body> + <h1>Password required</h1> + <p>You need a password to access this page.</p> + <form action="{{ action_url }}" method="POST"> + {% csrf_token %} + + {{ form.non_field_errors }} + + <div> + {{ form.password.errors }} + {{ form.password.label_tag }} + {{ form.password }} + </div> + + {% for field in form.hidden_fields %} + {{ field }} + {% endfor %} + <input type="submit" value="Continue" /> + </form> + </body> +</html>
we point to the password required template here.
@@ -151,3 +151,4 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'static') MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') +PASSWORD_REQUIRED_TEMPLATE = 'blog/password_required.html'
I'm pretty sure I need to add the login urls to urls.py so we did that.
@@ -29,6 +29,7 @@ urlpatterns = [ url(r'^cms/', include(wagtailadmin_urls)), url(r'^documents/', include(wagtaildocs_urls)), url(r'^blog/', include(wagtail_urls)), + url(r'^', include('django.contrib.auth.urls')), url(r'^$', redirect_to_blog, name='root') ]