Skip to content

Commit

Permalink
Merge pull request #40 from stuartmaxwell/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartmaxwell authored May 13, 2024
2 parents e6029d3 + 2d1c539 commit 9fbb187
Show file tree
Hide file tree
Showing 12 changed files with 274 additions and 47 deletions.
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Django",
"type": "debugpy",
"request": "launch",
"args": [
"runserver"
],
"django": true,
"autoStartBrowser": false,
"program": "${workspaceFolder}/manage.py"
}
]
}
2 changes: 1 addition & 1 deletion config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@
ARCHIVES_PATH_ENABLED: bool = True
ARCHIVES_PATH: str = "archives"
DATE_ARCHIVES_ENABLED: bool = True
DATE_ARCHIVES: bool = True
RSS_ENABLED: bool = True
RSS_PATH: str = "rss"

# The following are used to generate the post permalink
DAY_SLUG: str = "%Y/%m/%d"
MONTH_SLUG: str = "%Y/%m"
YEAR_SLUG: str = "%Y"
Expand Down
8 changes: 0 additions & 8 deletions djpress/models/post.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,6 @@ def is_truncated(self: "Post") -> bool:
"""Return whether the content is truncated."""
return settings.TRUNCATE_TAG in self.content

@property
def author_display_name(self: "Post") -> str:
"""Return the author's display name.
If the author has a first name, return that. Otherwise, return the username.
"""
return self.author.first_name or self.author.username

@property
def permalink(self: "Post") -> str:
"""Return the post's permalink.
Expand Down
24 changes: 24 additions & 0 deletions djpress/models/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Functions related to the User model."""

from django.contrib.auth.models import User


def get_author_display_name(user: User) -> str:
"""Return the author display name.
Tries to display the first name and last name if available, otherwise falls back to
the username.
Args:
user: The user.
Returns:
str: The author display name.
"""
if user.first_name and user.last_name:
return f"{user.first_name} {user.last_name}"

if user.first_name:
return user.first_name

return user.username
4 changes: 2 additions & 2 deletions djpress/templates/djpress/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ <h1><a href="{% url "djpress:index" %}">{% get_blog_title %}</a></h1>
<article>
<header>
<h1>{{ post.title }}</h1>
<p>By <span rel="author">{{ post.author_display_name }}</span></p>
<p>By <span rel="author">{% post_author post.author %}</span></p>
<p><time datetime="2023-05-01">{{ post.date }}</time></p>
</header>
<section>
Expand Down Expand Up @@ -53,7 +53,7 @@ <h1>{{ category.name }}</h1>
<article>
<header>
<h1><a href="{% url 'djpress:post_detail' post.permalink %}">{{ post.title }}</a></h1>
<p>By <span rel="author">{{ post.author_display_name }}</span></p>
<p>By <span rel="author">{% post_author post.author %}</span></p>
<p><time datetime="2023-05-01">{{ post.date }}</time></p>
</header>
<section>
Expand Down
126 changes: 115 additions & 11 deletions djpress/templatetags/djpress_tags.py
Original file line number Diff line number Diff line change
@@ -1,62 +1,116 @@
"""Template tags for djpress."""

from datetime import datetime

from django import template
from django.conf import settings
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils.safestring import mark_safe

from djpress.models import Category, Post
from djpress.models.user import get_author_display_name

register = template.Library()


@register.simple_tag
def get_categories() -> models.QuerySet[Category] | None:
"""Return all categories."""
"""Return all categories.
Returns:
models.QuerySet[Category]: All categories.
"""
return Category.objects.get_categories()


@register.simple_tag
def get_recent_published_posts() -> models.QuerySet[Category] | None:
"""Return recent published posts from the cache."""
"""Return recent published posts from the cache.
Returns:
models.QuerySet[Category]: Recent published posts.
"""
return Post.post_objects.get_recent_published_posts()


@register.simple_tag
def get_single_published_post(slug: str) -> Post | None:
"""Return a single published post by slug."""
"""Return a single published post by slug.
Args:
slug: The slug of the post.
Returns:
Post: A single published post.
"""
return Post.post_objects.get_published_post_by_slug(slug)


@register.simple_tag
def get_blog_title() -> str:
"""Return the blog title."""
"""Return the blog title.
Returns:
str: The blog title.
"""
return settings.BLOG_TITLE


@register.simple_tag
def post_author_link(post: Post, link_class: str = "") -> str:
"""Return the author link for a post."""
def post_author(user: User) -> str:
"""Return the author display name.
Tries to display the first name and last name if available, otherwise falls back to
the username.
Args:
user: The user.
Returns:
str: The author display name.
"""
return get_author_display_name(user)


@register.simple_tag
def post_author_link(author: User, link_class: str = "") -> str:
"""Return the author link for a post.
Args:
author: The author of the post.
link_class: The CSS class(es) for the link.
Returns:
str: The author link.
"""
author_display_name = get_author_display_name(author)

if not settings.AUTHOR_PATH_ENABLED:
return post.author_display_name
return author_display_name

author_url = reverse("djpress:author_posts", args=[post.author])
author_url = reverse("djpress:author_posts", args=[author])

link_class_html = f' class="{link_class}"' if link_class else ""

output = (
f'<a href="{author_url}" title="View all posts by '
f'{ post.author_display_name }"{link_class_html}>'
f"{ post.author_display_name }</a>"
f'{ author_display_name }"{link_class_html}>'
f"{ author_display_name }</a>"
)

return mark_safe(output)


@register.simple_tag
def post_category_link(category: Category, link_class: str = "") -> str:
"""Return the category links for a post."""
"""Return the category links for a post.
Args:
category: The category of the post.
link_class: The CSS class(es) for the link.
"""
if not settings.CATEGORY_PATH_ENABLED:
return category.name

Expand All @@ -70,3 +124,53 @@ def post_category_link(category: Category, link_class: str = "") -> str:
)

return mark_safe(output)


@register.simple_tag
def post_date_link(post_date: datetime, link_class: str = "") -> str:
"""Return the date link for a post.
Args:
post_date: The date of the post.
link_class: The CSS class(es) for the link.
"""
if not settings.DATE_ARCHIVES_ENABLED:
return post_date.strftime("%b %-d, %Y")

post_year = post_date.strftime("%Y")
post_month = post_date.strftime("%m")
post_month_name = post_date.strftime("%b")
post_day = post_date.strftime("%d")
post_day_name = post_date.strftime("%-d")
post_time = post_date.strftime("%-I:%M %p")

year_url = reverse(
"djpress:archives_posts",
args=[post_year],
)
month_url = reverse(
"djpress:archives_posts",
args=[post_year, post_month],
)
day_url = reverse(
"djpress:archives_posts",
args=[
post_year,
post_month,
post_day,
],
)

link_class_html = f' class="{link_class}"' if link_class else ""

output = (
f'<a href="{month_url}" title="View all posts in {post_month_name} {post_year}"'
f"{link_class_html}>{post_month_name}</a> "
f'<a href="{day_url}" title="View all posts on {post_day_name} '
f'{post_month_name} {post_year}"{link_class_html}>{post_day_name}</a>, '
f'<a href="{year_url}" title="View all posts in {post_year}"{link_class_html}>'
f"{post_year}</a>, "
f"{post_time}."
)

return mark_safe(output)
Loading

0 comments on commit 9fbb187

Please sign in to comment.