diff options
-rw-r--r-- | app/posts/templates/posts/guide_by_topic.html | 39 | ||||
-rw-r--r-- | app/posts/urls/guide_urls.py | 6 | ||||
-rw-r--r-- | app/posts/views/guide_views.py | 15 | ||||
-rw-r--r-- | app/taxonomy/admin.py | 3 | ||||
-rw-r--r-- | app/taxonomy/migrations/0005_category_description.py | 18 | ||||
-rw-r--r-- | app/taxonomy/migrations/0006_auto_20210107_1611.py | 33 | ||||
-rw-r--r-- | app/taxonomy/models.py | 13 |
7 files changed, 126 insertions, 1 deletions
diff --git a/app/posts/templates/posts/guide_by_topic.html b/app/posts/templates/posts/guide_by_topic.html new file mode 100644 index 0000000..625ac5e --- /dev/null +++ b/app/posts/templates/posts/guide_by_topic.html @@ -0,0 +1,39 @@ +{% extends 'base.html' %} +{% load typogrify_tags %} +{% load html5_datetime %} +{% load pagination_tags %} +{% block pagetitle %}Guides, tutorials, tips, and tricks to improve your {{topic}}.{% endblock %} +{% block metadescription %}Guides for fellow travelers: tools, tips, and tricks to make life on the road in an RV or Van easier and more enjoyable.{% endblock %} + +{% block primary %}<ul class="bl" id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> + <li><a href="/" title="luxagraf homepage" itemprop="url"><span itemprop="title">Home</span></a> → </li> + <li><a href="/guides/" title="luxagraf guides" itemprop="url"><span itemprop="title">Guides</span></a> → </li> + <li itemprop="title">{{topic}}</li> + </ul> + <main role="main" id="guide-archive" class="essay-archive guide-archive archive-list"> + <div class="essay-intro"> + <h2>{{topic}} Guides</h2> + <h3>{{topic.description|safe|smartypants|widont}}</h3> + {{topic.intro_html|safe|smartypants|widont}} + </div> + {% autopaginate object_list 30 %} + <ul class="fancy-archive-list">{% for object in object_list %} + <li class="h-entry hentry" itemscope itemType="http://schema.org/Article"> + <a href="{{object.get_absolute_url}}" class="u-url"> + <div class="circle-img-wrapper"><img src="{{object.featured_image.get_thumbnail_url}}" alt="{{object.featured_image.alt}}" class="u-photo" /></div> + <span class="date dt-published">{{object.pub_date|date:"F d, Y"}}</span> + <a href="{{object.get_absolute_url}}"> + <h2>{{object.title|safe|smartypants|widont}}</h2> + {% if object.subtitle %}<h3 class="p-summary">{{object.subtitle|safe|smartypants|widont}}</h3>{%endif%} + </a> + {% if object.location %}<h4 class="p-location h-adr post-location" itemprop="geo" itemscope itemtype="http://data-vocabulary.org/Geo"> + <span class="p-locality">{{object.location.name|smartypants|safe}}</span>, + <span class="p-region">{{object.location.state_name}}</span>, + <span class="p-country-name">{{object.location.country_name}}</span> + <data class="p-latitude" value="{{object.latitude}}"></data> + <data class="p-longitude" value="{{object.longitude}}"></data> + </h4>{% endif %} + </li> + {%endfor%}</ul> + </main> +{%endblock%} diff --git a/app/posts/urls/guide_urls.py b/app/posts/urls/guide_urls.py index e0a2210..8927034 100644 --- a/app/posts/urls/guide_urls.py +++ b/app/posts/urls/guide_urls.py @@ -17,6 +17,12 @@ urlpatterns = [ #path(r'field-tests/', include('posts.urls', namespace='review-list')), #path(r'review/', include('posts.review_urls')), re_path(r'^review/$', RedirectView.as_view(url='/guides/')), + path( + r'<str:topic>/', + views.GuideTopicListView.as_view(), + {'page':1}, + name="guides-by-topic" + ), #path( # r'<str:slug>', # views.EntryDetailView.as_view(), diff --git a/app/posts/views/guide_views.py b/app/posts/views/guide_views.py index 3d7ca86..d9503db 100644 --- a/app/posts/views/guide_views.py +++ b/app/posts/views/guide_views.py @@ -21,6 +21,21 @@ class GuideListView(PaginatedListView): queryset = super(GuideListView, self).get_queryset() return queryset.filter(status__exact=1).filter(post_type__in=[PostType.REVIEW,PostType.FIELD_TEST]).order_by('-pub_date').prefetch_related('location').prefetch_related('featured_image') +class GuideTopicListView(GuideListView): + """ + Return a list of Posts by topic in reverse chronological order + """ + template_name = "posts/guide_by_topic.html" + + def get_queryset(self): + queryset = super(GuideTopicListView, self).get_queryset() + topic = Category.objects.get(slug=self.kwargs['topic']) + return queryset.filter(status__exact=1).filter(topics__slug=topic).order_by('-pub_date').prefetch_related('featured_image') + + def get_context_data(self, **kwargs): + context = super(GuideTopicListView, self).get_context_data(**kwargs) + context['topic'] = Category.objects.get(slug=self.kwargs['topic']) + return context class ReviewsListView(GuideListView): template_name = "posts/post.html" diff --git a/app/taxonomy/admin.py b/app/taxonomy/admin.py index 783584e..45e4e26 100644 --- a/app/taxonomy/admin.py +++ b/app/taxonomy/admin.py @@ -14,6 +14,9 @@ class CategoryAdmin(admin.ModelAdmin): 'name', 'color_rgb', 'slug', + "pluralized_name", + "description", + "intro_markdown", ), 'classes': ( 'show', diff --git a/app/taxonomy/migrations/0005_category_description.py b/app/taxonomy/migrations/0005_category_description.py new file mode 100644 index 0000000..bd2ec0b --- /dev/null +++ b/app/taxonomy/migrations/0005_category_description.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1 on 2021-01-07 15:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('taxonomy', '0004_auto_20201114_0757'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='description', + field=models.CharField(max_length=300, null=True), + ), + ] diff --git a/app/taxonomy/migrations/0006_auto_20210107_1611.py b/app/taxonomy/migrations/0006_auto_20210107_1611.py new file mode 100644 index 0000000..1a875f7 --- /dev/null +++ b/app/taxonomy/migrations/0006_auto_20210107_1611.py @@ -0,0 +1,33 @@ +# Generated by Django 3.1 on 2021-01-07 16:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('taxonomy', '0005_category_description'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='intro_html', + field=models.TextField(blank=True, null=True), + ), + migrations.AddField( + model_name='category', + name='intro_markdown', + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name='category', + name='description', + field=models.CharField(blank=True, max_length=300, null=True), + ), + migrations.AlterField( + model_name='category', + name='pluralized_name', + field=models.CharField(blank=True, max_length=60, null=True), + ), + ] diff --git a/app/taxonomy/models.py b/app/taxonomy/models.py index 4db3294..6cc1769 100644 --- a/app/taxonomy/models.py +++ b/app/taxonomy/models.py @@ -3,6 +3,8 @@ from django.urls import reverse from django.utils.translation import ugettext_lazy as _ from django.utils.functional import cached_property +from utils.util import markdown_to_html + from taggit.models import TagBase, GenericTaggedItemBase @@ -27,7 +29,10 @@ class TaggedItems(GenericTaggedItemBase): class Category(models.Model): """ Generic model for Categories """ name = models.CharField(max_length=250) - pluralized_name = models.CharField(max_length=60, null=True) + pluralized_name = models.CharField(max_length=60, null=True, blank=True) + description = models.CharField(max_length=300, null=True, blank=True) + intro_markdown = models.TextField(null=True, blank=True) + intro_html = models.TextField(null=True, blank=True) slug = models.SlugField(blank=True) color_rgb = models.CharField(max_length=20, blank=True) date_created = models.DateTimeField(blank=True, auto_now_add=True, editable=False) @@ -42,3 +47,9 @@ class Category(models.Model): def get_absolute_url(self): return reverse("taxonomy:cat-detail", kwargs={"slug": self.slug}) + + + def save(self, *args, **kwargs): + if self.intro_markdown: + self.intro_html = markdown_to_html(self.intro_markdown) + super(Category, self).save(*args, **kwargs) |