Switched to class based views for blog
This commit is contained in:
parent
db0c031664
commit
c1f6d3f22e
|
@ -17,7 +17,7 @@ from mhackspace.subscriptions import views as subscription
|
||||||
from mhackspace.base.feeds import LatestEntriesFeed
|
from mhackspace.base.feeds import LatestEntriesFeed
|
||||||
from mhackspace.blog.feeds import BlogFeed, BlogCategoryFeed
|
from mhackspace.blog.feeds import BlogFeed, BlogCategoryFeed
|
||||||
from mhackspace.base.views import markdown_uploader
|
from mhackspace.base.views import markdown_uploader
|
||||||
from mhackspace.blog.views import blog, PostViewSet, CategoryViewSet
|
from mhackspace.blog.views import PostViewSet, CategoryViewSet, BlogPost, PostList
|
||||||
from mhackspace.blog.sitemaps import PostSitemap, CategorySitemap
|
from mhackspace.blog.sitemaps import PostSitemap, CategorySitemap
|
||||||
from mhackspace.feeds.views import FeedViewSet, ArticleViewSet
|
from mhackspace.feeds.views import FeedViewSet, ArticleViewSet
|
||||||
|
|
||||||
|
@ -46,10 +46,10 @@ urlpatterns = [
|
||||||
r'^api/uploader/$',
|
r'^api/uploader/$',
|
||||||
markdown_uploader, name='markdown_uploader_page'
|
markdown_uploader, name='markdown_uploader_page'
|
||||||
),
|
),
|
||||||
url(r'^blog/$', blog, name='blog'),
|
url(r'^blog/$', PostList.as_view(), name='blog'),
|
||||||
url(r'^blog/rss/$', BlogFeed()),
|
url(r'^blog/rss/$', BlogFeed(), name='blog-rss'),
|
||||||
url(r'^blog/(?P<slug>[0-9A-Za-z_\-]+)/$', blog, name='blog-item'),
|
url(r'^blog/(?P<slug>[0-9A-Za-z_\-]+)/$', BlogPost.as_view(), name='blog-item'),
|
||||||
url(r'^blog/category/(?P<category>[0-9A-Za-z_\-]+)/$', blog, name='blog-category'),
|
url(r'^blog/category/(?P<category>[0-9A-Za-z_\-]+)/$', PostList.as_view(), name='blog-category'),
|
||||||
url(r'^blog/category/(?P<category>[0-9A-Za-z_\-]+)/rss/$', BlogCategoryFeed(), name='blog-category-feed'),
|
url(r'^blog/category/(?P<category>[0-9A-Za-z_\-]+)/rss/$', BlogCategoryFeed(), name='blog-category-feed'),
|
||||||
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
|
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},
|
||||||
name='django.contrib.sitemaps.views.sitemap'),
|
name='django.contrib.sitemaps.views.sitemap'),
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
from mhackspace.blog.models import Category
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
|
@register.inclusion_tag('blog/sidebar.html')
|
||||||
|
def sidebar():
|
||||||
|
return {'categories': Category.objects.all()}
|
|
@ -1,7 +1,6 @@
|
||||||
from django.http import Http404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.shortcuts import render
|
|
||||||
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.views.generic import ListView, DetailView
|
||||||
from rest_framework import viewsets
|
from rest_framework import viewsets
|
||||||
from django_filters import DateTimeFromToRangeFilter
|
from django_filters import DateTimeFromToRangeFilter
|
||||||
from django_filters.rest_framework import FilterSet
|
from django_filters.rest_framework import FilterSet
|
||||||
|
@ -10,31 +9,20 @@ from mhackspace.blog.models import Post, Category
|
||||||
from mhackspace.blog.serializers import PostSerializer, CategorySerializer
|
from mhackspace.blog.serializers import PostSerializer, CategorySerializer
|
||||||
|
|
||||||
|
|
||||||
def blog(request, slug=None, category=None):
|
class BlogPost(DetailView):
|
||||||
categories = Category.objects.all()
|
context_object_name = 'post'
|
||||||
|
queryset = Post.objects.filter(active=True, members_only=False) # todo: check member status here
|
||||||
|
|
||||||
if slug is not None:
|
|
||||||
blog_posts = Post.objects.filter(active=True, slug=slug)
|
|
||||||
elif category is not None:
|
|
||||||
category = Category.objects.filter(slug=category)
|
|
||||||
blog_posts = Post.objects.filter(active=True, categories=category, published_date__lte=timezone.now())
|
|
||||||
else:
|
|
||||||
blog_posts = Post.objects.filter(active=True, published_date__lte=timezone.now())
|
|
||||||
|
|
||||||
if len(blog_posts) < 1:
|
class PostList(ListView):
|
||||||
raise Http404("No posts found")
|
context_object_name = 'posts'
|
||||||
|
paginate_by = 5
|
||||||
|
|
||||||
paginator = Paginator(blog_posts, 5)
|
def get_queryset(self):
|
||||||
|
if 'category' in self.kwargs:
|
||||||
page = request.GET.get('page')
|
self.category = get_object_or_404(Category, slug=self.kwargs['category'])
|
||||||
try:
|
return Post.objects.filter(active=True, categories=self.category, published_date__lte=timezone.now(), members_only=False)
|
||||||
posts = paginator.page(page)
|
return Post.objects.filter(active=True, published_date__lte=timezone.now(), members_only=False)
|
||||||
except PageNotAnInteger:
|
|
||||||
posts = paginator.page(1)
|
|
||||||
except EmptyPage:
|
|
||||||
posts = paginator.page(paginator.num_pages)
|
|
||||||
|
|
||||||
return render(request, 'blog/posts.html', {'posts': posts, 'categories': categories})
|
|
||||||
|
|
||||||
|
|
||||||
class PostFilter(FilterSet):
|
class PostFilter(FilterSet):
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
{% if is_paginated == True %}
|
||||||
|
<nav aria-label="Blog Posts">
|
||||||
|
<ul class="pagination">
|
||||||
|
{% if page_obj.has_previous %}
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="?page={{ page_obj.previous_page_number }}" tabindex="-1">Previous</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link" href="?page={{ page_obj.number }}" tabindex="-1">Previous</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
{% for page in paginator.page_range %}
|
||||||
|
{{ pages }}
|
||||||
|
<li class="page-item {% if page == page_obj.number %}active{% endif %}">
|
||||||
|
<a class="page-link" href="?page={{ page }}">{{ page }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
{% if page_obj.has_next %}
|
||||||
|
<li class="page-item">
|
||||||
|
<a class="page-link" href="?page={{ page_obj.next_page_number }}" tabindex="-1">Next</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="page-item disabled">
|
||||||
|
<a class="page-link" href="?page={{ page_obj.number }}" tabindex="-1">Previous</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
{% endif %}
|
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="text-muted">
|
||||||
|
Published:
|
||||||
|
<span itemprop="datePublished" content="{{ post.published_date|date:"c" }}">
|
||||||
|
({{ post.published_date }})
|
||||||
|
</span>
|
||||||
|
{% if post.updated_date != post.published_date %}
|
||||||
|
Updated:
|
||||||
|
<span itemprop="dateModified" content="{{ post.updated_date|date:"c" }}">
|
||||||
|
{{ post.updated_date }}
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load dractags blog %}
|
||||||
|
{% block title %}{{ post.title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<article itemscope itemtype="http://schema.org/Article">
|
||||||
|
<a href="{{ post.get_absolute_url }}"><h1 itemprop="name">{{ post.title }}</h1></a>
|
||||||
|
{% include "blog/post_date.html" %}
|
||||||
|
{% if post.image %}
|
||||||
|
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
|
||||||
|
<img src="{{ post.image.url }}" class="img-fluid"/>
|
||||||
|
<meta itemprop="url" content="{{ post.image.url }}">
|
||||||
|
<meta itemprop="width" content="{{ post.image.width }}">
|
||||||
|
<meta itemprop="height" content="{{ post.image.height }}">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<span itemprop="articleBody">{{ post.description|safe_markdown }}</span>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
{% sidebar %}
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% load dractags blog %}
|
||||||
|
{% block title %}Blog Posts{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-8">
|
||||||
|
{% for post in posts %}
|
||||||
|
<article itemscope itemtype="http://schema.org/Article">
|
||||||
|
<a href="{{ post.get_absolute_url }}"><h3 itemprop="name">{{ post.title }}</h3></a>
|
||||||
|
{% include "blog/post_date.html" %}
|
||||||
|
{% if post.image %}
|
||||||
|
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
|
||||||
|
<img src="{{ post.image.url }}" class="img-fluid"/>
|
||||||
|
<meta itemprop="url" content="{{ post.image.url }}">
|
||||||
|
<meta itemprop="width" content="{{ post.image.width }}">
|
||||||
|
<meta itemprop="height" content="{{ post.image.height }}">
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<span itemprop="articleBody">{{ post.description|safe_markdown|striptags|truncatewords:30 }}</span>
|
||||||
|
</article>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% include "base/pagination.html" %}
|
||||||
|
</div>
|
||||||
|
{% sidebar %}
|
||||||
|
</div>
|
||||||
|
{% endblock content %}
|
|
@ -1,55 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
{% load dractags %}
|
|
||||||
{% block title %}Blog Posts{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-8">
|
|
||||||
{% for post in posts %}
|
|
||||||
<article itemscope itemtype="http://schema.org/Article">
|
|
||||||
<a href="{{ post.get_absolute_url }}"><h1 itemprop="name">{{ post.title }}</h1></a>
|
|
||||||
<div>
|
|
||||||
Published: <span itemprop="datePublished" content="{{ post.published_date|date:"c" }}">{{ post.published_date }}</span>
|
|
||||||
{% if post.updated_date != post.published_date %}
|
|
||||||
Updated: <span itemprop="dateModified" content="{{ post.updated_date|date:"c" }}">{{ post.updated_date }}</span>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% if post.image %}
|
|
||||||
<div itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
|
|
||||||
<img src="{{ post.image.url }}" class="img-fluid"/>
|
|
||||||
<meta itemprop="url" content="{{ post.image.url }}">
|
|
||||||
<meta itemprop="width" content="{{ post.image.width }}">
|
|
||||||
<meta itemprop="height" content="{{ post.image.height }}">
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<span itemprop="articleBody">{{ post.description|safe_markdown }}</span>
|
|
||||||
</article>
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if posts.num_pages > 1 %}
|
|
||||||
<div class="pagination">
|
|
||||||
<span class="step-links">
|
|
||||||
{% if contacts.has_previous %}
|
|
||||||
<a href="?page={{ posts.previous_page_number }}">previous</a>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<span class="current">
|
|
||||||
Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{% if contacts.has_next %}
|
|
||||||
<a href="?page={{ posts.next_page_number }}">next</a>
|
|
||||||
{% endif %}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-3 offset-sm-1">
|
|
||||||
<ul class="list-group">
|
|
||||||
{% for category in categories %}
|
|
||||||
<a href="{{ category.get_absolute_url }}" class="list-group-item list-group-item-action">{{ category.name }}</a>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock content %}
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div class="col-sm-3 offset-sm-1">
|
||||||
|
<h2>Categories</h2>
|
||||||
|
<ul class="list-group">
|
||||||
|
<a href="{% url "blog" %}" class="list-group-item list-group-item-action">All Articles</a>
|
||||||
|
{% for category in categories %}
|
||||||
|
<a href="{{ category.get_absolute_url }}" class="list-group-item list-group-item-action">{{ category.name }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<a href="{% url "blog-rss" %}"><i class="fa fa-rss-square"> RSS Feed</i></a>
|
||||||
|
</div>
|
Loading…
Reference in New Issue