diff options
author | luxagraf <sng@luxagraf.net> | 2020-11-15 10:13:08 -0500 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2020-11-15 10:13:08 -0500 |
commit | 7509da286bccd1dda358507cd455f9297db59247 (patch) | |
tree | 779aa3660e453d73268d22a72d9a5599cc94aa02 /app/pages | |
parent | b2434dcba142961b4a4b67780cf64e01d0908bf5 (diff) |
ported jrnl building to posts
Diffstat (limited to 'app/pages')
-rw-r--r-- | app/pages/admin.py | 16 | ||||
-rw-r--r-- | app/pages/migrations/0007_homepage.py | 28 | ||||
-rw-r--r-- | app/pages/migrations/0008_auto_20201114_0934.py | 30 | ||||
-rw-r--r-- | app/pages/models.py | 15 | ||||
-rw-r--r-- | app/pages/templates/pages/homepage.html | 98 | ||||
-rw-r--r-- | app/pages/views.py | 24 |
6 files changed, 208 insertions, 3 deletions
diff --git a/app/pages/admin.py b/app/pages/admin.py index 5cd2b23..4b4dcce 100644 --- a/app/pages/admin.py +++ b/app/pages/admin.py @@ -1,10 +1,11 @@ from django.contrib import admin +from utils.widgets import LGEntryForm from django import forms from django.forms import Textarea from django.db import models -from pages.models import Page +from pages.models import Page, HomePage class PageEntryForm(forms.ModelForm): @@ -16,6 +17,7 @@ class PageEntryForm(forms.ModelForm): } +@admin.register(Page) class PageAdmin(admin.ModelAdmin): form = PageEntryForm list_display = ('title', 'slug', 'path', 'app', 'build') @@ -32,4 +34,14 @@ class PageAdmin(admin.ModelAdmin): }) ) -admin.site.register(Page, PageAdmin) + +@admin.register(HomePage) +class HomePageAdmin(admin.ModelAdmin): + form = LGEntryForm + filter_horizontal = ('popular',) + + class Media: + js = ('image-loader.js', 'next-prev-links.js') + css = { + "all": ("my_styles.css",) + } diff --git a/app/pages/migrations/0007_homepage.py b/app/pages/migrations/0007_homepage.py new file mode 100644 index 0000000..c11aae9 --- /dev/null +++ b/app/pages/migrations/0007_homepage.py @@ -0,0 +1,28 @@ +# Generated by Django 3.1 on 2020-11-14 09:30 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('posts', '0015_post_old_image'), + ('photos', '0019_auto_20190704_0903'), + ('pages', '0006_page_enable_comments'), + ] + + operations = [ + migrations.CreateModel( + name='HomePage', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('image_offset_vertical', models.CharField(help_text='add negative top margin to shift image (include css unit)', max_length=20)), + ('tag_line', models.CharField(max_length=200, null=True)), + ('template_name', models.CharField(help_text='full path', max_length=200)), + ('featured', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='banner', to='posts.post')), + ('featured_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='photos.luximage')), + ('popular', models.ManyToManyField(related_name='popular', to='posts.Post')), + ], + ), + ] diff --git a/app/pages/migrations/0008_auto_20201114_0934.py b/app/pages/migrations/0008_auto_20201114_0934.py new file mode 100644 index 0000000..e8465a6 --- /dev/null +++ b/app/pages/migrations/0008_auto_20201114_0934.py @@ -0,0 +1,30 @@ +# Generated by Django 3.1 on 2020-11-14 09:34 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('photos', '0019_auto_20190704_0903'), + ('pages', '0007_homepage'), + ] + + operations = [ + migrations.AlterField( + model_name='homepage', + name='featured_image', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='photos.luximage'), + ), + migrations.AlterField( + model_name='homepage', + name='tag_line', + field=models.CharField(blank=True, max_length=200, null=True), + ), + migrations.AlterField( + model_name='homepage', + name='template_name', + field=models.CharField(blank=True, help_text='full path', max_length=200, null=True), + ), + ] diff --git a/app/pages/models.py b/app/pages/models.py index 5e9cd5b..8caa29e 100644 --- a/app/pages/models.py +++ b/app/pages/models.py @@ -2,6 +2,8 @@ import re from django.db import models from django.contrib.sitemaps import Sitemap +from photos.models import LuxImage +from posts.models import Post from utils.util import markdown_to_html, render_images @@ -33,6 +35,19 @@ class Page(models.Model): super(Page, self).save() +class HomePage(models.Model): + """ + simple model to control the featured article on the homepage + also allows me to fudge the "popular" section to be what I want + """ + image_offset_vertical = models.CharField(max_length=20, help_text="add negative top margin to shift image (include css unit)") + featured_image = models.ForeignKey(LuxImage, on_delete=models.CASCADE) + tag_line = models.CharField(max_length=200, null=True, blank=True) + featured = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="banner") + popular = models.ManyToManyField(Post, related_name="popular") + template_name = models.CharField(max_length=200, help_text="full path", null=True, blank=True) + + class PageSitemap(Sitemap): changefreq = "never" priority = 1.0 diff --git a/app/pages/templates/pages/homepage.html b/app/pages/templates/pages/homepage.html new file mode 100644 index 0000000..c8075ea --- /dev/null +++ b/app/pages/templates/pages/homepage.html @@ -0,0 +1,98 @@ +{% extends 'base.html' %} +{% load typogrify_tags %} +{% block sitename %} +<head itemscope itemtype="http://schema.org/WebSite"> + <title itemprop='name'>Luxagraf: thoughts on ecology, culture, travel, photography, walking and other ephemera</title> + <link rel="canonical" href="https://luxagraf.net/">{%endblock%} + + {%block extrahead%} +<style> +@media screen and (min-width: 1440px) { + .banner .post-image img { + margin-top: {{object.image_offset_vertical}}; + } +} +</style> +{%endblock%} +{%block bodyid%}id="home" class="archive"{%endblock%} + +{% block primary %}<div class="banner">{% with object=homepage.featured %} + <article class="h-entry hentry" itemscope itemType="http://schema.org/Article"> + <figure class="post-image"> + <a href="{{object.get_absolute_url}}" title="{{object.title}}">{%with image=homepage.featured_image%} + <img class="u-photo" itemprop="image" sizes="(max-width: 960px) 100vw" + srcset="{{image.get_srcset}}" + src="{{image.get_src}}" + alt="{{image.alt}} photographed by {% if image.photo_credit_source %}{{image.photo_credit_source}}{%else%}luxagraf{%endif%}"> + </a>{%endwith%} + <figcaption> + <div class="hero-text-wrapper"> + <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> + <h2 class="post-subtitle">{% if object.subtitle %}{{object.subtitle|smartypants|safe}}{%else%}{{homepage.tag_line|safe|smartypants}}{%endif%}</h2> + <aside class="p-location h-adr adr post-location" itemprop="contentLocation" itemscope itemtype="http://schema.org/Place"> + <div 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%}</div> + </aside> + <time class="dt-published published dt-updated post-date" datetime="{{object.pub_date|date:'c'}}" itemprop="datePublished">{{object.pub_date|date:"F"}} <span>{{object.pub_date|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> + <a href="{{object.get_absolute_url}}" class="u-url btn" title="{%if object.title_keywords%}{{object.title_keywords}}{%else%}{{object.title}}{%endif%}">Read</a> + </div> + </figcaption> + </figure> + </article>{% endwith %} + </div> + <section class="bio-short"> + <h2 class="homepage-section-header">About Luxagraf</h2> + <img src="/media/img/usa-resize.svg" alt="map of travels" class="homepage-map-img" /> + <p>We’re a family of five living full time in a vintage 1969 Dodge Travco motorhome. We’ve been at it for three years now. People always ask: <a href="https://luxagraf.net/1969-dodge-travco-motorhome">What's it like for five people to live in a 26ft RV</a>? <a href="https://luxagraf.net/essay/why-a-vintage-rv">Why do we live this way</a>?</p> + <p>The short answer is simple: because we like it and we can. If you want more than a soundbite, <a href="/jrnl/">read through the journal</a>. If you like it, sign up for the newsletter, <a href="/newsletter/friends/"><em>Friends of a Long Year</em></a>. I'd also <a href="/feed.xml">subscribe to the RSS feed</a>, but that's just <a href="/about">me</a>. <!-- If you’re interested there’s a guide section with some <a href="/guides/">advice, tips and tricks for those who’d aspire to live full time in a van or RV</a> --></p> + </section> + <section class="recent-popular"> + <div class="recent"> + <h2 class="homepage-section-header">Recent</h2> + <div class="archive-grid">{% for object in object_list %} + <article class="h-entry hentry archive-card {% cycle 'odd' 'even' %} {% cycle 'first' 'second' 'third' %}" itemscope itemType="http://schema.org/Article"> + <div class="post-image"> + <a href="{{object.get_absolute_url}}" title="{{object.title}}">{% if object.featured_image %} + {% include "lib/img_archive.html" with image=object.featured_image %} + {%else%} + <img src="{{object.get_image_url}}" alt="{{ object.title }}" class="u-photo post-image" itemprop="image" />{%endif%}</a> + </div> + <h3 class="p-name entry-title post-title" itemprop="headline"><a href="{{object.get_absolute_url}}" class="u-url" title="{%if object.title_keywords%}{{object.title_keywords}}{%else%}{{object.title}}{%endif%}">{{object.title|safe|smartypants|widont}}</a></h3> + <p class="p-author author hide" itemprop="author"><span class="byline-author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Scott Gilbertson</span></span></p> + <time class="dt-published published dt-updated post-date" datetime="{{object.pub_date|date:'c'}}">{{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></time> + <p class="post-summary"> + <span class="p-location h-adr adr post-location" itemprop="contentLocation" itemscope itemtype="http://schema.org/Place"> + {% if object.location.country_name == "United States" %}<span class="p-locality locality">{{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}}</a>, <span class="p-country-name">U.S.</span>{%else%}<span class="p-region">{{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}}">{{object.location.country_name}}</a>{%endif%} + </span> + </p> + </article> {% endfor %} + </div> + </div> + <div class="popular"> + <h2 class="homepage-section-header">Popular</h2> + <div class="archive-grid">{% for object in homepage.popular.all %} + <article class="h-entry hentry archive-card {% cycle 'odd' 'even' %} {% cycle 'first' 'second' 'third' %}" itemscope itemType="http://schema.org/Article"> + <div class="post-image"> + <a href="{{object.get_absolute_url}}" title="{{object.title}}">{% if object.featured_image %} + {% include "lib/img_archive.html" with image=object.featured_image %} + {%else%} + <img src="{{object.get_image_url}}" alt="{{ object.title }}" class="u-photo post-image" itemprop="image" />{%endif%}</a> + </div> + <h3 class="p-name entry-title post-title" itemprop="headline"><a href="{{object.get_absolute_url}}" class="u-url" title="{%if object.title_keywords%}{{object.title_keywords}}{%else%}{{object.title}}{%endif%}">{{object.title|safe|smartypants|widont}}</a></h3> + <p class="p-author author hide" itemprop="author"><span class="byline-author" itemscope itemtype="http://schema.org/Person"><span itemprop="name">Scott Gilbertson</span></span></p> + <time class="dt-published published dt-updated post-date" datetime="{{object.pub_date|date:'c'}}">{{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></time> + <p class="post-summary"> + <span class="p-location h-adr adr post-location" itemprop="contentLocation" itemscope itemtype="http://schema.org/Place"> + {% if object.location.country_name == "United States" %}<span class="p-locality locality">{{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}}</a>, <span class="p-country-name">U.S.</span>{%else%}<span class="p-region">{{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}}">{{object.location.country_name}}</a>{%endif%} + </span> + </p> + </article> {% endfor %} + </div> + </div> + </section> + <section> + <h5 class="homepage-next"><a href="/jrnl/">Browse the Archives</a></h5> + </section> +{% endblock %} + +{% block js %}{% comment %} <script async src="/media/js/hyphenate.min.js" type="text/javascript"></script>{% endcomment%}{% endblock%} diff --git a/app/pages/views.py b/app/pages/views.py index 167ad01..ed8d380 100644 --- a/app/pages/views.py +++ b/app/pages/views.py @@ -1,6 +1,9 @@ from utils.views import LuxDetailView +from django.views.generic import DetailView -from .models import Page +from locations.models import LuxCheckIn +from posts.models import Post, PostType +from .models import Page, HomePage class PageDetailView(LuxDetailView): @@ -15,3 +18,22 @@ class PageDetailTXTView(LuxDetailView): model = Page slug_field = "slug" template_name = "pages/page_detail.txt" + + +class HomePageList(DetailView): + """ + Return a main entry and list of Entries in reverse chronological order + """ + model = HomePage + + def get_template_names(self): + return ["pages/%s.html" % self.template_name, 'pages/homepage.html'] + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(HomePageList, self).get_context_data(**kwargs) + context['object_list'] = Post.objects.filter(post_type=PostType.JRNL).filter(status__exact=1).order_by('-pub_date').exclude().select_related('location').select_related('featured_image')[1:9] + context['location'] = LuxCheckIn.objects.latest() + return context + + |