summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/blog/admin.py16
-rw-r--r--app/blog/models.py3
-rw-r--r--app/blog/urls.py37
-rw-r--r--app/blog/views.py34
-rw-r--r--app/links/__init__.py0
-rw-r--r--app/links/admin.py32
-rw-r--r--app/links/build.py22
-rw-r--r--app/links/migrations/0001_initial.py43
-rw-r--r--app/links/migrations/0002_auto_20190501_1054.py44
-rw-r--r--app/links/migrations/__init__.py0
-rw-r--r--app/links/models.py46
-rw-r--r--app/links/urls.py39
-rw-r--r--app/links/views.py65
-rw-r--r--config/base_urls.py7
-rw-r--r--config/requirements.txt1
-rw-r--r--design/sass/_content.scss266
-rw-r--r--design/sass/_fonts.scss14
-rw-r--r--design/sass/_footer.scss76
-rw-r--r--design/sass/_global.scss95
-rw-r--r--design/sass/_header.scss79
-rw-r--r--design/sass/_mixins.scss20
-rw-r--r--design/templates/base.html33
-rw-r--r--design/templates/blog/entry_detail.html62
-rw-r--r--design/templates/blog/entry_list.html18
-rw-r--r--design/templates/homepage.html88
-rw-r--r--design/templates/links/link_detail.html13
-rw-r--r--design/templates/links/link_list.html15
-rw-r--r--design/templates/pages/page.html12
28 files changed, 716 insertions, 464 deletions
diff --git a/app/blog/admin.py b/app/blog/admin.py
index 6a4749f..b3093f6 100644
--- a/app/blog/admin.py
+++ b/app/blog/admin.py
@@ -18,8 +18,9 @@ class EntryAdmin(admin.ModelAdmin):
'sub_title',
'body_markdown',
('pub_date', 'status'),
+ 'tags',
'meta_description',
- ('slug', 'enable_comments', 'has_code'),
+ 'slug',
),
'classes': (
'show',
@@ -27,19 +28,6 @@ class EntryAdmin(admin.ModelAdmin):
'wide'
)
}),
- ('meta', {
- 'fields': (
- 'originally_published_by',
- 'originally_published_by_url',
- 'afterword',
- ('field_notes', 'books'),
- ),
- 'classes': (
- 'hide',
- 'extrapretty',
- 'wide'
- )
- }),
)
class Media:
diff --git a/app/blog/models.py b/app/blog/models.py
index 3d1ae30..61ac407 100644
--- a/app/blog/models.py
+++ b/app/blog/models.py
@@ -27,7 +27,6 @@ class Entry(models.Model):
status = models.IntegerField(choices=PUB_STATUS, default=0)
meta_description = models.CharField(max_length=256, null=True, blank=True)
tags = TaggableManager(through=TaggedItems, blank=True, help_text='Topics Covered')
- featured_image = models.ForeignKey(LuxImage, on_delete=models.CASCADE, null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
@@ -39,7 +38,7 @@ class Entry(models.Model):
return self.title
def get_absolute_url(self):
- return reverse('essays:detail', kwargs={"slug": self.slug})
+ return reverse("blog:detail", kwargs={"year": self.pub_date.year, "month": self.pub_date.strftime("%m"), "slug": self.slug})
def comment_period_open(self):
return self.enable_comments and datetime.datetime.today() - datetime.timedelta(30) <= self.pub_date
diff --git a/app/blog/urls.py b/app/blog/urls.py
index da3e1fd..0e9a55c 100644
--- a/app/blog/urls.py
+++ b/app/blog/urls.py
@@ -5,24 +5,35 @@ from . import views
app_name = "blog"
urlpatterns = [
- #path(
- # r'topic/<str:slug>',
- # views.TopicListView.as_view(),
- # name="list_topics"
- #),
- path(
- r'<str:slug>',
+ re_path(
+ r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+).txt$',
+ views.EntryDetailViewTXT.as_view(),
+ name="detail-txt"
+ ),
+ re_path(
+ r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)$',
views.EntryDetailView.as_view(),
name="detail"
),
- path(
- r'<str:slug>',
- views.EntryDetailViewTXT.as_view(),
- name="detail-txt"
+ re_path(
+ r'^(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',
+ views.EntryMonthArchiveView.as_view(month_format='%m'),
+ name="list_month"
+ ),
+ re_path(
+ r'(?P<year>\d{4})/$',
+ views.EntryYearArchiveView.as_view(),
+ name="list_year"
+ ),
+ re_path(
+ r'^(?P<page>\d+)/$',
+ views.EntryListView.as_view(),
+ name="list"
),
- path(
+ re_path(
r'',
views.EntryListView.as_view(),
- name="list",
+ {'page': 1},
+ name="list"
),
]
diff --git a/app/blog/views.py b/app/blog/views.py
index 56bd823..cf0fdf6 100644
--- a/app/blog/views.py
+++ b/app/blog/views.py
@@ -1,9 +1,13 @@
+from operator import attrgetter
+from itertools import chain
from django.views.generic import ListView
from django.views.generic.detail import DetailView
+from django.views.generic.dates import YearArchiveView, MonthArchiveView
from django.contrib.syndication.views import Feed
from .models import Entry
+from links.models import Link
class EntryListView(ListView):
@@ -22,6 +26,36 @@ class EntryDetailViewTXT(EntryDetailView):
template_name = "entry_detail.txt"
+class EntryYearArchiveView(YearArchiveView):
+ queryset = Entry.objects.filter(status__exact=1).select_related()
+ date_field = "pub_date"
+ make_object_list = True
+ allow_future = True
+
+
+class EntryMonthArchiveView(MonthArchiveView):
+ queryset = Entry.objects.filter(status__exact=1).select_related()
+ date_field = "pub_date"
+ allow_future = True
+
+
+class HomePageView(ListView):
+ model = Entry
+ template_name = "homepage.html"
+
+ def get_queryset(self, **kwargs):
+ entry_list = Entry.objects.filter(status=1)
+ link_list = Link.objects.filter(status=1)
+ result_list = sorted(
+ chain(entry_list, link_list),
+ key=attrgetter('pub_date')
+ )
+ return reversed(result_list)
+
+
+
+
+
'''
class TopicListView(ListView):
template_name = 'archives/src_home.html'
diff --git a/app/links/__init__.py b/app/links/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/links/__init__.py
diff --git a/app/links/admin.py b/app/links/admin.py
new file mode 100644
index 0000000..9ee9fbf
--- /dev/null
+++ b/app/links/admin.py
@@ -0,0 +1,32 @@
+from django.contrib import admin
+
+from utils.widgets import LGEntryForm
+
+from .models import Link
+
+
+@admin.register(Link)
+class EntryAdmin(admin.ModelAdmin):
+ form = LGEntryForm
+ list_display = ('title', 'pub_date', 'status')
+ list_filter = ('pub_date', 'status')
+ prepopulated_fields = {"slug": ('title',)}
+ fieldsets = (
+ ('Link', {
+ 'fields': (
+ 'title',
+ 'body_markdown',
+ 'slug',
+ 'link_url',
+ ('pub_date', 'status'),
+ ),
+ 'classes': (
+ 'show',
+ 'extrapretty',
+ 'wide'
+ )
+ }),
+ )
+
+ class Media:
+ js = ('next-prev-links.js')
diff --git a/app/links/build.py b/app/links/build.py
new file mode 100644
index 0000000..392e991
--- /dev/null
+++ b/app/links/build.py
@@ -0,0 +1,22 @@
+import os
+from builder.base import BuildNew
+from django.urls import reverse
+from . import models
+
+
+class BuildEssays(BuildNew):
+
+ def build(self):
+ self.build_list_view()
+ self.build_detail_view()
+ # These are the unique classes for this model:
+ #self.build_feed("src:feed")
+
+ def build_list_view(self):
+ response = self.client.get('/essays/')
+ self.write_file('essays/', response.content)
+
+
+def essaybuilder():
+ j = BuildEssays("essays", "essay")
+ j.build()
diff --git a/app/links/migrations/0001_initial.py b/app/links/migrations/0001_initial.py
new file mode 100644
index 0000000..be54329
--- /dev/null
+++ b/app/links/migrations/0001_initial.py
@@ -0,0 +1,43 @@
+# Generated by Django 2.1.7 on 2019-03-30 17:07
+
+from django.db import migrations, models
+import django.db.models.deletion
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('photos', '0001_initial'),
+ ('taxonomy', '__first__'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Entry',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=200)),
+ ('sub_title', models.CharField(blank=True, max_length=200)),
+ ('dek', models.TextField(blank=True)),
+ ('slug', models.SlugField(unique_for_date='pub_date')),
+ ('body_html', models.TextField(blank=True)),
+ ('body_markdown', models.TextField()),
+ ('pub_date', models.DateTimeField(verbose_name='Date published')),
+ ('last_updated', models.DateTimeField(auto_now=True)),
+ ('enable_comments', models.BooleanField(default=False)),
+ ('status', models.IntegerField(choices=[(0, 'Draft'), (1, 'Published')], default=0)),
+ ('meta_description', models.CharField(blank=True, max_length=256, null=True)),
+ ('category', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='taxonomy.Category')),
+ ('featured_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='photos.LuxImage')),
+ ('tags', taggit.managers.TaggableManager(blank=True, help_text='Topics Covered', through='taxonomy.TaggedItems', to='taxonomy.LuxTag', verbose_name='Tags')),
+ ],
+ options={
+ 'get_latest_by': 'pub_date',
+ 'verbose_name_plural': 'Essays',
+ 'ordering': ('-pub_date',),
+ },
+ ),
+ ]
diff --git a/app/links/migrations/0002_auto_20190501_1054.py b/app/links/migrations/0002_auto_20190501_1054.py
new file mode 100644
index 0000000..b4ca5d1
--- /dev/null
+++ b/app/links/migrations/0002_auto_20190501_1054.py
@@ -0,0 +1,44 @@
+# Generated by Django 2.1.7 on 2019-05-01 15:54
+
+from django.db import migrations, models
+import taggit.managers
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('taxonomy', '0001_initial'),
+ ('links', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Link',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(max_length=200)),
+ ('link_url', models.URLField(max_length=400)),
+ ('pub_date', models.DateTimeField(verbose_name='Date published')),
+ ('slug', models.SlugField(unique_for_date='pub_date')),
+ ('body_html', models.TextField(blank=True)),
+ ('body_markdown', models.TextField()),
+ ('status', models.IntegerField(choices=[(0, 'Draft'), (1, 'Published')], default=0)),
+ ('tags', taggit.managers.TaggableManager(blank=True, help_text='Topics Covered', through='taxonomy.TaggedItems', to='taxonomy.LuxTag', verbose_name='Tags')),
+ ],
+ ),
+ migrations.RemoveField(
+ model_name='entry',
+ name='category',
+ ),
+ migrations.RemoveField(
+ model_name='entry',
+ name='featured_image',
+ ),
+ migrations.RemoveField(
+ model_name='entry',
+ name='tags',
+ ),
+ migrations.DeleteModel(
+ name='Entry',
+ ),
+ ]
diff --git a/app/links/migrations/__init__.py b/app/links/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/links/migrations/__init__.py
diff --git a/app/links/models.py b/app/links/models.py
new file mode 100644
index 0000000..518ba33
--- /dev/null
+++ b/app/links/models.py
@@ -0,0 +1,46 @@
+from django.db import models
+from django.urls import reverse
+from django.contrib.sitemaps import Sitemap
+
+from taggit.managers import TaggableManager
+
+from taxonomy.models import TaggedItems
+from utils.util import render_images, markdown_to_html
+
+
+class Link(models.Model):
+ title = models.CharField(max_length=200)
+ link_url = models.URLField(max_length=400)
+ pub_date = models.DateTimeField('Date published')
+ slug = models.SlugField(unique_for_date='pub_date')
+ tags = TaggableManager(through=TaggedItems, blank=True, help_text='Topics Covered')
+ body_html = models.TextField(blank=True)
+ body_markdown = models.TextField()
+ PUB_STATUS = (
+ (0, 'Draft'),
+ (1, 'Published'),
+ )
+ status = models.IntegerField(choices=PUB_STATUS, default=0)
+
+ def __str__(self):
+ return self.title
+
+ def get_absolute_url(self):
+ return reverse("links:detail", kwargs={"year": self.pub_date.year, "month": self.pub_date.strftime("%m"), "slug": self.slug})
+
+ def save(self):
+ md = render_images(self.body_markdown)
+ self.body_html = markdown_to_html(md)
+ super(Link, self).save()
+
+
+class LinkedSitemap(Sitemap):
+ changefreq = "weekly"
+ priority = 0.8
+ protocol = "https"
+
+ def items(self):
+ return Link.objects.filter(status=1)
+
+ def lastmod(self, obj):
+ return obj.pub_date
diff --git a/app/links/urls.py b/app/links/urls.py
new file mode 100644
index 0000000..fb18532
--- /dev/null
+++ b/app/links/urls.py
@@ -0,0 +1,39 @@
+from django.urls import path, re_path
+
+from . import views
+
+app_name = "links"
+
+urlpatterns = [
+ re_path(
+ r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+).txt$',
+ views.EntryDetailViewTXT.as_view(),
+ name="detail-txt"
+ ),
+ re_path(
+ r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)$',
+ views.EntryDetailView.as_view(),
+ name="detail"
+ ),
+ re_path(
+ r'^(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',
+ views.EntryMonthArchiveView.as_view(month_format='%m'),
+ name="list_month"
+ ),
+ re_path(
+ r'(?P<year>\d{4})/$',
+ views.EntryYearArchiveView.as_view(),
+ name="list_year"
+ ),
+ re_path(
+ r'^(?P<page>\d+)/$',
+ views.EntryListView.as_view(),
+ name="list"
+ ),
+ re_path(
+ r'',
+ views.EntryListView.as_view(),
+ {'page': 1},
+ name="list"
+ ),
+]
diff --git a/app/links/views.py b/app/links/views.py
new file mode 100644
index 0000000..64cc5f7
--- /dev/null
+++ b/app/links/views.py
@@ -0,0 +1,65 @@
+from django.views.generic import ListView
+from django.views.generic.detail import DetailView
+from django.views.generic.dates import YearArchiveView, MonthArchiveView
+from django.contrib.syndication.views import Feed
+
+
+from .models import Link
+
+
+class EntryListView(ListView):
+ model = Link
+
+ def get_queryset(self, **kwargs):
+ qs = Link.objects.filter(status=1)
+ return qs
+
+
+class EntryDetailView(DetailView):
+ model = Link
+
+
+class EntryDetailViewTXT(EntryDetailView):
+ template_name = "entry_detail.txt"
+
+
+
+class EntryYearArchiveView(YearArchiveView):
+ queryset = Link.objects.filter(status__exact=1).select_related()
+ date_field = "pub_date"
+ make_object_list = True
+ allow_future = True
+
+
+class EntryMonthArchiveView(MonthArchiveView):
+ queryset = Link.objects.filter(status__exact=1).select_related()
+ date_field = "pub_date"
+ allow_future = True
+
+
+
+
+
+'''
+class TopicListView(ListView):
+ template_name = 'archives/src_home.html'
+
+ def queryset(self):
+ return Post.objects.filter(topics__slug=self.kwargs['slug'])
+
+ def get_context_data(self, **kwargs):
+ # Call the base implementation first to get a context
+ context = super(TopicListView, self).get_context_data(**kwargs)
+ context['topic'] = Topic.objects.get(slug__exact=self.kwargs['slug'])
+ return context
+
+
+class SrcRSSFeedView(Feed):
+ title = "luxagraf:src Code and Technology"
+ link = "/src/"
+ description = "Latest postings to luxagraf.net/src"
+ description_template = 'feeds/blog_description.html'
+
+ def items(self):
+ return Post.objects.filter(status__exact=1).order_by('-pub_date')[:10]
+'''
diff --git a/config/base_urls.py b/config/base_urls.py
index ed7da2d..cbc9517 100644
--- a/config/base_urls.py
+++ b/config/base_urls.py
@@ -4,7 +4,8 @@ from django.conf.urls.static import static
from django.conf import settings
from django.contrib.sitemaps.views import sitemap
-from pages.views import PageDetailView, HomePageDetailView
+from pages.views import PageDetailView
+from blog.views import HomePageView
#import builder.views
import utils.views
import builder.views
@@ -18,9 +19,11 @@ urlpatterns = [
path(r'admin/', admin.site.urls),
#path(r'luximages/insert/', utils.views.insert_image),
#path(r'sitemap.xml', sitemap, {'sitemaps': sitemaps}),
+ path(r'essays/', include('blog.urls')),
+ path(r'linked/', include('links.urls')),
path(r'<slug>', PageDetailView.as_view()),
path(r'<path>/<slug>/', PageDetailView.as_view()),
- path(r'', HomePageDetailView.as_view()),
+ path(r'', HomePageView.as_view()),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
diff --git a/config/requirements.txt b/config/requirements.txt
index a75a0c8..be0d327 100644
--- a/config/requirements.txt
+++ b/config/requirements.txt
@@ -14,6 +14,7 @@ ipython==7.4.0
ipython-genutils==0.2.0
jedi==0.13.3
Jinja2==2.10
+jsmin==2.2.2
lxml==4.3.3
Markdown==3.1
MarkupSafe==1.1.1
diff --git a/design/sass/_content.scss b/design/sass/_content.scss
index 9a81b64..598d63e 100644
--- a/design/sass/_content.scss
+++ b/design/sass/_content.scss
@@ -1,236 +1,74 @@
-.hero-wrapper {
- @include fancy_sans;
- padding: 5rem 0 0;
- &:after {
- @include faded_line_after;
- margin-top: 4rem;
- margin-bottom: 4rem;
- padding: 0;
- }
-}
-.circle-pic {
- border-radius: 50%;
- border: 5px solid #000;
-}
-.btn {
- @include fontsize(14);
- display: inline-block;
- border-radius: 4px;
- @include fancy_sans;
- @include smcaps;
- -webkit-appearance: none;
- text-decoration: none;
- cursor: pointer;
- background: $link_color;
- color: #fff !important;
- border: 1px solid $link_color;
- padding: 7px 9px;
- white-space: nowrap;
- &:hover {
- background: $link_hover_color;
- border: 1px solid $link_hover_color;
- }
+.content-narrow {
+ margin-top: 3rem;
+ @include constrain_narrow;
}
-.btn-small {
- @include fontsize(10);
- @include smcaps;
-}
-.btn-hollow {
- @include fontsize(17);
- padding: 6px 8px;
- border: none; //1px solid $body_font_light;
- color: $link_color !important;
- outline: $link_color !important;
- background: white;
- border: 1px solid $link_color;
- &:hover {
- background: $link_color !important;
- color: white !important;
- }
-}
-.hed-alpha {
- @include fancy_serif;
- line-height: 1.2;
- font-weight: 600;
-}
-.hed-beta {
- line-height: 1.4;
-}
-.hed-gamma {
- line-height: 1.4;
- @include fontsize(20);
- @include fancy_sans;
- text-align: center;
- letter-spacing: 1px;
- margin: 0 auto;
-}
-.hed-delta {
- @include fancy_sans;
- @include fontsize(22);
- font-weight: bold;
- margin-bottom: .5em;
-}
-.hed-epsilon {
- @include fontsize(14);
- @include fancy_sans;
- text-transform: uppercase;
- letter-spacing: 1px;
- font-weight: bold;
- color: $body_font_light;
- line-height: 1.2;
- text-align: center;
- margin: 0;
+.post-header {
+ @extend %clearfix;
+ padding-bottom: 2.6rem;
+ border-bottom: 1px solid #efefef;
}
.hed-border {
display: inline-block;
border-bottom: 3px solid #efefef;
width: auto;
}
-.hero {
- .hero-pic {
- max-width: 50%;
- margin: 1.5rem auto;
- }
- h3.hed-alpha {
- @include fontsize(24);
- }
- .hed-beta {
- @include fancy_sans;
- @include fontsize(22);
- margin: .5rem auto;
- text-align: center;
- &:last-of-type:after {
- @include faded_line_after;
- margin-top: 2rem;
- margin-bottom: 2rem;
- }
- }
- @include breakpoint(beta) {
- display: flex;
- align-items: flex-start;
- align-content: flex-start;
- .hero-text {
- margin-left: 5rem;
- & > * {
- text-align: left;
- }
- }
- p {
- width: 90%;
- @include fontsize(20);
- }
- .btn {
- margin-top: 1.5rem;
- }
- }
-}
-.home {
- h4 {
- @include fancy_sans;
- text-align: center;
- letter-spacing: 1px;
- }
- hr {
- border-top: 3px solid #efefef;
- margin: 5em auto;
- width: 40%;
- }
-}
-.border-wrapper {
- margin: 2rem auto 0;
-}
-.home-logos {
- display: flex;
- flex-wrap: wrap;
- align-items: center;
- justify-content: center;
- width: 100%;
- li {
- margin: 0 .5rem;
- }
- img {
- max-width: 80px;
- }
+.flex {
@include breakpoint(gamma) {
- @include constrain_wide;
- margin: 0 auto;
- img {
- max-width: 120px;
- }
+ display: flex;
+ justify-content: center ;
}
}
-
-.home-border-wrapper {
- @include breakpoint(beta) {
- margin-top: 4rem;
- .btn {
- margin-bottom: 4rem;
- }
- }
- &:before {
- @include faded_line_after;
- margin-top: 0;
- margin-bottom: 5rem;
+article ul {
+ list-style-type: none;
+ @include fontsize(22);
+ li:before {
+ content: "";
+ border: 2px #000 solid !important;
+ border-radius: 50px;
+ margin-top: 16px;
+ margin-left: -12px;
+ position: absolute;
}
}
-.card-image {
- max-height: 10rem;
- overflow: hidden;
- border: 4px $body_font_color solid;
- img {
- width: 100%;
- margin-top: -14%;
+.archive-list {
+ @include constrain_narrow;
+ text-align: left;
+ ul {
+ padding: 0;
+ list-style-type: none;
}
-}
-.home-card-wrapper {
- @include breakpoint(beta) {
- margin-top: 4rem;
- .btn {
- margin-bottom: 4rem;
+ a {
+ text-decoration: none;
+ color: lighten($body_font_color, 20);
+ &:hover {
+ color: $link_color;
}
}
- &:after {
- @include faded_line_after;
- margin-top: 0;
- margin-bottom: 5rem;
- }
-}
-.card {
- margin: 4rem auto;
p {
- margin-top: .5rem;
- @include fontsize(18);
- }
- h5 {
- @include fontsize(24);
- text-align: center;
- margin: 1rem 0 0 0;
- }
- &:after {
- @include faded_line_after;
- }
- &:last-of-type:after {
- display: none;
- }
- @include breakpoint(beta) {
- flex-grow: 1;
- flex-shrink: 1;
- flex-basis: 0;
- margin-top: 0;
- margin-right: 2rem;
- &:last-of-type {
- margin-right: 0;
- }
- &:after {
- display: none;
- }
+ margin: 0;
+ @include fontsize(20);
+ font-style: italic;
}
}
-.flex {
- @include breakpoint(gamma) {
- display: flex;
- justify-content: center ;
+.post-linewrapper {
+ margin-top: 1rem;
+ padding-top: 1rem;
+ display: inline-block;
+ margin-left: 0;
+ border-top: 2px solid darken($body_color, 8);
+ float: left;
+}
+
+.star {
+ color: transparent;
+ text-shadow: 0 0 0 lighten($body_font_color, 50);
+ text-decoration: none;
+ @include fontsize(22);
+ padding: 0 6px 3px 6px;
+ font-family: "Hiragino Kaku Gothic Pro", "Osaka", "Zapf Dingbats";
+ &:hover {
+ background: darken(#fff, 10);
}
}
diff --git a/design/sass/_fonts.scss b/design/sass/_fonts.scss
index 77f6f7c..b80bc6b 100644
--- a/design/sass/_fonts.scss
+++ b/design/sass/_fonts.scss
@@ -33,3 +33,17 @@
font-style: normal;
}
+@font-face {
+ font-family: 'sortsmill';
+ src: url('/media/fonts/oflgoudystmtt-webfont.woff2') format('woff2');
+ src: url('/media/fonts/oflgoudystmtt-webfont.woff') format('woff');
+ font-weight: 400;
+ font-style: normal;
+}
+@font-face {
+ font-family: 'sortsmill';
+ src: url('/media/fonts/oflgoudystmtt-italic-webfont.woff2') format('woff2');
+ src: url('/media/fonts/oflgoudystmtt-italic-webfont.woff') format('woff');
+ font-weight: 400;
+ font-style: italic;
+}
diff --git a/design/sass/_footer.scss b/design/sass/_footer.scss
index 1ff56b9..d326d4a 100644
--- a/design/sass/_footer.scss
+++ b/design/sass/_footer.scss
@@ -1,54 +1,50 @@
footer {
- margin-top: 5em;
+ @include constrain_wide;
+ margin-top: 6rem;
+ margin-bottom: 1rem;
@include breakpoint(gamma) {
max-width: 960;
+ margin-top: 8rem;
+ margin-bottom: 3rem;
}
&:before {
- @include breakpoint(beta) {
- @include faded_line_after;
- margin-bottom: 1.2em;
- }
- }
- .footer-nav {
- list-style-type: none !important;
- margin-left: 0 !important;
- border-top: 1px $body_font_color dotted;
- border-bottom: 1px $body_font_color dotted;
- padding: .5rem 0;
- @include breakpoint(beta) {
- border: none;
- }
+ @include faded_line_after;
+ margin-bottom: 2em;
}
- li {
- display: inline;
- margin: 0 .25em;
- &:after {
- content: "\00b7";
- color: #999999;
- padding-left: 0.75em;
+ .footer-nav-menu {
+ padding: 0;
+ text-align: center;
+ margin-bottom: 1rem;
+ li {
+ display: inline;
+ margin: 0 auto;
+ &:after {
+ content: "/";
+ color: #999999;
+ padding-left: 0.75em;
+ }
+ a {
+ color: $secondary-link-color;
+ text-decoration: none;
+ }
}
- a {
- color: $secondary-link-color;
- text-decoration: none;
+ li:last-of-type {
+ margin-right: 0;
+ &:after {
+ content: " ";
+ }
}
- ul { display:inline;}
- }
- li:last-of-type {
- margin-right: 0;
- &:after {
- content: " ";
+ @include breakpoint(beta) {
+ float: right;
+ text-align: left;
}
}
p {
- @include fontsize(10);
text-align: center;
- margin-top: 1.5em;
- margin-bottom: 1.5em;
+ a { text-decoration: none; }
+ @include breakpoint(beta) {
+ float: left;
+ text-align: left;
+ }
}
}
-#license {
- @include fancy_sans;
- @include fontsize(12);
- text-transform: none;
- letter-spacing: normal;
-}
diff --git a/design/sass/_global.scss b/design/sass/_global.scss
index 719d23a..8e3e435 100644
--- a/design/sass/_global.scss
+++ b/design/sass/_global.scss
@@ -1,18 +1,17 @@
html {
border-top: 0.25em solid $body_font_color;
}
-
body {
margin: 0 auto;
padding: 0;
overflow-x: hidden;
font:$body_p_font;
color: $body_font_color;
- text-align: center;
- background-color: transparent
+ text-align: left;
+ background-color: $body_color;
}
ul {
- padding: 0;
+ text-align: left;
}
// eliminate touch delay on mobile safari
a, button, input, select, textarea, label, summary {
@@ -46,9 +45,10 @@ p {
}
}
time {
- @include smcaps;
- @include fontsize(11);
display: block;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ @include fontsize(11);
span {
@include fontsize(13);
}
@@ -63,6 +63,12 @@ pre {
line-height: 1.5;
}
}
+p code {
+ font-family: Inconsolata, Consolas, Courier New, monospace;
+ font-size: 96%;
+ background: darken($body_color, 8);
+ padding: 1px 3px;
+}
object, embed, video {
max-width: 100%;
width: 100%;
@@ -75,9 +81,9 @@ audio {
blockquote {
@include fontsize(18);
display: block;
- border-top: 4px solid lighten($body_font_light, 20);
- border-bottom: 4px solid lighten($body_font_light, 20);
margin: 3rem 0;
+ padding-left: 1rem;
+ border-left: 2px solid lighten($body_font_color, 40);
position: relative;
text-align: left;
font-style: italic;
@@ -85,6 +91,9 @@ blockquote {
display: block;
text-align: right;
}
+ p {
+ @include fontsize(18);
+ }
@include breakpoint(alpha){
@include fontsize(20);
line-height: 1.5;
@@ -92,21 +101,12 @@ blockquote {
@include breakpoint(beta){
@include fontsize(22);
line-height: 1.6;
+ margin-left: 1rem;
+ p {
+ @include fontsize(20);
+ }
}
}
-blockquote:before {
- @include fancy_sans;
- @include fontsize(68);
- content: '\201C';
- position: absolute;
- top: -1.35rem;
- left: 50%;
- transform: translate(-50%, -50%);
- width: 3rem;
- height: 2rem;
- color: #666;
- text-align: center;
-}
hr {
border: 0;
height: 1px;
@@ -129,7 +129,7 @@ figcaption, figcaption a {
line-height: 1.9;
padding: .3rem .5rem .3rem 0;
color: #666;
- border-bottom: 1px lighten($body_font_light, 20) solid;
+ border-bottom: 1px lighten($body_font_color, 40) solid;
margin-bottom: 1rem;
}
figcaption a:visited {
@@ -161,6 +161,8 @@ h3 {
}
h4 {
@include fontsize(20);
+ @include fancy_sans;
+ font-weight: bold;
text-align: left;
@include breakpoint(gamma){
@include fontsize(22);
@@ -175,19 +177,50 @@ h5 {
line-height: 1.4;
}
}
-.subhead {
- font-size: 26px !important;
+//************** Universals ************************
+.hed-primary {
+ @include fancy_serif;
+ @include fontsize(28);
+ margin: .25rem 0;
+ line-height: 1.2;
+ font-weight: 400;
+ @include breakpoint(delta) {
+ @include fontsize(32);
+ margin-top: 0;
+ }
+}
+.hed-secondary {
+ @include fancy_serif;
+ @include fontsize(20);
+ margin: 0;
font-style: italic;
- margin-top: 0;
- margin-bottom: 0;
+ line-height: 1.2;
}
-.subhead + p {
- margin-top: .75rem !important;
+.hed-tertiary, .nav-menu {
+ @include fancy_sans;
+ @include fontsize(14);
+ font-weight: bold;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ margin: 0;
+ line-height: 1.3;
+ color: lighten($body_font_color, 40);
+ a {
+ color: lighten($body_font_color, 40);
+ }
}
-.essay-intro .subhead + p:first-of-type {
- margin-top: .75rem !important;
+.blok {
+ display: block;
+ margin: 0;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ @include fontsize(13);
+ @include fancy_sans;
+ letter-spacing: 1px;
+ font-weight: bold;
+ color: lighten($body_font_color, 40);
+ text-align: left;
}
-//************** Universals ************************
.hide {
display: none;
}
diff --git a/design/sass/_header.scss b/design/sass/_header.scss
index 431897e..c5d9ed1 100644
--- a/design/sass/_header.scss
+++ b/design/sass/_header.scss
@@ -1,31 +1,8 @@
-.header-wrapper {
-}
-
-#logo {
- a {
- @include fontsize(32);
- line-height: 1;
- text-decoration: none;
- display: block;
- font-weight: 300;
- font-family: 'carrois_gothicregular', Helvetica, sans-serif;
- color: $body_font_color;
- }
- .tagline {
- display: block;
- @include fancy_sans;
- @include smcaps;
- @include fontsize(12);
- font-style: normal;
- margin-left: 2px;
- }
-}
.site-banner {
@extend %clearfix;
margin: 0 auto;
@include constrain_wide;
- @include smcaps;
- nav {
+ .nav-menu {
border-top: 1px #444444 dotted;
border-bottom: 1px #444444 dotted;
//box-shadow: 0 3px 8px 0 #e6e6e6
@@ -35,22 +12,18 @@
margin-left: -20px;
margin-top: 1em;
padding: 0.25em 0.5em;
- a {
+ a {
+ @include fontsize(15);
text-decoration: none;
- color: #505050;
- &:visited {
- color: #505050
- }
+ font-weight: bold;
+ color: lighten($body_font_color, 30);
}
ul {
- @include smcaps;
- @include fancy_sans;
- @include fontsize(15);
max-width: 100%;
- font-weight: 600;
margin-top: 0.5em;
margin-bottom: 0.5em !important;
padding: 0;
+ text-align: center;
@include constrain(85%);
}
li {
@@ -68,8 +41,6 @@
}
}
}
- @include breakpoint(beta) {
- }
}
@include breakpoint(beta) {
height: 90px;
@@ -101,22 +72,22 @@
margin-top: -30px;
}
}
- nav {
+ .nav-menu {
float: right;
border: none;
margin: 22px 0 0 0;
padding: 0;
ul {
max-width: 50em;
+ text-align: left;
}
}
}
}
-
.header-wrapper {
@extend %clearfix;
@include breakpoint(beta) {
- border-bottom: 1px #f3efef solid;
+ border-bottom: 1px darken(#fff, 10) solid;
position: relative;
}
@include breakpoint(gamma) {
@@ -133,3 +104,35 @@
max-width: $max_width;
}
}
+#logo {
+ a {
+ @include fontsize(34);
+ line-height: 1;
+ text-decoration: none;
+ display: block;
+ font-weight: 300;
+ font-family: 'carrois_gothicregular', Helvetica, sans-serif;
+ text-transform: uppercase;
+ color: $body_font_color;
+ text-align: center;
+ margin-top: 1.3rem;
+ @include breakpoint(beta) {
+ text-align: left;
+ @include fontsize(32);
+ }
+ }
+ .tagline {
+ display: block;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ @include fancy_sans;
+ @include fontsize(13);
+ font-style: normal;
+ margin-left: 2px;
+ text-align: center;
+ @include breakpoint(beta) {
+ text-align: left;
+ @include fontsize(12);
+ }
+ }
+}
diff --git a/design/sass/_mixins.scss b/design/sass/_mixins.scss
index f12888e..6bd5e1b 100644
--- a/design/sass/_mixins.scss
+++ b/design/sass/_mixins.scss
@@ -1,21 +1,15 @@
-
+$body_color: darken(#fff, 3);
$body_p_font: normal 100% / 1.5 Georgia, Cambria, "Times New Roman", Times, serif;
$body_font_color: #222;
$link_color: #b53a04;
-$body_font_light: #787474;
$secondary-link-color: #838383;
-$narrow-beta-width: 720px;
-$narrow-max-width: 750px;
+$narrow-beta-width: 680px;
+$narrow-max-width: 720px;
$max_width: 1140px;
$link_hover_color: #b53a04;
$home-palette-primary: #14cfe7;
-@mixin smcaps {
- @include fancy_sans;
- text-transform: uppercase;
- letter-spacing: 1px;
-}
@function calc-rem($size) {
$remsize: $size/16;
@return #{$remsize}rem;
@@ -35,7 +29,7 @@ $home-palette-primary: #14cfe7;
font-family: mffnweb, Helvetica, sans-serif;
}
@mixin fancy-serif {
- font-family: mffweb, Georgia, 'Times New Roman', serif;
+ font-family: mffweb, 'PT Serif', Georgia, 'Times New Roman', serif;
}
%clearfix {
*zoom: 1;
@@ -50,12 +44,6 @@ $home-palette-primary: #14cfe7;
}
}
-@mixin transparent_class {
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=90)";
- filter: alpha(opacity = 90);
- opacity: 0.9;
-}
-
@mixin faded_line_after {
display: block;
content: "";
diff --git a/design/templates/base.html b/design/templates/base.html
index 41a8033..9be4f51 100644
--- a/design/templates/base.html
+++ b/design/templates/base.html
@@ -7,17 +7,16 @@
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description"
- content="{% block metadescription %}Scott Gilbertson is a Technical Writer, Copywriter and Editor helping your company increase its online content to boost your traffic and attract new leads. {% endblock %}">
+ content="{% block metadescription %}{% endblock %}">
<meta name="author" content="Scott Gilbertson">
<link rel="alternate"
type="application/rss+xml"
title="RSS feed"
- href="/rss/">
+ href="/rss">
{%block stylesheet%}<link rel="stylesheet"
href="/media/screenv1.css?{% now "u" %}"
media="screen">{%endblock%}
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
- <!--<link rel="manifest" href="/manifest.webmanifest" /> -->
{%block extrahead%}{%endblock%}
</head>
<body {%block bodyid%}{%endblock%}{%block bodyevents%}{%endblock%}>
@@ -26,30 +25,30 @@
<header class="site-banner">
<div id="logo">
<a href="/" title="Home">Libregraf</a>
- <span class="tagline">Let's Tell Your Story</span>
+ <span class="tagline">Free Software &amp; nerdery</span>
</div>
- <nav>
+ <nav class="nav-menu">
<ul>
- <li><a href="/hire-me" title="">Hire Me</a></li>
- <li><a href="/about" title="">About Scott</a></li>
- <!--<li><a href="/portfolio" title="">Portfolio</a></li>
- <li><a href="/praise" title="">Praise</a></li>
- <li><a href="/contact" title="">Contact</a></li>
- <li><a href="/blog/" title="">Blog</a></li>-->
+ <li><a href="/essays/" title="Previous articles">Archive</a></li>
+ <li><a href="/linked/" title="Thoughts on Free, open source and Libre software news">Links</a></li>
+ <li><a href="/about" title="About this site and the tools I use to make it">About</a></li>
+ <li><a href="/contact" title="How to get in touch regarding Libregraf">Contact</a></li>
</ul>
</nav>
</header>
</div>
{% block content %}{% endblock %}
{% block extrabody %}{% endblock %}
- <footer class="bl">
- <p id="license">
+ <footer>
+ <ul class="nav-menu footer-nav-menu">
+ <li><a href="/contact" title="How to get in touch regarding Libregraf">Contact</a></li>
+ <li><a href="/rss" title="RSS feed">RSS</a></li>
+ <li><a href="" title="Libregraf on twitter">Twitter</a></li>
+ </ul>
+ <p class="hed-tertiary">
&copy; {% now "Y" %}
- <span class="h-card"><a class="p-name u-url" href="https://luxagraf.net/">Scott Gilbertson</a><data class="p-nickname" value="luxagraf"></data><data class="p-locality" value="Athens"></data><data class="p-region" value="Georgia"></data><data class="p-country-name" value="United States"></data></span>.
+ <span class="h-card"><a class="p-name u-url" href="https://libregraf.net/">Scott Gilbertson</a><data class="p-nickname" value="libregraf"></data><data class="p-locality" value="Athens"></data><data class="p-region" value="Georgia"></data><data class="p-country-name" value="United States"></data></span>.
</p>
- <ul class="footer-nav">
- <li><a href="/contact" title="contact luxagraf">Contact</a></li>
- </ul>
</footer>
</div>
{% block js %}{% endblock%}
diff --git a/design/templates/blog/entry_detail.html b/design/templates/blog/entry_detail.html
new file mode 100644
index 0000000..ad4eda8
--- /dev/null
+++ b/design/templates/blog/entry_detail.html
@@ -0,0 +1,62 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{%block bodyid%}id="essay-archive" class="archive"{%endblock%}
+
+{% block content %}
+<div class="content-narrow">
+ <article class="h-entry hentry entry-content content" itemscope itemType="http://schema.org/BlogPosting">
+ <header id="header" class="post-header">
+ <h1 class="p-name hed-primary" itemprop="headline">{{object.title|smartypants|safe}}</h1>
+ {% if object.sub_title %}<h2 class="p-summary hed-secondary">{{object.sub_title|smartypants|safe}}</h2>{%endif%}
+ <div class="post-linewrapper">
+ <h5 class="hed-tertiary">Filed Under: {% for tag in object.tags.all %}<a href="/essays/tags/{{tag.slug}}" title="View all essays about {{tag}}">{{tag}}</a>{%if forloop.last%}{%else%}, {%endif%}{% endfor %}</h5>
+ <time class="dt-published published dt-updated hed-tertiary" 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>
+ </div>
+ </header>
+ <div id="article" class="e-content entry-content" itemprop="articleBody">
+ {{object.body_html|safe|smartypants}}
+ </div>
+ </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>
+ {% if object.related.all %}<div class="article-afterward related">
+ <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>
+ {% if object.subtitle%}<h5 class="post-subtitle">{{object.subtitle|safe|smartypants}}</h5>{%endif%}
+ <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>{%endif%}
+</div>
+{% endblock %}
diff --git a/design/templates/blog/entry_list.html b/design/templates/blog/entry_list.html
new file mode 100644
index 0000000..0931ac4
--- /dev/null
+++ b/design/templates/blog/entry_list.html
@@ -0,0 +1,18 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{%block bodyid%}id="essay-archive" class="archive"{%endblock%}
+
+{% block content %}
+ <main role="main" id="essay-archive" class="essay-archive archive-list">
+ <h1 class="topic-hed">Essays</h1>
+ <ul>{% for object in object_list %}
+ <li class="h-entry hentry" itemscope itemType="http://schema.org/Article">
+ <span class="date dt-published hed-tertiary">{{object.pub_date|date:"F Y"}}</span>
+ <a class="u-url" href="{{object.get_absolute_url}}">
+ <h2 class="p-name hed-primary">{{object.title|safe|smartypants|widont}}</h2>
+ <p class="p-summary hed-secondary">{% if object.sub_title %}{{object.sub_title|safe|smartypants}}{%else%}{{object.metadescription}}{%endif%}</p>
+ </a>
+ </li>
+ {%endfor%}</ul>
+ </main>
+{% endblock %}
diff --git a/design/templates/homepage.html b/design/templates/homepage.html
index ed47bdb..ca8d3b5 100644
--- a/design/templates/homepage.html
+++ b/design/templates/homepage.html
@@ -2,87 +2,21 @@
{% load typogrify_tags %}
{% block sitename %}
<head itemscope itemtype="http://schema.org/WebSite">
- <title itemprop='name'>Everyone has a story - I'll help you tell yours</title>
+ <title itemprop='name'>Libregraf: Free software, open source, and web nerdery</title>
<link rel="canonical" href="https://libregraf.net/" itemprop="url" />
{% endblock %}
-{%block bodyid%}id="home" class="home"{%endblock%}
-
+{%block bodyid%}id="home" class="archive home"{%endblock%}
{% block content %}
-<div class="content-wrapper hero-wrapper">
- <div class="content hero">
- <div class="hero-pic">
- <img src="/media/bio.jpg" class="circle-pic" alt="Scott Gilbertson" />
- </div>
- <div class="hero-text">
- <h1 class="hed-alpha">Need Content That Converts?</h1>
- <h2 class="hed-beta">Let's find the weak spots in your content and strengthen them.</h2>
- <h2 class="hed-beta">I'll create the content you need to amp up your traffic, leads and&nbsp;sales.</h2>
- <h3 class="hed-alpha">My writing attracts, engages and converts.</h3>
- <p>Whether you’re an entrepreneur, small business, or large company, my custom tailored content can catapult your online visibility and give you the traffic boost you need to attract new leads.</p>
- <p><a href="/hire-me" class="btn btn-hollow">Let's Get Started</a></p>
- </div>
- </div>
-</div>
-<div class="content-wrapper">
- <div class="content">
- <h4 class="hed-gamma hed-border">How Can I Help You?</h4>
- <p class="narrow">Since the dawn of the Internet I've been helping people discover the power of stories. Stories pull customers in, stories drive traffic. You don't need &#8220;marketing,&#8221; you need good stories. Here's a few ways I can help tell your story.</p>
- <div class="home-card-wrapper">
- <div class="flex">
- <div class="card card-tiny">
- <div class="card-image">
- <img src="/media/img/typing.jpg" alt="hands typing code on laptop" />
- </div>
- <h5 class="hed-delta">Technical Writing</h5>
- <p>My specialty is making the technical easy to understand. I've used my expertise as a developer to write documentation, tutorials, and white papers. I&#8217;ve helped companies like Opera Software, Postmarkapp, Sifter tell their story to developers and users. Lets tell your story.</p>
- </div>
- <div class="card card-tiny">
- <div class="card-image">
- <img src="/media/img/content.jpg" alt="hands typing code on laptop" />
- </div>
- <h5 class="hed-delta">Content Marketing</h5>
- <p>Content marketing is marketing-speak for telling stories that captivate your audience. Whether you already have a blog or are starting from scratch, I can help refine your strategies and create content focused on achieving measurable results.</p>
- </div>
- <div class="card card-tiny">
- <div class="card-image">
- <img src="/media/img/pen.jpg" alt="pen editing papers" />
- </div>
- <h5 class="hed-delta">Copywriting &amp; Copy editing</h5>
- <p>Maybe you've already written your story, but could use a hand polishing it up. Whether you need some need some fine tuning of what you already have, or need some help organizing and streamlining your story, I can help.</p>
- </div>
- </div>
- <a href="/hire-me" class="btn btn-hollow btn-link">Hire Me!</a>
- <a href="https://google.com/" class="btn btn-hollow btn-link">Go Cheap</a>
- </div>
- </div>
-</div>
-<div class="content-wrapper">
- <h6 class="hed-gamma hed-border">Companies I've helped</h6>
- <div class="border-wrapper">
- <ul class="list-inline home-logos">
- <li><a href="https://wired.com/" title="Wired.com"><img src="/media/img/wired.png" alt="Wired logo" /></a></li>
- <li><a href="https://opera.com/" title="Opera.com"><img src="/media/img/opera.png" alt="Opera Web Browser logo" /></a></li>
- <li><a href="https://arstechnica.com/" title="ArsTechnica.com"><img src="/media/img/ars.png" alt="Ars logo" /></a></li>
- <li><a href="https://sifterapp.com/" title="Sifter.com"><img src="/media/img/sifter.png" alt="Sifter logo" /></a></li>
- <li><a href="https://www.boostmobile.com/" title="boostmobile"><img src="/media/img/boost.png" alt="Boost Mobile logo" /></a></li>
- <li><a href="https://webmonkey.com/" title="Webmonkey.com"><img src="/media/img/webmonkey.jpg" alt="Webmonkey logo" /></a></li>
- <!--<li><a href="" title=""><img src="/media/img/budgettravel.jpg" alt="Budget Travel logo" /></li>-->
- <li><a href="https://postmarkapp.com/" title="Postmark"><img src="/media/img/postmark.png" alt="Postmarkapp logo" /></a></li>
- <li><a href="https://theregister.co.uk/" title="The register"><img src="/media/img/register.png" alt="Register logo" /></a></li>
- </ul>
- </div>
-</div>
-
-<div class="content-wrapper">
- <div class="content">
- <div class="home-border-wrapper">
- <h6 class="hed-gamma hed-border">What Clients Say</h6>
- </div>
- </div>
+<div class="content-narrow">
+{% for obj in object_list %}
+<article class="h-entry hentry" itemscope itemType="http://schema.org/Article">
+ <span class="date dt-published hed-tertiary">{{obj.pub_date|date:"F d, Y"}}</span>
+ <h3 class="p-name hed-primary"><a class="u-repost-of" href="{{obj.link_url}}" title="Read the original story">{{obj.title|safe|smartypants|widont}}</a> &nbsp;<a class="hed-star u-url" href="{{obj.get_absolute_url}}">&#9733;</a></h3>
+ <div class="p-summary">{{obj.body_html|safe|smartypants}}</div>
+</article>
+{% if forloop.last %}{%else%}<hr />{%endif%}
+{% endfor %}
</div>
{% endblock %}
-
-#### Copywriting &amp; Copy editing
-Whether you need some writing done from scratch or just need some fine tuning of what you already have, I can help.
diff --git a/design/templates/links/link_detail.html b/design/templates/links/link_detail.html
new file mode 100644
index 0000000..500dfcb
--- /dev/null
+++ b/design/templates/links/link_detail.html
@@ -0,0 +1,13 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{%block bodyid%}id="essay-archive" class="archive"{%endblock%}
+
+{% block content %}
+<div class="content-narrow">
+<article class="h-entry hentry" itemscope itemType="http://schema.org/Article">
+ <span class="date dt-published blok">{{object.pub_date|date:"F d, Y"}}</span>
+ <h3 class="hed-primary"><a class="u-url" href="{{object.link_url}}" title="Read the original story">{{object.title|safe|smartypants|widont}}</a></h3>
+ <div class="p-summary">{{object.body_html|safe|smartypants}}</div>
+</article>
+</div>
+{% endblock %}
diff --git a/design/templates/links/link_list.html b/design/templates/links/link_list.html
new file mode 100644
index 0000000..f38771a
--- /dev/null
+++ b/design/templates/links/link_list.html
@@ -0,0 +1,15 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{%block bodyid%}id="essay-archive" class="archive"{%endblock%}
+
+{% block content %}
+<div class="content-narrow">
+{% for obj in object_list %}
+<article class="h-entry hentry" itemscope itemType="http://schema.org/Article">
+ <span class="date dt-published blok">{{obj.pub_date|date:"F d, Y"}}</span>
+ <h3 class="p-name hed-primary"><a class="u-repost-of" href="{{obj.link_url}}" title="Read the original story">{{obj.title|safe|smartypants|widont}}</a> &nbsp;<a class="star u-url" href="{{obj.get_absolute_url}}">&#9733;</a></h3>
+ <div class="p-summary">{{obj.body_html|safe|smartypants}}</div>
+</article>
+{% endfor %}
+</div>
+{% endblock %}
diff --git a/design/templates/pages/page.html b/design/templates/pages/page.html
new file mode 100644
index 0000000..095ccd1
--- /dev/null
+++ b/design/templates/pages/page.html
@@ -0,0 +1,12 @@
+{% extends 'base.html' %}
+{% load typogrify_tags %}
+{%block bodyid%}id="page" class="detail"{%endblock%}
+
+{% block content %}
+<div class="content-narrow">
+<article class="h-entry hentry" itemscope itemType="http://schema.org/Article">
+ <h3 class="hed-primary">{{object.title|safe|smartypants|widont}}</h3>
+ <div class="e-content">{{object.body_html|safe|smartypants}}</div>
+</article>
+</div>
+{% endblock %}