summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/builder/views.py15
-rw-r--r--app/lttr/admin.py37
-rw-r--r--app/lttr/build.py37
-rw-r--r--app/lttr/migrations/0015_newnewslettermailing.py35
-rw-r--r--app/lttr/migrations/0016_mailingstatus_newnewsletter_mailing.py20
-rw-r--r--app/lttr/migrations/0017_auto_20210324_1330.py19
-rw-r--r--app/lttr/migrations/0018_auto_20210324_1331.py23
-rw-r--r--app/lttr/migrations/0019_auto_20210324_1350.py20
-rw-r--r--app/lttr/migrations/0020_auto_20210324_1351.py19
-rw-r--r--app/lttr/migrations/0021_auto_20210324_1352.py18
-rw-r--r--app/lttr/models.py52
-rw-r--r--app/lttr/templates/lttr/confirm_activate.html2
-rw-r--r--app/lttr/templates/lttr/emails/friends_html_email.html9
-rw-r--r--app/lttr/templates/lttr/emails/friends_plain_text_email.txt6
-rw-r--r--app/lttr/templates/lttr/emails/range_html_email.html13
-rw-r--r--app/lttr/templates/lttr/emails/range_plain_text_email.txt6
-rw-r--r--app/lttr/templates/lttr/emails/test-friends_html_email.html8
-rw-r--r--app/lttr/templates/lttr/emails/test-friends_plain_text_email.txt6
-rw-r--r--app/lttr/templates/lttr/emails/test-range_html_email.html13
-rw-r--r--app/lttr/templates/lttr/emails/test-range_plain_text_email.txt8
-rw-r--r--app/lttr/templates/lttr/friends_detail.html175
-rw-r--r--app/lttr/templates/lttr/friends_list.html29
-rw-r--r--app/lttr/templates/lttr/subscribed.html4
-rw-r--r--app/lttr/templates/lttr/unsubscribe.html15
-rw-r--r--app/lttr/urls.py32
-rw-r--r--app/lttr/views.py51
-rw-r--r--app/posts/build.py29
-rw-r--r--app/posts/models.py12
-rw-r--r--app/posts/urls/friends_urls.py7
-rw-r--r--app/posts/urls/range_urls.py11
-rw-r--r--app/posts/views/friends_views.py15
-rw-r--r--app/posts/views/range_views.py15
32 files changed, 367 insertions, 394 deletions
diff --git a/app/builder/views.py b/app/builder/views.py
index e3c795e..5d209d5 100644
--- a/app/builder/views.py
+++ b/app/builder/views.py
@@ -6,8 +6,7 @@ from resume.build import pub_builder, resume_builder
from books.build import builder as book_builder
from sightings.build import builder as sightings_builder
from pages.build import BuildPages, BuildHome
-from posts.build import BuildJrnl, BuildFieldNotes, BuildSrc, BuildGuide, BuildEssays
-from lttr.build import lttr_builder
+from posts.build import BuildJrnl, BuildFieldNotes, BuildSrc, BuildGuide, BuildEssays, BuildRange, BuildFriends
def do_build(request):
section = request.GET.get('id', '')
@@ -35,15 +34,18 @@ def do_build(request):
elif section == 'guide':
context = {'message': 'Writing guide section to Disk'}
BuildGuide("posts", "post").build()
+ elif section == 'range':
+ context = {'message': 'Writing Range to Disk'}
+ BuildRange("posts", "post").build()
+ elif section == 'friends':
+ context = {'message': 'Writing Friends to Disk'}
+ BuildFriends("posts", "post").build()
elif section == 'pages':
context = {'message': 'Writing Pages to Disk'}
BuildPages("pages", "page", 'luxagraf.net').build()
elif section == 'fieldnotes':
context = {'message': 'Writing FieldNotes to Disk'}
BuildFieldNotes("posts", "post").build()
- elif section == 'lttr_archive':
- context = {'message': 'Writing newsletter archives to Disk'}
- lttr_builder()
elif section == 'buildbooks':
context = {'message': 'Writing Book Pages to Disk'}
book_builder()
@@ -62,9 +64,6 @@ def do_build(request):
elif section == 'discursivepages':
context = {'message': 'Writing Discursive Meditation Pages to Disk'}
BuildPages("pages", "page", 'discursivemeditation.com').build()
- elif section == 'srcrss':
- context = {'message': 'Writing SrcRSS to Disk'}
- BuildSrc("posts", "post").build_feed("src:feed")
return render(request, 'admin/message.html', context)
diff --git a/app/lttr/admin.py b/app/lttr/admin.py
index da306f5..a13ab5b 100644
--- a/app/lttr/admin.py
+++ b/app/lttr/admin.py
@@ -2,7 +2,7 @@ from django.contrib import admin
from utils.widgets import AdminImageWidget, LGEntryForm
-from .models import NewsletterMailing, Subscriber, Newsletter, MailingStatus
+from .models import NewsletterMailing, OldNewsletterMailing, Subscriber, Newsletter, MailingStatus
@admin.register(Subscriber)
class SubscriberAdmin(admin.ModelAdmin):
@@ -17,8 +17,8 @@ class SubscriberAdmin(admin.ModelAdmin):
class NewsletterAdmin(admin.ModelAdmin):
pass
-@admin.register(NewsletterMailing)
-class NewsletterMailingAdmin(admin.ModelAdmin):
+@admin.register(OldNewsletterMailing)
+class OldNewsletterMailingAdmin(admin.ModelAdmin):
form = LGEntryForm
list_display = ('title', 'pub_date', 'newsletter', 'status')
list_filter = ['newsletter']
@@ -53,3 +53,34 @@ class NewsletterMailingAdmin(admin.ModelAdmin):
class MailingStatusAdmin(admin.ModelAdmin):
list_display = ('newsletter_mailing', 'subscriber', 'status', 'creation_date', 'newsletter')
list_filter = ('status', 'creation_date', 'newsletter_mailing__newsletter')
+
+@admin.register(NewsletterMailing)
+class NewsletterMailingAdmin(admin.ModelAdmin):
+ form = LGEntryForm
+ list_display = ('title', 'pub_date', 'newsletter', 'post')
+ list_filter = ['newsletter']
+ fieldsets = (
+ ('Entry', {
+ 'fields': (
+ ("newsletter", "post"),
+ 'title',
+ 'subtitle',
+ 'body_markdown',
+ 'body_html',
+ 'body_email_html',
+ 'pub_date',
+ 'featured_image',
+ ),
+ 'classes': (
+ 'show',
+ 'extrapretty',
+ 'wide'
+ )
+ }
+ ),
+ )
+ class Media:
+ js = ('image-loader.js', 'next-prev-links.js')
+ css = {
+ "all": ("my_styles.css",)
+ }
diff --git a/app/lttr/build.py b/app/lttr/build.py
deleted file mode 100644
index 4e53e39..0000000
--- a/app/lttr/build.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import os
-from django.urls import reverse
-from django.apps import apps
-from builder.base import BuildNew
-from itertools import chain
-
-from django.conf import settings
-from .models import NewsletterMailing
-
-
-class BuildNewsletterArchives(BuildNew):
-
- def get_model_queryset(self):
- return self.model.objects.exclude(slug='test-friends').exclude(slug='test-range').exclude(slug='test-src').exclude(slug='src')
-
-
- def build(self):
- for lttr in self.get_model_queryset():
- self.build_list_view(
- base_path=reverse("lttr:list", kwargs={'slug':lttr.slug}),
- paginate_by=50
- )
- self.build_detail_view(lttr)
-
- def build_detail_view(self, lttr):
- for obj in lttr.newslettermailing_set.all():
- url = obj.get_absolute_url()
- path, slug = os.path.split(url)
- path = '%s/' % path
- # write html
- response = self.client.get(url)
- print(path, slug)
- self.write_file(path, response.content, filename=slug)
-
-def lttr_builder():
- j = BuildNewsletterArchives("lttr", "Newsletter")
- j.build()
diff --git a/app/lttr/migrations/0015_newnewslettermailing.py b/app/lttr/migrations/0015_newnewslettermailing.py
new file mode 100644
index 0000000..0d8fa34
--- /dev/null
+++ b/app/lttr/migrations/0015_newnewslettermailing.py
@@ -0,0 +1,35 @@
+# Generated by Django 3.1 on 2021-03-24 12:54
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('media', '0008_auto_20201202_1155'),
+ ('posts', '0019_auto_20210323_2155'),
+ ('lttr', '0014_newsletter_intro'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='NewNewsletterMailing',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(blank=True, max_length=250)),
+ ('subtitle', models.CharField(blank=True, max_length=250, null=True)),
+ ('body_html', models.TextField(blank=True)),
+ ('body_email_html', models.TextField(blank=True)),
+ ('body_markdown', models.TextField(blank=True)),
+ ('pub_date', models.DateTimeField(blank=True)),
+ ('issue', models.PositiveIntegerField(blank=True)),
+ ('featured_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='media.luximage')),
+ ('newsletter', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lttr.newsletter')),
+ ('post', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='posts.post')),
+ ],
+ options={
+ 'ordering': ('-title', '-pub_date'),
+ },
+ ),
+ ]
diff --git a/app/lttr/migrations/0016_mailingstatus_newnewsletter_mailing.py b/app/lttr/migrations/0016_mailingstatus_newnewsletter_mailing.py
new file mode 100644
index 0000000..dfe9463
--- /dev/null
+++ b/app/lttr/migrations/0016_mailingstatus_newnewsletter_mailing.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1 on 2021-03-24 13:23
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('lttr', '0015_newnewslettermailing'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='mailingstatus',
+ name='newnewsletter_mailing',
+ field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, to='lttr.newnewslettermailing', verbose_name='newsletter'),
+ preserve_default=False,
+ ),
+ ]
diff --git a/app/lttr/migrations/0017_auto_20210324_1330.py b/app/lttr/migrations/0017_auto_20210324_1330.py
new file mode 100644
index 0000000..3519eec
--- /dev/null
+++ b/app/lttr/migrations/0017_auto_20210324_1330.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.1 on 2021-03-24 13:30
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('lttr', '0016_mailingstatus_newnewsletter_mailing'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='mailingstatus',
+ name='newnewsletter_mailing',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lttr.newnewslettermailing', verbose_name='newnewsletter'),
+ ),
+ ]
diff --git a/app/lttr/migrations/0018_auto_20210324_1331.py b/app/lttr/migrations/0018_auto_20210324_1331.py
new file mode 100644
index 0000000..1dc16a1
--- /dev/null
+++ b/app/lttr/migrations/0018_auto_20210324_1331.py
@@ -0,0 +1,23 @@
+# Generated by Django 3.1 on 2021-03-24 13:31
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('lttr', '0017_auto_20210324_1330'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='mailingstatus',
+ name='newsletter_mailing',
+ ),
+ migrations.AlterField(
+ model_name='mailingstatus',
+ name='newnewsletter_mailing',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lttr.newnewslettermailing', verbose_name='newsletter'),
+ ),
+ ]
diff --git a/app/lttr/migrations/0019_auto_20210324_1350.py b/app/lttr/migrations/0019_auto_20210324_1350.py
new file mode 100644
index 0000000..47b0f38
--- /dev/null
+++ b/app/lttr/migrations/0019_auto_20210324_1350.py
@@ -0,0 +1,20 @@
+# Generated by Django 3.1 on 2021-03-24 13:50
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('media', '0008_auto_20201202_1155'),
+ ('taxonomy', '0006_auto_20210107_1611'),
+ ('books', '0016_bookhighlight_is_public'),
+ ('lttr', '0018_auto_20210324_1331'),
+ ]
+
+ operations = [
+ migrations.RenameModel(
+ old_name='NewsletterMailing',
+ new_name='OldNewsletterMailing',
+ ),
+ ]
diff --git a/app/lttr/migrations/0020_auto_20210324_1351.py b/app/lttr/migrations/0020_auto_20210324_1351.py
new file mode 100644
index 0000000..e4315dc
--- /dev/null
+++ b/app/lttr/migrations/0020_auto_20210324_1351.py
@@ -0,0 +1,19 @@
+# Generated by Django 3.1 on 2021-03-24 13:51
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('posts', '0019_auto_20210323_2155'),
+ ('media', '0008_auto_20201202_1155'),
+ ('lttr', '0019_auto_20210324_1350'),
+ ]
+
+ operations = [
+ migrations.RenameModel(
+ old_name='NewNewsletterMailing',
+ new_name='NewsletterMailing',
+ ),
+ ]
diff --git a/app/lttr/migrations/0021_auto_20210324_1352.py b/app/lttr/migrations/0021_auto_20210324_1352.py
new file mode 100644
index 0000000..42d6b41
--- /dev/null
+++ b/app/lttr/migrations/0021_auto_20210324_1352.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.1 on 2021-03-24 13:52
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('lttr', '0020_auto_20210324_1351'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='mailingstatus',
+ old_name='newnewsletter_mailing',
+ new_name='newsletter_mailing',
+ ),
+ ]
diff --git a/app/lttr/models.py b/app/lttr/models.py
index e39b3b0..f1125d0 100644
--- a/app/lttr/models.py
+++ b/app/lttr/models.py
@@ -21,6 +21,7 @@ from utils.util import render_images, parse_video, markdown_to_html
from taxonomy.models import TaggedItems
from media.models import LuxImage, LuxImageSize
from books.models import Book
+from posts.models import Post
# Possible actions that user can perform
@@ -125,7 +126,7 @@ class Newsletter(models.Model):
return None
-class NewsletterMailing(models.Model):
+class OldNewsletterMailing(models.Model):
""" A model for Newletter Mailings, the things actually sent out """
newsletter = models.ForeignKey(Newsletter, on_delete=models.CASCADE)
title = models.CharField(max_length=250)
@@ -206,6 +207,55 @@ class NewsletterMailing(models.Model):
super(NewsletterMailing, self).save()
+class NewsletterMailing(models.Model):
+ """ A model for Newletter Mailings, the things actually sent out """
+ newsletter = models.ForeignKey(Newsletter, on_delete=models.CASCADE)
+ post = models.ForeignKey(Post, null=True, blank=True, on_delete=models.SET_NULL)
+ title = models.CharField(max_length=250, blank=True)
+ subtitle = models.CharField(max_length=250, null=True, blank=True)
+ body_html = models.TextField(blank=True)
+ body_email_html = models.TextField(blank=True)
+ body_markdown = models.TextField(blank=True)
+ pub_date = models.DateTimeField(blank=True)
+ featured_image = models.ForeignKey(LuxImage, on_delete=models.CASCADE, null=True, blank=True)
+ issue = models.PositiveIntegerField(blank=True)
+
+ class Meta:
+ ordering = ('-title', '-pub_date')
+
+ def __str__(self):
+ return self.title
+
+ def email_encode(self):
+ return self.body_markdown
+
+ def get_issue_str(self):
+ issue = self.issue
+ if self.issue < 100:
+ issue = "0%s" % self.issue
+ if self.issue < 10:
+ issue = "00%s" % self.issue
+ return issue
+
+ def save(self, *args, **kwargs):
+ created = self.pk is None
+ if created and self.post:
+ self.title = self.post.title
+ self.subtitle = self.post.subtitle
+ self.body_markdown = self.post.body_markdown
+ self.pub_date = self.post.pub_date
+ self.featured_image = self.post.featured_image
+ self.issue = self.post.issue
+ if not created:
+ md = render_images(self.body_markdown)
+ self.body_html = markdown_to_html(md)
+ self.body_email_html = markdown_to_emailhtml(self.body_html)
+ self.date_created = timezone.now()
+ if created and not self.featured_image:
+ self.featured_image = LuxImage.objects.latest()
+ super(NewNewsletterMailing, self).save()
+
+
class Subscriber(models.Model):
""" A model for Newletter Subscriber """
email_field = models.EmailField(db_column='email', db_index=True, blank=True, null=True)
diff --git a/app/lttr/templates/lttr/confirm_activate.html b/app/lttr/templates/lttr/confirm_activate.html
index 533d93f..a2d3a3d 100644
--- a/app/lttr/templates/lttr/confirm_activate.html
+++ b/app/lttr/templates/lttr/confirm_activate.html
@@ -18,7 +18,7 @@
<main role="main" id="essay-archive" class="archive-wrapper">
<div class="archive-intro">
<h2>You're confirmed, thanks for joining.</h2>
- <p>If you'd like you can <a href="{% url 'lttr:list' slug=newsletter %}">visit the archives</a> of past mailings.</p>
+ <p>If you'd like you can <a href="/{{newsletter}}/">browse the archives</a> of past mailings.</p>
</div>
</main>
{%endblock%}
diff --git a/app/lttr/templates/lttr/emails/friends_html_email.html b/app/lttr/templates/lttr/emails/friends_html_email.html
index 0c70654..66ae18f 100644
--- a/app/lttr/templates/lttr/emails/friends_html_email.html
+++ b/app/lttr/templates/lttr/emails/friends_html_email.html
@@ -187,11 +187,11 @@ ul li, ol li {
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<h2 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:30px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;" ><br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/newsletter/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >Friends of a Long Year</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
+ <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/friends/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >Friends of a Long Year</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
<h1 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:mffnweb, 'Lora', 'Lucida Serif', Lucida, Georgia, serif;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:44px;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >{{object.title|safe|smartypants}}</singleline></h1>
<hr style="padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:50%;margin-top:40px;margin-bottom:40px;margin-right:auto;margin-left:auto;border-width:0;border-top-width:1px;border-top-style:solid;border-top-color:#ddd;" />
- <a href="https://luxagraf.net{{object.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
+ <a href="https://luxagraf.net{{object.post.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
{% include "lib/friends_featured_img.html" with image=object.featured_image %}
</a>
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
@@ -218,12 +218,9 @@ ul li, ol li {
<table style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:100%;" >
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td align="center" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
-
- {%comment%}<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >This newsletter is made possible by members of <a href="" class="sp" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-size:.85em;text-transform:uppercase;font-weight:bold;letter-spacing:1px;color:#333;text-decoration:none;" >SPECIAL PROJECTS</a>.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- If you enjoy <em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Ridgeline</em>, consider joining. Thanks. </p>{%endcomment%}
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >New subscriber?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- Browse the <a href="https://luxagraf.net/newsletter/friends/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
+ Browse the <a href="https://luxagraf.net/friends/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >⫹⫺</p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" ><em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Friends</em>?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
diff --git a/app/lttr/templates/lttr/emails/friends_plain_text_email.txt b/app/lttr/templates/lttr/emails/friends_plain_text_email.txt
index b145d51..286b527 100644
--- a/app/lttr/templates/lttr/emails/friends_plain_text_email.txt
+++ b/app/lttr/templates/lttr/emails/friends_plain_text_email.txt
@@ -7,10 +7,10 @@ You're getting this email because you signed up for
Scott Gilbertson's (luxagraf)[https://luxagraf.net/] newsletter,
-*Friends of a Long Year* [https://luxagraf.net/newsletter/friends/]
+*Friends of a Long Year* [https://luxagraf.net/friends/]
-If you're new, you can explore past letters here: [https://luxagraf.net/newsletter/friends/]
+If you're new, you can explore past letters here: [https://luxagraf.net/friends/]
You can always: Unsubscribe [https://luxagraf.net{{subscriber.unsubscribe_activate_url}}] instantly.
-[https://luxagraf.net/] ✪ [https://luxagraf.net/newsletter/friends/]
+[https://luxagraf.net/] ✪ [https://luxagraf.net/friends/]
diff --git a/app/lttr/templates/lttr/emails/range_html_email.html b/app/lttr/templates/lttr/emails/range_html_email.html
index 0b94a68..09c2db3 100644
--- a/app/lttr/templates/lttr/emails/range_html_email.html
+++ b/app/lttr/templates/lttr/emails/range_html_email.html
@@ -179,17 +179,17 @@ ul li, ol li {
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<h2 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:30px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;" ><br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/newsletter/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >✪ Range</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
+ <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >✪ Range</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
<h1 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:mffnweb, 'Lora', 'Lucida Serif', Lucida, Georgia, serif;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:44px;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >{{object.title|safe|smartypants}}</singleline></h1>
<hr style="padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:50%;margin-top:40px;margin-bottom:40px;margin-right:auto;margin-left:auto;border-width:0;border-top-width:1px;border-top-style:solid;border-top-color:#ddd;" />
- <a href="https://luxagraf.net{{object.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
+ <a href="https://luxagraf.net{{object.post.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
{% include "lib/friends_featured_img.html" with image=object.featured_image %}
</a>
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- If you'd like to view a larger version, read some backstory, and see a video of the development process in Darktable, head on over to: <a href="https://luxagraf.net{{object.get_absolute_url}}">https://luxagraf.net{{object.get_absolute_url}}</a>
+ If you'd like to view a larger version, read some backstory, and see a video of the development process in Darktable, head on over to: <a href="https://luxagraf.net{{object.post.get_absolute_url}}">https://luxagraf.net{{object.post.get_absolute_url}}</a>
<hr style="padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:50%;margin-top:40px;margin-bottom:40px;margin-right:auto;margin-left:auto;border-width:0;border-top-width:1px;border-top-style:solid;border-top-color:#ddd;" />
</td>
@@ -210,19 +210,16 @@ ul li, ol li {
<table style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:100%;" >
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td align="center" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
-
- {%comment%}<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >This newsletter is made possible by members of <a href="" class="sp" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-size:.85em;text-transform:uppercase;font-weight:bold;letter-spacing:1px;color:#333;text-decoration:none;" >SPECIAL PROJECTS</a>.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- If you enjoy <em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Ridgeline</em>, consider joining. Thanks. </p>{%endcomment%}
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >New subscriber?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- Browse the <a href="https://luxagraf.net/newsletter/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
+ Browse the <a href="https://luxagraf.net/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" ><em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Range</em>?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
A weekly letter from <a href="https://luxagraf.net/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >Scott Gilberson</a>, <br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />also known as luxagraf.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" /></p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >
Shipped from Points Unknown, USA.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- Explained <a href="https://luxagraf.net/newsletter/range" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >here</a>.</p>
+ Explained <a href="https://luxagraf.net/range" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >here</a>.</p>
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >If you enjoy this, <br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
please consider forwarding it to a friend.</p>
diff --git a/app/lttr/templates/lttr/emails/range_plain_text_email.txt b/app/lttr/templates/lttr/emails/range_plain_text_email.txt
index cdb8c52..2044e44 100644
--- a/app/lttr/templates/lttr/emails/range_plain_text_email.txt
+++ b/app/lttr/templates/lttr/emails/range_plain_text_email.txt
@@ -10,10 +10,10 @@ You're getting this email because you signed up for
Scott Gilbertson's (luxagraf)[https://luxagraf.net/] photo newsletter,
-*Range* [https://luxagraf.net/newsletter/range/]
+*Range* [https://luxagraf.net/range/]
-If you're new, you can explore past letters here: [https://luxagraf.net/newsletter/range/]
+If you're new, you can explore past letters here: [https://luxagraf.net/range/]
You can always: Unsubscribe [https://luxagraf.net{{subscriber.unsubscribe_activate_url}}] instantly.
-[https://luxagraf.net/] ✪ [https://luxagraf.net/newsletter/range/]
+[https://luxagraf.net/] ✪ [https://luxagraf.net/range/]
diff --git a/app/lttr/templates/lttr/emails/test-friends_html_email.html b/app/lttr/templates/lttr/emails/test-friends_html_email.html
index 0c70654..d1e2f5a 100644
--- a/app/lttr/templates/lttr/emails/test-friends_html_email.html
+++ b/app/lttr/templates/lttr/emails/test-friends_html_email.html
@@ -187,11 +187,11 @@ ul li, ol li {
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<h2 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:30px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;" ><br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/newsletter/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >Friends of a Long Year</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
+ <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/friends/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >Friends of a Long Year</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
<h1 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:mffnweb, 'Lora', 'Lucida Serif', Lucida, Georgia, serif;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:44px;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >{{object.title|safe|smartypants}}</singleline></h1>
<hr style="padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:50%;margin-top:40px;margin-bottom:40px;margin-right:auto;margin-left:auto;border-width:0;border-top-width:1px;border-top-style:solid;border-top-color:#ddd;" />
- <a href="https://luxagraf.net{{object.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
+ <a href="https://luxagraf.net{{object.post.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
{% include "lib/friends_featured_img.html" with image=object.featured_image %}
</a>
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
@@ -219,11 +219,9 @@ ul li, ol li {
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td align="center" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
- {%comment%}<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >This newsletter is made possible by members of <a href="" class="sp" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-size:.85em;text-transform:uppercase;font-weight:bold;letter-spacing:1px;color:#333;text-decoration:none;" >SPECIAL PROJECTS</a>.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- If you enjoy <em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Ridgeline</em>, consider joining. Thanks. </p>{%endcomment%}
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >New subscriber?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- Browse the <a href="https://luxagraf.net/newsletter/friends/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
+ Browse the <a href="https://luxagraf.net/friends/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >⫹⫺</p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" ><em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Friends</em>?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
diff --git a/app/lttr/templates/lttr/emails/test-friends_plain_text_email.txt b/app/lttr/templates/lttr/emails/test-friends_plain_text_email.txt
index b145d51..286b527 100644
--- a/app/lttr/templates/lttr/emails/test-friends_plain_text_email.txt
+++ b/app/lttr/templates/lttr/emails/test-friends_plain_text_email.txt
@@ -7,10 +7,10 @@ You're getting this email because you signed up for
Scott Gilbertson's (luxagraf)[https://luxagraf.net/] newsletter,
-*Friends of a Long Year* [https://luxagraf.net/newsletter/friends/]
+*Friends of a Long Year* [https://luxagraf.net/friends/]
-If you're new, you can explore past letters here: [https://luxagraf.net/newsletter/friends/]
+If you're new, you can explore past letters here: [https://luxagraf.net/friends/]
You can always: Unsubscribe [https://luxagraf.net{{subscriber.unsubscribe_activate_url}}] instantly.
-[https://luxagraf.net/] ✪ [https://luxagraf.net/newsletter/friends/]
+[https://luxagraf.net/] ✪ [https://luxagraf.net/friends/]
diff --git a/app/lttr/templates/lttr/emails/test-range_html_email.html b/app/lttr/templates/lttr/emails/test-range_html_email.html
index 0b94a68..d11479c 100644
--- a/app/lttr/templates/lttr/emails/test-range_html_email.html
+++ b/app/lttr/templates/lttr/emails/test-range_html_email.html
@@ -179,17 +179,17 @@ ul li, ol li {
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<h2 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:30px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;" ><br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/newsletter/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >✪ Range</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
+ <span style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-size:.5em;line-height:2em;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" ><a href="https://luxagraf.net/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;color:#000;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-weight:normal;" >✪ Range</a> — {{object.get_issue_str}} — {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></singleline></span></h2>
<h1 style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:mffnweb, 'Lora', 'Lucida Serif', Lucida, Georgia, serif;line-height:1;margin-bottom:15px;color:#000;text-align:center;font-weight:400;font-size:44px;" ><singleline style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >{{object.title|safe|smartypants}}</singleline></h1>
<hr style="padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:50%;margin-top:40px;margin-bottom:40px;margin-right:auto;margin-left:auto;border-width:0;border-top-width:1px;border-top-style:solid;border-top-color:#ddd;" />
- <a href="https://luxagraf.net{{object.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
+ <a href="https://luxagraf.net{{object.post.get_absolute_url}}" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-width:0;color:#000;font-weight:600;text-decoration:none;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;" >
{% include "lib/friends_featured_img.html" with image=object.featured_image %}
</a>
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- If you'd like to view a larger version, read some backstory, and see a video of the development process in Darktable, head on over to: <a href="https://luxagraf.net{{object.get_absolute_url}}">https://luxagraf.net{{object.get_absolute_url}}</a>
+ If you'd like to view a larger version, read some backstory, and see a video of the development process in Darktable, head on over to: <a href="https://luxagraf.net{{object.post.get_absolute_url}}">https://luxagraf.net{{object.post.get_absolute_url}}</a>
<hr style="padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:50%;margin-top:40px;margin-bottom:40px;margin-right:auto;margin-left:auto;border-width:0;border-top-width:1px;border-top-style:solid;border-top-color:#ddd;" />
</td>
@@ -210,19 +210,16 @@ ul li, ol li {
<table style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;width:100%;" >
<tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
<td align="center" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >
-
- {%comment%}<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >This newsletter is made possible by members of <a href="" class="sp" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;font-size:.85em;text-transform:uppercase;font-weight:bold;letter-spacing:1px;color:#333;text-decoration:none;" >SPECIAL PROJECTS</a>.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- If you enjoy <em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Ridgeline</em>, consider joining. Thanks. </p>{%endcomment%}
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >New subscriber?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- Browse the <a href="https://luxagraf.net/newsletter/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
+ Browse the <a href="https://luxagraf.net/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >online archives</a> here.</p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" ><em style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" >Range</em>?<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
A weekly letter from <a href="https://luxagraf.net/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >Scott Gilberson</a>, <br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />also known as luxagraf.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" /></p>
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >
Shipped from Points Unknown, USA.<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
- Explained <a href="https://luxagraf.net/newsletter/range" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >here</a>.</p>
+ Explained <a href="https://luxagraf.net/range/" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-weight:600;border-bottom-width:1px;border-bottom-style:solid;border-bottom-color:#ddd;color:#333;text-decoration:none;" >here</a>.</p>
<br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
<p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;margin-bottom:1.4em;font-weight:400;line-height:1.5;hyphens:auto;font-size:14px;" >If you enjoy this, <br style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;" />
please consider forwarding it to a friend.</p>
diff --git a/app/lttr/templates/lttr/emails/test-range_plain_text_email.txt b/app/lttr/templates/lttr/emails/test-range_plain_text_email.txt
index b823d2f..970c42f 100644
--- a/app/lttr/templates/lttr/emails/test-range_plain_text_email.txt
+++ b/app/lttr/templates/lttr/emails/test-range_plain_text_email.txt
@@ -2,7 +2,7 @@ Greetings Range subscribers-
While I respect your desire for plain text email, there really isn't a way to do a photo newsletter in plain text other than to say, here's a link to the web-based version:
-<{{ object.get_absolute_url }}>
+<https://luxagraf.net{{ object.get_absolute_url }}>
-----
@@ -10,10 +10,10 @@ You're getting this email because you signed up for
Scott Gilbertson's (luxagraf)[https://luxagraf.net/] photo newsletter,
-*Range* [https://luxagraf.net/newsletter/range/]
+*Range* [https://luxagraf.net/range/]
-If you're new, you can explore past letters here: [https://luxagraf.net/newsletter/range/]
+If you're new, you can explore past letters here: [https://luxagraf.net/range/]
You can always: Unsubscribe [https://luxagraf.net{{subscriber.unsubscribe_activate_url}}] instantly.
-[https://luxagraf.net/] ✪ [https://luxagraf.net/newsletter/range/]
+[https://luxagraf.net/] ✪ [https://luxagraf.net/range/]
diff --git a/app/lttr/templates/lttr/friends_detail.html b/app/lttr/templates/lttr/friends_detail.html
deleted file mode 100644
index 5a8c92d..0000000
--- a/app/lttr/templates/lttr/friends_detail.html
+++ /dev/null
@@ -1,175 +0,0 @@
-{% extends 'base.html' %}
-{% load typogrify_tags %}
-{% load get_image_by_size %}
-{%block htmlclass%}{%endblock%}
-{% block sitename %}
-<head itemscope itemtype="http://schema.org/WebSite">
- <title itemprop='name'>{{object.title|safe}} by Scott Gilbertson</title>
- <link rel="canonical" href="https://luxagraf.net{{object.get_absolute_url}}">{%endblock%}
-
- {%block extrahead%}
- <link rel="canonical" href="https://luxagraf.net{{object.get_absolute_url}}" />
- <meta property="og:type" content="article" />
- <meta property="og:title" content="{{object.title|safe}}" />
- <meta property="og:url" content="https://luxagraf.net{{object.get_absolute_url}}" />
- <meta property="og:description" content="{{object.meta_description}}" />
- <meta property="article:published_time" content="{{object.pub_date|date:'c'}}" />
- <meta property="article:author" content="Scott Gilbertson" />
- <meta property="og:site_name" content="Luxagraf" />
- <meta property="og:image" content="{{object.get_featured_image}}" />
- <meta property="og:locale" content="en_US" />
- <meta name="twitter:card" content="summary_large_image"/>
- <meta name="twitter:description" content="{{object.meta_description}}"/>
- <meta name="twitter:title" content="{{object.title|safe}}"/>
- <meta name="twitter:site" content="@luxagraf"/>
- <meta name="twitter:domain" content="luxagraf"/>
- <meta name="twitter:image:src" content="{{object.get_featured_image}}"/>
- <meta name="twitter:creator" content="@luxagraf"/>
-<script type="application/ld+json">
-{
- "@context": "https://schema.org",
- "@type": "Article",
- "mainEntityOfPage": {
- "@type": "WebPage",
- "@id": "https://luxagraf.net{{object.get_absolute_url}}"
- },
- "headline": "{{object.title}}",
- "datePublished": "{{object.pub_date|date:'c'}}+04:00",
- "dateModified": "{{object.pub_date|date:'c'}}+04:00",
- "author": {
- "@type": "Person",
- "name": "Scott Gilbertson"
- },
- "publisher": {
- "@type": "Organization",
- "name": "Luxagraf",
- "logo": {
- "@type": "ImageObject",
- "url": "https://luxagraf.net/media/img/logo-white.jpg"
- }
- },
- "description": "{{object.meta_description}}"
-}
-</script>
-{%endblock%}
-{%block bodyid%}id="home" class="friends"{%endblock%}
-{% block breadcrumbs %}<nav class="breadcrumbs" itemscope itemtype="http://schema.org/BreadcrumbList">
- <span class="nav-item" itemprop="item">
- <a href="/" itemprop="name">Home</a>
- <meta itemprop="position" content="1" />
- </span>
- <span class="nav-item" itemprop="item">
- <a href="/friends/" itemprop="name">Friends of a Long Year</a>
- <meta itemprop="position" content="2" />
- </span>
- <span class="nav-item" itemprop="item">
- <span itemprop="name">{{object.get_issue_str}}</span>
- <meta itemprop="position" content="3" />
- </span>
- </nav>
-{% endblock %}
-{% block primary %}
- <main>
- <figure class="large-top-image">
- <a href="{{object.get_absolute_url}}" title="{{object.title}}">{%with image=object.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%}
- </figure>
- <article class="h-entry hentry content" itemscope itemType="http://schema.org/BlogPosting">
- <header id="header" class="post-header">
- <h1 class="p-name post-title" itemprop="headline">{{object.title|smartypants|safe}}</h1>
- <div class="post-dateline">
- <time class="dt-published published dt-updated post-date lttr-box" datetime="{{object.pub_date|date:'c'}}" itemprop="datePublished">Transmission {{object.get_issue_str}} &ndash; {{object.pub_date|date:"F, 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>
- <div id="article" class="e-content entry-content post-body" itemprop="articleBody">
- {{object.body_html|safe|smartypants}}
- </div>
- {%if object.books.all %}<div class="entry-footer">
- <aside id="recommended-reading" class="" >
- <h3>Recommended Reading</h3>{% for obj in object.books.all %}
- <div itemprop="mainEntity" itemscope itemtype="http://schema.org/Book">
- <div class="book-cover-wrapper">
- <img src="{{obj.get_image_url}}" alt="{{obj.title}} cover" class="lttr-cover" />
- </div>
- <div class="meta-cover">
- <h5 class="post-title book-title" itemprop="name">{{obj.title|smartypants|widont|safe}}</h6>
- <h6 class="post-subtitle" itemprop="author" itemscope itemtype="http://schema.org/Person">
- <meta itemprop="name" content="{{obj.author_name}}"/>by {{obj.author_name}}</h5>
- <dl class="book-metadata">
- {% if obj.rating %}<dt>Rating</dt><dd class="book-stars">
- {% for i in obj.ratings_range %}{% if i <= obj.get_rating%}&#9733;{%else%}&#9734;{%endif%}{%endfor%}</span></dd>{%endif%}
- {% if obj.read_in %}<dt>Read</dt>
- <dd>{{obj.read_in}}</dd>{%endif%}
- {% if obj.pages %}<dt>Pages</dt>
- <dd itemprop="numberOfPages">{{obj.pages}}</dd>{%endif%}
- {% if obj.publish_date %}<dt>Published</dt>
- <dd>{%if obj.publish_place%}{{obj.publish_place}}, {%endif%}{{obj.publish_date}}</dd>{%endif%}
- {% if obj.isbn %}<dt>ISBN</dt>
- <dd>{{obj.isbn}}</dd>{%endif%}
- </dl>
- <div class="buy-btn-wrapper">
- {% if obj.isbn %}<a class="buy-btn" href="http://worldcat.org/isbn/{{obj.isbn}}" title="find {{obj.title}} in your local library">Borrow</a>{%endif%}
- {% if obj.afflink %}<a class="buy-btn" href="{{obj.afflink}}" title="buy {{obj.title}} at Amazon">Buy</a>{%endif%}
- </div>
- </div>{%if obj.body_html%}
- <div class="thoughts" itemprop="review" itemscope itemtype="http://schema.org/Review">
- <h5>Notes</h5>
- <span class="hide" itemprop="reviewRating">{{obj.rating}}</span>
- <meta itemprop="author" content="Scott Gilbertson" />
- <meta itemprop="datePublished" content="{{obj.read_date|date:"c"}}">
- <div itemprop="reviewBody">{{obj.body_html|safe|smartypants|widont}}</div>
- </div>{%endif%}
- </div>
- {% endfor %}
- </aside>{%endif%}
- </article>
-
- {% with object.get_next_published as next %}
- {% with object.get_previous_published as prev %}
- <nav class="page-navigation">
- <div>{% if prev%}
- <span class="label">Previous:</span>
- <a href="{{ prev.get_absolute_url }}" rel="prev" title=" {{prev.title}}">{{prev.title|safe}}</a>
- </div>{%endif%}{% if next%}
- <div>
- <span class="label">Next:</span>
- <a href="{{ next.get_absolute_url }}" rel="next" title=" {{next.title}}">{{next.title|safe}}</a>
- </div>{%endif%}
- </nav>{%endwith%}{%endwith%}
- </div>
- {% if object.related.all %}<div class="article-afterward related">
- <div class="related-bottom">
- <h6 class="hedtinycaps">You might also enjoy</h6>
- <ul class="article-card-list">{% for object in related %}
- <li class="article-card-mini"><a href="{{object.get_absolute_url}}" title="{{object.title}}">
- <div class="post-image post-mini-image">
- {% if object.featured_image %}
- {% include "lib/img_archive.html" with image=object.featured_image nolightbox=True %}
- {% elif object.image %}
- {% include "lib/img_archive.html" with image=object.image nolightbox=True %}
- {% else %}
- <img src="{{object.get_image_url}}" alt="{{ object.title }}" class="u-photo post-image" itemprop="image" />{%endif%}
- </div>
- <h4 class="p-name entry-title post-title" itemprop="headline">{% if object.title %}{{object.title|safe|smartypants|widont}}{% else %}{{object.common_name}}{%endif%}</h4>
- <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>
- <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" %}{{object.location.state_name}}{%else%}{{object.location.country_name}}{%endif%}
- </span>
- &ndash;
- <time class="dt-published published dt-updated post-date" datetime="{{object.pub_date|date:'c'}}"><span>{{object.pub_date|date:" Y"}}</span></time>
- </p>
- </a>
- </li>
- {% endfor %}</ul>
- </div>
- </div>{%endif%}
- </main>
-{% endblock %}
-
-{% block js %}{% comment %} <script async src="/media/js/hyphenate.min.js" type="text/javascript"></script>{% endcomment%}{% endblock%}
diff --git a/app/lttr/templates/lttr/friends_list.html b/app/lttr/templates/lttr/friends_list.html
deleted file mode 100644
index 3318a08..0000000
--- a/app/lttr/templates/lttr/friends_list.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends 'base.html' %}
-{% load typogrify_tags %}
-
-{% block pagetitle %}Luxagraf | Friends of a Long Year {% endblock %}
-{% block metadescription %}An infrequesnt mailing list about living outdoors, travel, literature, music, vintage vehicles, and other ephemera.{% endblock %}
-{% block breadcrumbs %}{% include "lib/breadcrumbs.html" with breadcrumbs=breadcrumbs %}{% endblock %}
-{% block primary %}
- <main role="main" class="archive-wrapper">
- <div class="archive-intro">
- <h1 class="list-hed">Join the <em>Friends of a Long Year</em>.</h1>
- <iframe target='_parent' style="border:none; background:white; width:100%;" title="embedded form for subscribing the the Friends of a Long Year newsletter" src="{% url 'lttr:subscribe' slug='friends' %}"></iframe>
- <h2 class="list-subhed">Say what? </h2>
- <p><em>Friends of a Long Year</em> is a monthly letter about living outdoors, travel, literature, music, vintage vehicles, and other ephemera. It's written in the spirit of Mary Austin. And Mike’s emails. A more detailed explaination can be found <a href="/jrnl/2020/11/invitation">here</a>.</p>
- <p>Unsubscribing is easy. It's all <a href="/src/building-your-own-mailing-list-software">self-hosted</a> and designed to <a href="/privacy" title="My privacy policy">respect your privacy</a>.</p>
- <p>There's also the <em><a href="/range/">Range</a></em> newsletter if you'd like a photo in your inbox once a week.</p>
- </div>
- <h3 class="archive-sans">Letters</h3>
- <ul class="archive-list">{% for object in object_list %}
- <li class="h-entry hentry archive-list-card" itemscope itemType="http://schema.org/Article">
- <a href="{{object.get_absolute_url}}" class="u-url">
- {% if object.featured_image %}<div class="circle-img-wrapper"><img src="{{object.featured_image.get_thumbnail_url}}" alt="{{object.featured_image.alt}}" class="u-photo" /></div>{%endif%}
- <span class="date dt-published card-smcaps">issue {{object.get_issue_str}} &ndash; {{object.pub_date|date:"M y"}}</span>
- <h2 class="card-hed">{{object.title|safe|smartypants|widont}}</h2>
- {% if object.subtitle %}<h3 class="p-summary card-lede">{{object.subtitle|safe|smartypants|widont}}</h3>{%endif%}
- </a>
- </li>
- {%endfor%}</ul>
- </main>
-{%endblock%}
diff --git a/app/lttr/templates/lttr/subscribed.html b/app/lttr/templates/lttr/subscribed.html
index 7139d24..43278cf 100644
--- a/app/lttr/templates/lttr/subscribed.html
+++ b/app/lttr/templates/lttr/subscribed.html
@@ -17,8 +17,8 @@
</nav>
<main role="main" id="essay-archive" class="archive-wrapper">
<div class="archive-intro">
- <h2>Thanks for joining.</h2>
- <p>Check your email for a link to confirm your subscription</p>
+ <h2>Thanks, You're Almost There.</h2>
+ <p><b>Check your email for a link to confirm your subscription</b></p>
</div>
</main>
{%endblock%}
diff --git a/app/lttr/templates/lttr/unsubscribe.html b/app/lttr/templates/lttr/unsubscribe.html
index d3f17e0..993ea9f 100644
--- a/app/lttr/templates/lttr/unsubscribe.html
+++ b/app/lttr/templates/lttr/unsubscribe.html
@@ -4,10 +4,17 @@
{% block pagetitle %}Luxagraf | Friends of a Long Year {% endblock %}
{% block metadescription %}An infrequesnt mailing list about travel, photography, tools, walking, the natural world and other ephemera.{% 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> &rarr; </li>
- <li>Lttr</li>
- </ul>
+{% block primary %}
+<nav class="breadcrumbs" itemscope="" itemtype="http://schema.org/BreadcrumbList">
+ <span class="nav-item" itemprop="item">
+ <a href="/" itemprop="name">Home</a>
+ <meta itemprop="position" content="1">
+ </span>
+ <span class="nav-item" itemprop="item">
+ <span itemprop="name">Unsubscribe</span>
+ <meta itemprop="position" content="2">
+ </span>
+</nav>
<main role="main" id="essay-archive" class="essay-archive archive-list">
<div class="essay-intro">
<h2>You're unsubscribed, so long friend</h2>
diff --git a/app/lttr/urls.py b/app/lttr/urls.py
index b4485d2..abeac11 100644
--- a/app/lttr/urls.py
+++ b/app/lttr/urls.py
@@ -6,32 +6,17 @@ app_name = "lttr"
urlpatterns = [
path(
- r'feed.xml',
- views.NewsletterRSSFeedView(),
- name="feed"
- ),
- path(
- 'unsubscribe/<str:activation_code>',
+ '<str:slug>/unsubscribe/<str:activation_code>',
views.UnsubscribeRequestView.as_view(),
name='newsletter_unsubscribe'
),
path(
- r'<int:issue>/<str:mailing>',
- views.NewsletterMailingDetail.as_view(),
- name="detail"
- ),
- path(
- r'subscribe/',
+ r'<str:slug>/subscribe/',
views.NewsletterSubscribeView.as_view(),
name="subscribe"
),
path(
- r'<int:page>',
- views.NewsletterListView.as_view(),
- name="list"
- ),
- path(
- 'activate/<str:activation_code>/',
+ '<str:slug>/activate/<str:activation_code>/',
views.ConfirmSubscriptionView.as_view(), name='newsletter_activate'
),
path(
@@ -39,15 +24,4 @@ urlpatterns = [
views.NewsletterSubscribedView.as_view(),
name="subscribed"
),
- path(
- r'',
- views.NewsletterListView.as_view(),
- {'page': 1},
- name="list"
- ),
- path(
- r'',
- views.NewsletterOptionsView.as_view(),
- name="newsletters"
- ),
]
diff --git a/app/lttr/views.py b/app/lttr/views.py
index 6a9cfd8..7f094c6 100644
--- a/app/lttr/views.py
+++ b/app/lttr/views.py
@@ -13,49 +13,16 @@ from django.urls import reverse, reverse_lazy
from utils.views import PaginatedListView, LuxDetailView
from smtplib import SMTPException
-from .models import NewsletterMailing, Subscriber, Newsletter
+from .models import OldNewsletterMailing, Subscriber, Newsletter
from .forms import SubscribeRequestForm, UpdateForm
ACTIONS = ('subscribe', 'unsubscribe', 'update')
-class NewsletterMailingDetail(LuxDetailView):
- model = NewsletterMailing
- slug_field = "slug"
- slug_url_kwarg = 'mailing'
-
- def get_queryset(self):
- queryset = super(NewsletterMailingDetail, self).get_queryset()
- return queryset.filter(issue=self.kwargs['issue'])
-
- def get_template_names(self):
- obj = self.get_object()
- return ["lttr/%s_detail.html" % obj.newsletter.slug, 'post_detail.html']
-
-
class NewsletterSubscribedView(TemplateView):
template_name = "lttr/subscribed.html"
-class NewsletterListView(ListView):
- """
- Return a list of Newsletter posts in reverse chronological order
- """
- model = NewsletterMailing
-
- def get_template_names(self):
- return ["lttr/%s_list.html" % self.kwargs['slug'], 'newsletter_list.html']
-
- def get_queryset(self):
- queryset = super(NewsletterListView, self).get_queryset()
- return queryset.filter(newsletter__slug=self.kwargs['slug']).order_by('-pub_date')
-
- def get_context_data(self, **kwargs):
- context = super(NewsletterListView, self).get_context_data(**kwargs)
- context['breadcrumbs'] = [self.kwargs['slug'],]
- return context
-
-
class NewsletterOptionsView(ListView):
model = Newsletter
@@ -137,19 +104,3 @@ class UnsubscribeRequestView(DetailView):
context['subscriber'] = self.get_object()
context['newsletter'] = self.kwargs['slug']
return context
-
-class NewsletterRSSFeedView(Feed):
- title = "Luxagraf: Range, A Weekly Photo"
- link = "/newsletter/range/"
- description = "Latest Range Newsletter"
- description_template = 'feeds/blog_description.html'
-
- def items(self):
- return NewsletterMailing.objects.filter(newsletter__slug='ranger',status__exact=1)
-
- def item_pubdate(self, item):
- """
- Takes an item, as returned by items(), and returns the item's
- pubdate.
- """
-
diff --git a/app/posts/build.py b/app/posts/build.py
index 9a7e2c1..b49b925 100644
--- a/app/posts/build.py
+++ b/app/posts/build.py
@@ -18,6 +18,7 @@ class BuildSrc(BuildNew):
paginate_by=50
)
self.build_detail_view()
+ self.build_feed("src:feed")
class BuildGuide(BuildNew):
@@ -121,3 +122,31 @@ class BuildEssays(BuildNew):
paginate_by=50
)
self.build_detail_view()
+
+
+class BuildRange(BuildNew):
+
+ def get_model_queryset(self):
+ return self.model.objects.filter(post_type=PostType.RANGE).filter(status__exact=1).order_by('-pub_date')
+
+ def build(self):
+ self.build_list_view(
+ base_path=reverse("range:range-list"),
+ paginate_by=30
+ )
+ self.build_detail_view()
+ self.build_feed("range:feed")
+
+
+class BuildFriends(BuildNew):
+
+ def get_model_queryset(self):
+ return self.model.objects.filter(post_type=PostType.FRIENDS).filter(status__exact=1).order_by('-pub_date')
+
+ def build(self):
+ self.build_list_view(
+ base_path=reverse("friends:friends-list"),
+ paginate_by=30
+ )
+ self.build_detail_view()
+ self.build_feed("friends:feed")
diff --git a/app/posts/models.py b/app/posts/models.py
index 6adae3b..21dd6d5 100644
--- a/app/posts/models.py
+++ b/app/posts/models.py
@@ -32,8 +32,6 @@ from books.models import Book
from taxonomy.models import TaggedItems, Category
from utils.util import render_images, render_products, parse_video, markdown_to_html, extract_main_image
-from lttr.models import Newsletter
-
def get_upload_path(self, filename):
return "images/post-images/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)
@@ -115,7 +113,7 @@ class Post(models.Model):
if self.post_type == PostType.JRNL:
return reverse('jrnl:detail', kwargs={"year": self.pub_date.year, "month": self.pub_date.strftime("%m"), "slug": self.slug})
if self.post_type == PostType.RANGE:
- return reverse('range:detail', kwargs={"issue": self.issue, "slug": self.slug})
+ return reverse('range:range-detail', kwargs={"issue": self.get_issue_str(), "slug": self.slug})
if self.post_type == PostType.FRIENDS:
return reverse('friends:friends-detail', kwargs={"issue": self.get_issue_str(), "slug": self.slug})
@@ -241,14 +239,6 @@ class PostModerator(CommentModerator):
return True
moderator.register(Post, PostModerator)
-#class PostMailing(models.Model):
-# newsletter = models.ForeignKey(Newsletter, null=True, on_delete=models.SET_NULL)
-# post = models.ForeignKey(Post, null=True, on_delete=models.SET_NULL)
-# body_email_html = models.TextField(blank=True)
-# issue = models.PositiveIntegerField()
-# date_sent = models.DateTimeField(blank=True, auto_now_add=True, editable=False)
-
-
@receiver(comment_was_posted, sender=Comment)
def cache_gravatar(sender, comment, **kwargs):
gravatar_exists = has_gravatar(comment.email)
diff --git a/app/posts/urls/friends_urls.py b/app/posts/urls/friends_urls.py
index 5998d08..b7f7608 100644
--- a/app/posts/urls/friends_urls.py
+++ b/app/posts/urls/friends_urls.py
@@ -7,6 +7,11 @@ app_name = "range"
urlpatterns = [
path(
+ r'feed.xml',
+ views.FriendsRSSFeedView(),
+ name="feed"
+ ),
+ path(
r'<int:issue>/<str:slug>',
views.FriendsDetailView.as_view(),
name="friends-detail"
@@ -15,6 +20,6 @@ urlpatterns = [
r'',
views.FriendsListView.as_view(),
{'page':1},
- name="friends-base"
+ name="friends-list"
),
]
diff --git a/app/posts/urls/range_urls.py b/app/posts/urls/range_urls.py
index 7b29569..16655d6 100644
--- a/app/posts/urls/range_urls.py
+++ b/app/posts/urls/range_urls.py
@@ -7,14 +7,19 @@ app_name = "range"
urlpatterns = [
path(
- r'<str:slug>',
+ r'feed.xml',
+ views.RangeRSSFeedView(),
+ name="feed"
+ ),
+ path(
+ r'<int:issue>/<str:slug>',
views.RangeDetailView.as_view(),
- name="detail"
+ name="range-detail"
),
path(
r'',
views.RangeListView.as_view(),
{'page':1},
- name="range-base"
+ name="range-list"
),
]
diff --git a/app/posts/views/friends_views.py b/app/posts/views/friends_views.py
index dd4dac2..3d6ea8d 100644
--- a/app/posts/views/friends_views.py
+++ b/app/posts/views/friends_views.py
@@ -37,3 +37,18 @@ class FriendsListView(PaginatedListView):
return context
+class FriendsRSSFeedView(Feed):
+ title = "Friends of a Long Year"
+ link = "/range/"
+ description = "Friends of a Long Year: A monthly newsletter"
+ description_template = 'feeds/blog_description.html'
+
+ def items(self):
+ return Post.objects.filter(status__exact=1).filter(post_type=PostType.FRIENDS).order_by('-pub_date')[:10]
+
+ def item_pubdate(self, item):
+ """
+ Takes an item, as returned by items(), and returns the item's
+ pubdate.
+ """
+ return item.pub_date
diff --git a/app/posts/views/range_views.py b/app/posts/views/range_views.py
index 989134d..0a3a564 100644
--- a/app/posts/views/range_views.py
+++ b/app/posts/views/range_views.py
@@ -37,3 +37,18 @@ class RangeListView(PaginatedListView):
return context
+class RangeRSSFeedView(Feed):
+ title = "Range: A weekly photo, developed"
+ link = "/range/"
+ description = "Range: A weekly photo, developed"
+ description_template = 'feeds/blog_description.html'
+
+ def items(self):
+ return Post.objects.filter(status__exact=1).filter(post_type=PostType.RANGE).order_by('-pub_date')[:10]
+
+ def item_pubdate(self, item):
+ """
+ Takes an item, as returned by items(), and returns the item's
+ pubdate.
+ """
+ return item.pub_date