Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get-recent-posts-fix #34

Merged
merged 5 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions docs/templatetags.md
Original file line number Diff line number Diff line change
Expand Up @@ -452,12 +452,14 @@ Outputs:

## post_title_link

Returns the title of the current post as a link if it's part of a collection, or just the title if it's a
single post.
Returns the title of the current post as a link if it's part of a collection, or just the title if it's single post.

The `force_link` argument can be used to always return the link, regardless if it's part of a collection or not.

### Arguments

- `link_class` (optional): CSS class(es) to apply to the link.
- `force_link` (optional, boolean): Always displays a link when true. *Note* - this is a keyword-only argument.

### Returns

Expand Down Expand Up @@ -493,6 +495,20 @@ Outputs:
<a href="/my-post/" class="post-title-link">My Post Title</a>
```

Or, to force the link, even when just a single post is displayed:

```django
{% post_title_link force_link=True %}
```

Outputs:

```html
<a href="/my-post/">My Post Title</a>
```



## post_author

Returns the display name of the post's author.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "djpress"
version = "0.9.4"
version = "0.9.5"
description = "A blog application for Django sites, inspired by classic WordPress."
readme = "README.md"
requires-python = ">=3.10"
Expand Down
27 changes: 21 additions & 6 deletions src/djpress/templatetags/djpress_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,21 @@ def have_posts(context: Context) -> list[Post | None] | Page:
return []


@register.simple_tag(takes_context=True)
def get_recent_posts(context: Context) -> models.QuerySet[Post]:
"""Return the recent posts.

This returns the most recent published posts, and tries to be efficient by checking if there's a `posts` object we
can use.
"""
posts: Page | None = context.get("posts")

if isinstance(posts, Page) and posts.number == 1:
return posts.object_list

return Post.post_objects.get_recent_published_posts()


@register.simple_tag(takes_context=True)
def post_title(context: Context) -> str:
"""Return the title of a post.
Expand All @@ -274,27 +289,27 @@ def post_title(context: Context) -> str:


@register.simple_tag(takes_context=True)
def post_title_link(context: Context, link_class: str = "") -> str:
def post_title_link(context: Context, link_class: str = "", *, force_link: bool = False) -> str:
"""Return the title link for a post.

If the post is part of a posts collection, then return the title and a link to the
post.

If the post is a single post, then return just the title of the post with no link.
If the post is part of a posts collection, then return the title and a link to the post. If the post is a single
post, then return just the title of the post with no link. But this behavior can be overridden by setting
`force_link` to `True`.

Otherwise return and empty string.

Args:
context: The context.
link_class: The CSS class(es) for the link.
force_link: Whether to force the link to be displayed.

Returns:
str: The title link for the post.
"""
post: Post | None = context.get("post")
posts: Page | None = context.get("posts")

if posts and post:
if (posts and post) or force_link:
link_class_html = f' class="{link_class}"' if link_class else ""

output = f'<a href="{post.url}" title="{post.title}"{link_class_html}>{post.title}</a>'
Expand Down
54 changes: 54 additions & 0 deletions tests/test_templatetags_djpress_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,22 @@ def test_post_title_link_no_context():
assert djpress_tags.post_title_link(context) == expected_output


@pytest.mark.django_db
def test_post_title_link_single_post(test_post1):
context = Context({"post": test_post1})
assert djpress_tags.post_title_link(context) == test_post1.title


@pytest.mark.django_db
def test_post_title_link_single_post_force_link(test_post1):
context = Context({"post": test_post1})

# this generates a URL based on the slug only - this is prefixed with the POST_PREFIX setting
post_url = test_post1.url
expected_output = f'<a href="{post_url}" title="{test_post1.title}">{test_post1.title}</a>'
assert djpress_tags.post_title_link(context, force_link=True) == expected_output


@pytest.mark.django_db
def test_post_title_link_with_prefix(settings, test_post1):
# Confirm settings in settings_testing.py
Expand Down Expand Up @@ -1443,3 +1459,41 @@ def test_rss_url(settings):
assert settings.DJPRESS_SETTINGS["RSS_PATH"] == "test-rss"
expected_output = "/test-rss/"
assert djpress_tags.rss_url() == expected_output


@pytest.mark.django_db
def test_get_recent_posts(settings, test_post1, test_post2, test_post3):
assert settings.DJPRESS_SETTINGS["RECENT_PUBLISHED_POSTS_COUNT"] == 3
posts = Paginator(
Post.post_objects.get_published_posts(),
settings.DJPRESS_SETTINGS["RECENT_PUBLISHED_POSTS_COUNT"],
)
page = posts.get_page(number=None)
context = Context({"posts": page})
tag_get_recent_posts = list(djpress_tags.get_recent_posts(context))
page_posts = list(page.object_list)
assert tag_get_recent_posts == page_posts

# Test case 2 - 2 pages, i.e. 3 posts with 2 posts per page
settings.DJPRESS_SETTINGS["RECENT_PUBLISHED_POSTS_COUNT"] = 2
posts = Paginator(
Post.post_objects.get_published_posts(),
settings.DJPRESS_SETTINGS["RECENT_PUBLISHED_POSTS_COUNT"],
)
page = posts.get_page(number=2)
context = Context({"posts": page})
tag_get_recent_posts = list(djpress_tags.get_recent_posts(context))
page_posts = list(page.object_list)
assert tag_get_recent_posts != page_posts

# Test case 3 - 3 pages, i.e. 3 posts with 1 posts per page
settings.DJPRESS_SETTINGS["RECENT_PUBLISHED_POSTS_COUNT"] = 1
posts = Paginator(
Post.post_objects.get_published_posts(),
settings.DJPRESS_SETTINGS["RECENT_PUBLISHED_POSTS_COUNT"],
)
page = posts.get_page(number=3)
context = Context({"posts": page})
tag_get_recent_posts = list(djpress_tags.get_recent_posts(context))
page_posts = list(page.object_list)
assert tag_get_recent_posts != page_posts
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.