FossilRepo

fossilrepo / pages / views.py
Blame History Raw 110 lines
1
import markdown
2
from django.contrib import messages
3
from django.contrib.auth.decorators import login_required
4
from django.core.paginator import Paginator
5
from django.http import HttpResponse
6
from django.shortcuts import get_object_or_404, redirect, render
7
from django.utils.safestring import mark_safe
8
9
from core.pagination import PER_PAGE_OPTIONS, get_per_page
10
from core.permissions import P
11
from core.sanitize import sanitize_html
12
from organization.views import get_org
13
14
from .forms import PageForm
15
from .models import Page
16
17
18
def page_list(request):
19
# Published pages are visible to everyone (including anonymous users).
20
# Authenticated editors/admins can also see unpublished drafts.
21
if request.user.is_authenticated and (request.user.has_perm("pages.change_page") or request.user.is_superuser):
22
pages = Page.objects.all()
23
else:
24
pages = Page.objects.filter(is_published=True)
25
26
search = request.GET.get("search", "").strip()
27
if search:
28
pages = pages.filter(name__icontains=search)
29
30
per_page = get_per_page(request)
31
paginator = Paginator(pages, per_page)
32
page_obj = paginator.get_page(request.GET.get("page", 1))
33
34
ctx = {"pages": page_obj, "page_obj": page_obj, "search": search, "per_page": per_page, "per_page_options": PER_PAGE_OPTIONS}
35
36
if request.headers.get("HX-Request"):
37
return render(request, "pages/partials/page_table.html", ctx)
38
39
return render(request, "pages/page_list.html", ctx)
40
41
42
@login_required
43
def page_create(request):
44
P.PAGE_ADD.check(request.user)
45
org = get_org()
46
47
if request.method == "POST":
48
form = PageForm(request.POST)
49
if form.is_valid():
50
page = form.save(commit=False)
51
page.organization = org
52
page.created_by = request.user
53
page.save()
54
messages.success(request, f'Page "{page.name}" created.')
55
return redirect("pages:detail", slug=page.slug)
56
else:
57
form = PageForm()
58
59
return render(request, "pages/page_form.html", {"form": form, "title": "New Page"})
60
61
62
def page_detail(request, slug):
63
from django.core.exceptions import PermissionDenied
64
65
page = get_object_or_404(Page, slug=slug, deleted_at__isnull=True)
66
# Published pages are public. Unpublished drafts require auth + edit permission.
67
if not page.is_published:
68
if not request.user.is_authenticated:
69
raise PermissionDenied("Authentication required.")
70
if not (request.user.has_perm("pages.change_page") or request.user.is_superuser):
71
raise PermissionDenied("You don't have permission to view this draft page.")
72
content_html = mark_safe(sanitize_html(markdown.markdown(page.content, extensions=["fenced_code", "tables", "toc"])))
73
return render(request, "pages/page_detail.html", {"page": page, "content_html": content_html})
74
75
76
@login_required
77
def page_update(request, slug):
78
P.PAGE_CHANGE.check(request.user)
79
page = get_object_or_404(Page, slug=slug, deleted_at__isnull=True)
80
81
if request.method == "POST":
82
form = PageForm(request.POST, instance=page)
83
if form.is_valid():
84
page = form.save(commit=False)
85
page.updated_by = request.user
86
page.save()
87
messages.success(request, f'Page "{page.name}" updated.')
88
return redirect("pages:detail", slug=page.slug)
89
else:
90
form = PageForm(instance=page)
91
92
return render(request, "pages/page_form.html", {"form": form, "page": page, "title": "Edit Page"})
93
94
95
@login_required
96
def page_delete(request, slug):
97
P.PAGE_DELETE.check(request.user)
98
page = get_object_or_404(Page, slug=slug, deleted_at__isnull=True)
99
100
if request.method == "POST":
101
page.soft_delete(user=request.user)
102
messages.success(request, f'Page "{page.name}" deleted.')
103
104
if request.headers.get("HX-Request"):
105
return HttpResponse(status=200, headers={"HX-Redirect": "/kb/"})
106
107
return redirect("pages:list")
108
109
return render(request, "pages/page_confirm_delete.html", {"page": page})
110

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button