Skip to content

Commit ca8dba5

Browse files
committed
Refactor convert pagination to django-components structure.
1 parent 228c32f commit ca8dba5

File tree

20 files changed

+166
-137
lines changed

20 files changed

+166
-137
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ cython_debug/
198198
# $GIT_DIR/info/exclude or the core.excludesFile configuration variable as
199199
# described in https://git-scm.com/docs/gitignore
200200
*.pyc
201-
src
202201
*DS_Store
203202
*~
204203
*.db

base/components/components.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from typing import Literal, Optional
2+
3+
from django_components import Component, register
4+
from pydantic import BaseModel
5+
6+
from base.pagination import PAGE_VAR, Pagination
7+
from base.templatetags.base_templatetags import querystring
8+
9+
10+
class PaginationItem(BaseModel):
11+
kind: Literal["current", "ellipsis", "number"]
12+
text: Optional[str | int] = None
13+
attrs: Optional[dict] = None
14+
15+
16+
@register("pagination")
17+
class PaginationComponent(Component):
18+
template_file = "pagination.html"
19+
20+
class Kwargs(BaseModel):
21+
pagination_obj: Pagination
22+
model_config = {"arbitrary_types_allowed": True}
23+
24+
def pagination_number(self, pagination: Pagination, num: int) -> PaginationItem:
25+
"""
26+
Generates a list of `PaginatedItem`, each representing an individual page with
27+
its associated properties in a pagination navigation list.
28+
"""
29+
if num == pagination.paginator.ELLIPSIS:
30+
return PaginationItem(kind="ellipsis", text=pagination.paginator.ELLIPSIS)
31+
elif num == pagination.page_num:
32+
return PaginationItem(kind="current", text=num)
33+
else:
34+
link = querystring(None, {**pagination.params, PAGE_VAR: num})
35+
return PaginationItem(
36+
kind="number",
37+
text=num,
38+
attrs={"href": link},
39+
)
40+
41+
def get_template_data(self, args, kwargs, slots, context):
42+
pagination = kwargs.pagination_obj
43+
page_elements = [self.pagination_number(pagination, page_num) for page_num in pagination.page_range]
44+
previous_page_link = f"?{PAGE_VAR}={pagination.page_num - 1}" if pagination.page.has_previous() else ""
45+
next_page_link = f"?{PAGE_VAR}={pagination.page_num + 1}" if pagination.page.has_next() else ""
46+
return {
47+
"pagination": pagination,
48+
"previous_page_link": previous_page_link,
49+
"next_page_link": next_page_link,
50+
"page_elements": page_elements,
51+
}

base/components/pagination.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{% if pagination.multi_page %}
2+
<nav class="justify-center my-8" aria-labelledby="pagination">
3+
<h2 id="pagination" class="sr-only">Pagination {{ pagination.opts.verbose_name_plural }}</h2>
4+
<ul class="flex justify-center gap-2 transition-colors duration-200 ease-out ml-0">
5+
<li>
6+
<a class="py-[5px] px-[10px] mr-2 no-underline rounded-lg border-1 border-transparent text-base hover:border-base-orange-400 {% if previous_page_link == '' %}text-base-gray-400 hover:border-transparent cursor-default{% endif %}" href="{{ previous_page_link }}" rel="prev" aria-label="Previous page">
7+
<span class="arrow-left inline-flex items-center">Previous</span>
8+
</a>
9+
</li>
10+
{% with page_link_css="py-[5px] px-[10px] border-1 border-transparent rounded-lg no-underline hover:border-base-orange-400" %}
11+
{% for page_item in page_elements %}
12+
<li class="inline-block">
13+
{% if page_item.kind == 'ellipsis' %}
14+
{{ page_item.text }}
15+
{% elif page_item.kind == 'current' %}
16+
<a href="" class="{{ page_link_css }} bg-base-orange-400 text-base-white-400 cursor-default" aria-current="page">{{ page_item.text }}</a>
17+
{% else %}
18+
<a {% html_attrs page_item.attrs class=page_link_css %}>{{ page_item.text }}</a>
19+
{% endif %}
20+
</li>
21+
{% endfor %}
22+
{% endwith %}
23+
<li>
24+
<a class="py-[5px] px-[10px] ml-2 no-underline rounded-lg border-1 border-transparent text-base hover:border-base-orange-400 {% if next_page_link == '' %}text-base-gray-400 hover:border-transparent cursor-default{% endif %}" href="{{ next_page_link }}" rel="next" aria-label="Next page">
25+
<span class="arrow-right inline-flex items-center">Next</span>
26+
</a>
27+
</li>
28+
</ul>
29+
</nav>
30+
{% endif %}

base/templatetags/components.py

Lines changed: 0 additions & 40 deletions
This file was deleted.

djangosnippets/settings/base.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import os
2+
from pathlib import Path
23

34
import dj_database_url
45
from django.contrib import messages
@@ -13,6 +14,7 @@ def user_url(user):
1314

1415

1516
PROJECT_ROOT = os.path.join(os.path.dirname(os.path.abspath(__file__)), os.pardir)
17+
BASE_DIR = Path(__file__).resolve().parent.parent.parent
1618

