diff options
Diffstat (limited to 'app/locations')
-rw-r--r-- | app/locations/admin.py | 3 | ||||
-rw-r--r-- | app/locations/migrations/0025_auto_20191230_0738.py | 23 | ||||
-rw-r--r-- | app/locations/migrations/0026_walk_subtitle.py | 18 | ||||
-rw-r--r-- | app/locations/models.py | 11 | ||||
-rw-r--r-- | app/locations/templates/locations/walk_detail.html | 76 | ||||
-rw-r--r-- | app/locations/templates/locations/walk_list.html | 40 | ||||
-rw-r--r-- | app/locations/urls.py | 5 | ||||
-rw-r--r-- | app/locations/views.py | 26 | ||||
-rw-r--r-- | app/locations/walk_urls.py | 24 |
9 files changed, 222 insertions, 4 deletions
diff --git a/app/locations/admin.py b/app/locations/admin.py index 0e78948..4beca5b 100644 --- a/app/locations/admin.py +++ b/app/locations/admin.py @@ -300,9 +300,10 @@ class WalkAdmin(OLAdminBase): ('Region', { 'fields': ( ('title', 'rating'), + 'subtitle', 'body_markdown', ('date_walked', 'slug'), - 'distance', + ('distance', 'duration'), 'gpx_file', 'point', ), diff --git a/app/locations/migrations/0025_auto_20191230_0738.py b/app/locations/migrations/0025_auto_20191230_0738.py new file mode 100644 index 0000000..3dd9093 --- /dev/null +++ b/app/locations/migrations/0025_auto_20191230_0738.py @@ -0,0 +1,23 @@ +# Generated by Django 2.1.2 on 2019-12-30 07:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('locations', '0024_auto_20191229_1817'), + ] + + operations = [ + migrations.AddField( + model_name='walk', + name='duration', + field=models.DecimalField(decimal_places=0, help_text='in minutes', max_digits=3, null=True), + ), + migrations.AlterField( + model_name='walk', + name='distance', + field=models.DecimalField(decimal_places=2, max_digits=3, null=True), + ), + ] diff --git a/app/locations/migrations/0026_walk_subtitle.py b/app/locations/migrations/0026_walk_subtitle.py new file mode 100644 index 0000000..e5aae3f --- /dev/null +++ b/app/locations/migrations/0026_walk_subtitle.py @@ -0,0 +1,18 @@ +# Generated by Django 2.1.2 on 2020-01-22 10:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('locations', '0025_auto_20191230_0738'), + ] + + operations = [ + migrations.AddField( + model_name='walk', + name='subtitle', + field=models.CharField(blank=True, max_length=200), + ), + ] diff --git a/app/locations/models.py b/app/locations/models.py index e9eb047..6f598b2 100644 --- a/app/locations/models.py +++ b/app/locations/models.py @@ -469,6 +469,7 @@ def parse_gpx(gpx_obj, gpx_data): class Walk(models.Model): title = models.CharField(max_length=300) + subtitle = models.CharField(max_length=200, blank=True) slug = models.SlugField() body_markdown = models.TextField() body_html = models.TextField(blank=True) @@ -484,11 +485,19 @@ class Walk(models.Model): ('5', "5 Stars"), ) rating = models.CharField(max_length=1, choices=RATINGS, null=True, blank=True) - distance = models.DecimalField(max_digits=3, decimal_places=1, null=True) + distance = models.DecimalField(max_digits=3, decimal_places=2, null=True) + duration = models.DecimalField(max_digits=3, decimal_places=0, null=True, help_text="in minutes") def __str_(self): return self.title + def get_rating(self): + return int(self.rating) + + @property + def ratings_range(cls): + return range(1, 6) + def save(self, *args, **kwargs): created = self.pk is None if not created: diff --git a/app/locations/templates/locations/walk_detail.html b/app/locations/templates/locations/walk_detail.html new file mode 100644 index 0000000..f36a507 --- /dev/null +++ b/app/locations/templates/locations/walk_detail.html @@ -0,0 +1,76 @@ +{% extends 'base.html' %} +{% load typogrify_tags %} +{%block bodyid%}class="detail"{%endblock%} +{% block primary %}<ul class="bl crumbs" 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="/walks/" itemprop="url"><span itemprop="title">Walks</span></a> →</li> + <li><a href="/walks/{{object.pub_date|date:"Y"}}/">{{object.date_walked|date:"Y"}}</a> →</li> + <li>{{object.title}}</li> + </ul> + <main> + <article class="h-entry hentry {% with object.get_template_name_display as t %}{%if t == "double" or t == "double-dark" %} post--article--double{%endif%}{%endwith%}" itemscope itemType="http://schema.org/BlogPosting"> + <header id="header" class="post-header {% with object.get_template_name_display as t %}{%if t == "double" or t == "double-dark" %}post--header--double{%endif%}{%endwith%}"> + <h1 class="p-name entry-title post-title" itemprop="headline">{%if object.template_name == 1 or object.template_name == 3 %}{{object.title|smartypants|safe}}{%else%}{{object.title|smartypants|safe}}{%endif%}</h1> + {% if object.subtitle %}<h2 class="post-subtitle">{{object.subtitle|smartypants|safe}}</h2>{%endif%} + <div class="post-linewrapper"> + {% if object.location %}<div class="p-location h-adr adr post-location" itemprop="contentLocation" itemscope itemtype="http://schema.org/Place"> + <h3 class="h-adr" itemprop="address" itemscope itemtype="http://schema.org/PostalAddress">{% if object.location.country_name == "United States" %}<span class="p-locality locality" itemprop="addressLocality">{{object.location.name|smartypants|safe}}</span>, <a class="p-region region" href="/jrnl/united-states/" title="travel writing from the United States">{{object.location.state_name|safe}}</a>, <span class="p-country-name" itemprop="addressCountry">U.S.</span>{%else%}<span class="p-region" itemprop="addressRegion">{{object.location.name|smartypants|safe}}</span>, <a class="p-country-name country-name" href="/jrnl/{{object.location.country_slug}}/" title="travel writing from {{object.location.country_name}}"><span itemprop="addressCountry">{{object.location.country_name|safe}}</span></a>{%endif%}</h3> + </div>{%endif%} + <time class="dt-published published dt-updated post-date" datetime="{{object.date_walked|date:'c'}}" itemprop="datePublished">{{object.date_walked|date:"F"}} <span>{{object.date_walked|date:"j, Y"}}</span></time> + <span class="hide" itemprop="author" itemscope itemtype="http://schema.org/Person">by <a class="p-author h-card" href="/about"><span itemprop="name">Scott Gilbertson</span></a></span> + </div> + </header> + <img src="{{object.get_image_url}}" alt="{{object.title}} map" /> + + <div class="meta-cover"> + <dl class="book-metadata"> + {% if object.distance %}<dt>Distance</dt> + <dd>{{object.distance}} miles</dd>{%endif%} + {% if object.duration%}<dt>Duration</dt> + <dd>{{object.duration}} minutes</dd>{%endif%} + + {% if object.rating %}<dt>Rating</dt><dd class="book-stars"> + {% for i in object.ratings_range %}{% if i <= object.get_rating%}★{%else%}☆{%endif%}{%endfor%}</span></dd>{%endif%} + </dl> + <div class="e-content"> + <h5>Notes</h5> + {{object.body_html|safe|smartypants}} + </div> + + {%if wildlife %}<div class="entry-footer"> + <aside id="wildlife"> + <h3>Fauna and Flora</h3> + {% regroup wildlife by ap.apclass.get_kind_display as wildlife_list %} + <ul> + {% for object_list in wildlife_list %} + <li class="grouper">{{object_list.grouper}}<ul> + {% for object in object_list.list %} + <li>{%if object.ap.body_markdown%}<a href="{% url 'sightings:detail' object.ap.slug %}">{{object}}</a>{%else%}{{object}}{%endif%} </li> + {% endfor %}</ul> + {% endfor %}</ul> + </aside> + {% endif %} + {%if entry_list %} + <aside {% if wildlife %}class="margin-left-none" {%endif%}id="field_notes"> + <h3>Related Posts</h3> + <ul>{% for obj in entry_list %} + <li><a href="{% url 'jrnl:detail' year=obj.pub_date.year month=obj.pub_date|date:"m" slug=obj.slug %}">{{obj}}</a></li> + {% endfor %}</ul> + </aside>{% endif %} + </article> + {% with object.get_next_published as next %} + {% with object.get_previous_published as prev %} + <div class="nav-wrapper"> + <nav id="page-navigation" {%if wildlife or object.field_notes.all or object.books.all %}{%else%}class="page-border-top"{%endif%}> + <ul>{% if prev%} + <li id="prev"><span class="bl">Previous:</span> + <a href="{{ prev.get_absolute_url }}" rel="prev" title=" {{prev.title}}">{{prev.title|safe}}</a> + </li>{%endif%}{% if next%} + <li id="next"><span class="bl">Next:</span> + <a href="{{ next.get_absolute_url }}" rel="next" title=" {{next.title}}">{{next.title|safe}}</a> + </li>{%endif%} + </ul> + </nav>{%endwith%}{%endwith%} + </div> + </main> +{% endblock %} diff --git a/app/locations/templates/locations/walk_list.html b/app/locations/templates/locations/walk_list.html new file mode 100644 index 0000000..28d86ec --- /dev/null +++ b/app/locations/templates/locations/walk_list.html @@ -0,0 +1,40 @@ +{% extends 'base.html' %} +{% load typogrify_tags %} +{% load html5_datetime %} +{% load pagination_tags %} +{% block pagetitle %}Walks.{% endblock %} +{% block metadescription %}{% endblock %} +{% block breadcrumbs %}<ul class="bl" id="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList"> + <li itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"> + <a href="/" title="luxagraf homepage" itemprop="item"> + <span itemprop="title">Home</span> + </a> → + </li> + <li itemprop="title">Walks</li> + </ul>{% endblock %} +{% block primary %}<main role="main" id="essay-archive" class="essay-archive archive-list"> + <div class="essay-intro"> + <h2>Walks</h2> + <h3>Walks, hikes, forays, whatever you wish to call them.</h3> + <p>Walking is [meditation](/meditation), particularly the discursive meditation I practice. So this is not so much a record of physical activity as mental. If you're looking for awesome hikes, there might be some in here, but don't expect details. That's not what I'm interested in recording.<p> + </div> + <h1 class="topic-hed">Walks</h1> + {% 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="{% url 'walks:walk-detail' object.slug %}"> + <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> + </h4>{% endif %} + </li> + {%endfor%}</ul> + </main> +{%endblock%} diff --git a/app/locations/urls.py b/app/locations/urls.py index 5faefc1..ee98b17 100644 --- a/app/locations/urls.py +++ b/app/locations/urls.py @@ -6,6 +6,11 @@ app_name = "locations" urlpatterns = [ path( + r'<str:slug>', + views.WalkDetail.as_view(), + name="walk-detail" + ), + path( r'<str:country>/<str:state>/<str:slug>/', views.LocationDetail.as_view(), name="location-detail" diff --git a/app/locations/views.py b/app/locations/views.py index 3a93c0d..48ecc07 100644 --- a/app/locations/views.py +++ b/app/locations/views.py @@ -8,8 +8,8 @@ from django.db.models import Q from jrnl.models import Entry from projects.shortcuts import render_to_geojson from sightings.models import Sighting - -from .models import Country, Region, Route, Location +from utils.views import PaginatedListView +from .models import Country, Region, Route, Location, Walk def map_list(request): context = { @@ -99,3 +99,25 @@ class LocationDetail(DetailView): Q(location__in=Location.objects.filter(parent=self.get_object())) ).order_by('ap_id', 'ap__apclass__kind').distinct("ap") return context + + +class WalkDetail(DetailView): + model = Walk + + def get_context_data(self, **kwargs): + context = super(WalkDetail, self).get_context_data(**kwargs) + context['entry_list'] = Entry.objects.filter( + Q(location=self.get_object().location) | + Q(location__in=Location.objects.filter(parent=self.get_object().location)) + ) + context['wildlife'] = Sighting.objects.filter( + Q(location=self.get_object().location) | + Q(location__in=Location.objects.filter(parent=self.get_object().location)) + ).order_by('ap_id', 'ap__apclass__kind').distinct("ap") + return context + +class WalkList(PaginatedListView): + """ + Return list of Walks + """ + model = Walk diff --git a/app/locations/walk_urls.py b/app/locations/walk_urls.py new file mode 100644 index 0000000..4019ef6 --- /dev/null +++ b/app/locations/walk_urls.py @@ -0,0 +1,24 @@ +from django.urls import path, re_path + +from . import views + +app_name = "walks" + +urlpatterns = [ + path( + r'<str:slug>', + views.WalkDetail.as_view(), + name="walk-detail" + ), + re_path( + r'^(?P<page>\d+)/$', + views.WalkList.as_view(), + name="walk-list" + ), + re_path( + r'', + views.WalkList.as_view(), + {'page':1}, + name="walk-list" + ), +] |