1719
SITE_ID = 1
1820
SITE_NAME = "djangosnippets.org"
@@ -68,6 +70,7 @@ def user_url(user):
6870
"theme",
6971
"django_recaptcha",
7072
"django_extensions",
73+
"django_components",
7174
"rest_framework",
7275
"django_htmx",
7376
)
@@ -92,7 +95,6 @@ def user_url(user):
9295
{
9396
"BACKEND": "django.template.backends.django.DjangoTemplates",
9497
"DIRS": [os.path.join(PROJECT_ROOT, "templates")],
95-
"APP_DIRS": True,
9698
"OPTIONS": {
9799
"context_processors": [
98100
"django.contrib.auth.context_processors.auth",
@@ -102,13 +104,32 @@ def user_url(user):
102104
"django.contrib.messages.context_processors.messages",
103105
"django.template.context_processors.request",
104106
],
107+
"loaders": [
108+
(
109+
"django.template.loaders.cached.Loader",
110+
[
111+
"django.template.loaders.filesystem.Loader",
112+
"django.template.loaders.app_directories.Loader",
113+
"django_components.template_loader.Loader",
114+
],
115+
)
116+
],
117+
"builtins": [
118+
"django_components.templatetags.component_tags",
119+
],
105120
},
106121
}
107122
]
108123

109124
STATIC_URL = "/assets/static/"
110125
STATIC_ROOT = os.path.join(PROJECT_ROOT, "..", "assets", "static")
111126
STATICFILES_DIRS = (os.path.join(PROJECT_ROOT, "static"),)
127+
STATICFILES_FINDERS = [
128+
"django.contrib.staticfiles.finders.FileSystemFinder",
129+
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
130+
"django_components.finders.ComponentsFileSystemFinder",
131+
]
132+
112133
TAILWIND_APP_NAME = "theme"
113134

114135
SESSION_ENGINE = "django.contrib.sessions.backends.cached_db"

djangosnippets/settings/development.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,9 @@
99
CACHE_BACKEND = "dummy://"
1010

1111
INSTALLED_APPS = INSTALLED_APPS
12+
13+
TEMPLATES[0]["OPTIONS"]["loaders"] = [
14+
"django.template.loaders.filesystem.Loader",
15+
"django.template.loaders.app_directories.Loader",
16+
"django_components.template_loader.Loader",
17+
]

djangosnippets/settings/testing.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"django.contrib.sessions",
2323
"django.contrib.sites",
2424
"django.contrib.staticfiles",
25+
"django_components",
2526
"allauth",
2627
"allauth.account",
2728
"allauth.socialaccount",
@@ -53,13 +54,20 @@
5354
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, "cab", "tests", "templates"),
5455
SNIPPETS_TEMPLATES_DIR,
5556
],
56-
"APP_DIRS": True,
5757
"OPTIONS": {
5858
"context_processors": [
5959
"django.contrib.auth.context_processors.auth",
6060
"django.contrib.messages.context_processors.messages",
6161
"django.template.context_processors.request",
6262
],
63+
"loaders": [
64+
"django.template.loaders.filesystem.Loader",
65+
"django.template.loaders.app_directories.Loader",
66+
"django_components.template_loader.Loader",
67+
],
68+
"builtins": [
69+
"django_components.templatetags.component_tags",
70+
],
6371
},
6472
}
6573
]

djangosnippets/static/scss/main.scss

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -359,61 +359,6 @@ body.simple {
359359
}
360360
}
361361

362-
nav.pagination {
363-
display: flex;
364-
justify-content: center;
365-
text-align: center;
366-
ul {
367-
margin-left: 1rem;
368-
margin-right: 1rem;
369-
}
370-
li {
371-
display: inline-block;
372-
a, em, span {
373-
padding: 5px 10px;
374-
line-height: 20px;
375-
border: 1px solid transparent;
376-
border-radius: 6px;
377-
transition: border-color .2s cubic-bezier(0.3, 0, 0.5, 1);
378-
cursor: pointer;
379-
}
380-
a:hover {
381-
border-color: $secondary-color;
382-
text-decoration: none;
383-
}
384-
em {
385-
font-style: normal;
386-
cursor: default;
387-
}
388-
.current-page {
389-
font-weight: bold;
390-
color: white;
391-
background-color: $secondary-color;
392-
}
393-
.disabled {
394-
color: gray;
395-
cursor: default;
396-
border-color: transparent;
397-
}
398-
}
399-
.previous-page::before, .next-page::after {
400-
display: inline-block;
401-
width: 1rem;
402-
height: 1rem;
403-
vertical-align: text-bottom;
404-
content: "";
405-
background-color: currentColor;
406-
}
407-
.previous-page::before {
408-
clip-path: polygon(9.8px 12.8px, 8.7px 12.8px, 4.5px 8.5px, 4.5px 7.5px, 8.7px 3.2px, 9.8px 4.3px, 6.1px 8px, 9.8px 11.7px, 9.8px 12.8px);
409-
margin-right: 4px;
410-
}
411-
.next-page::after {
412-
clip-path: polygon(6.2px 3.2px, 7.3px 3.2px, 11.5px 7.5px, 11.5px 8.5px, 7.3px 12.8px, 6.2px 11.7px, 9.9px 8px, 6.2px 4.3px, 6.2px 3.2px);
413-
margin-left: 4px;
414-
}
415-
}
416-
417362
footer {
418363
padding: 30px 0 30px 0;
419364
clear: both;

djangosnippets/templates/base/components/pagination.html

Lines changed: 0 additions & 21 deletions
This file was deleted.

djangosnippets/templates/cab/language_list.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{% extends "base.html" %}
2-
{% load core_tags components %}
2+
{% load core_tags %}
33

44
{% block head_title %}All languages{% endblock %}
55

@@ -12,6 +12,6 @@
1212
{% endfor %}
1313
</ul>
1414

15-
{% pagination pagination %}
15+
{% component "pagination" pagination_obj=pagination / %}
1616

1717
{% endblock %}

0 commit comments

Comments
 (0)