Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
57c5544
Initialize postedits app
rafalp Dec 17, 2025
ab9591c
New postedit model
rafalp Dec 17, 2025
bbb01e6
Posts last edit reason, basic text diff, move post edits data migration
rafalp Dec 17, 2025
be6d7e3
Add edit reason to edit forms
rafalp Dec 18, 2025
308dd49
Change post edit model
rafalp Dec 18, 2025
8de274a
WIP create_post_edit obj
rafalp Dec 19, 2025
6df8252
Add create_post_edit object tests
rafalp Dec 19, 2025
4fcbd65
Create edit record on posts merge
rafalp Dec 19, 2025
2be2090
Add PostEdit asserts to edit view tests
rafalp Dec 19, 2025
90e82ce
Add tests for recording edits to edit views
rafalp Dec 19, 2025
6c0c072
Add post edits permission to group model
rafalp Dec 19, 2025
b76f449
Rename misago.postedits to edits
rafalp Dec 19, 2025
98f2ece
Add new permission to perm building and copying logics
rafalp Dec 19, 2025
436b0b7
WIP edit permissions, small style tweaks for posts
rafalp Dec 19, 2025
8fc00a4
More CSS tweaks
rafalp Dec 19, 2025
16bf8eb
WIP post edits permission
rafalp Dec 19, 2025
557ab2d
Add edits permissions utils
rafalp Dec 19, 2025
e691efc
Display post edits information on posts list
rafalp Dec 19, 2025
99af6e0
Add tests for post edit info visibility on post feed
rafalp Dec 22, 2025
7db7bf8
WIP finish diff util
rafalp Dec 23, 2025
287243e
WIP post edit diff
rafalp Dec 23, 2025
29d9b79
Diff text function
rafalp Dec 23, 2025
dbcb2e8
Diff texts, more work on post edits UI
rafalp Dec 23, 2025
7edd6b9
Fix HTMX history
rafalp Dec 23, 2025
d1a8a51
Add tabler icons, WIP display attachments list
rafalp Dec 24, 2025
6922056
WIP attachments diff
rafalp Dec 24, 2025
cca5ea7
More UI tweaks for post edits
rafalp Dec 29, 2025
55fa8ea
More work on post diff
rafalp Dec 29, 2025
4453444
More UI polish for post edits page
rafalp Dec 30, 2025
fa4e889
misago-confirm -> mg-confirm attr
rafalp Dec 30, 2025
97983b9
WIP restore post from edit
rafalp Dec 30, 2025
3cdf7a8
Small tweaks in translation strings contexts doc
rafalp Dec 30, 2025
07a1a19
Gitignore database.sql snapshot file
rafalp Jan 2, 2026
7b0429c
WIP delete post edit record
rafalp Jan 2, 2026
d91dd06
Add delete own post edit time limit
rafalp Jan 2, 2026
33b19f0
Add new tabler icons, begin replacing generic thread views with backends
rafalp Jan 3, 2026
2cd9d69
Add more icons
rafalp Jan 3, 2026
5f33eeb
WIP more work on post edits view refactor
rafalp Jan 3, 2026
4673b96
Basic post edit delete view
rafalp Jan 3, 2026
fa243e8
Fix tests
rafalp Jan 3, 2026
d660b6a
Delete post edit view (without tests)
rafalp Jan 5, 2026
de642db
Code style tweak
rafalp Jan 5, 2026
4f4cb55
Small code tweak
rafalp Jan 5, 2026
6b8af04
Add hide/unhide post edit data model
rafalp Jan 5, 2026
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,7 @@ pylint.txt
*.pot

# Docker Compose Override
docker-compose.override.yml
docker-compose.override.yml

# Database snapshot
database.sql
17 changes: 17 additions & 0 deletions dev-docs/html-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,29 @@

Like [htmx](https://htmx.org/reference/), Misago includes a set of custom HTML attributes that template authors can use.

- [`mg-confirm`](#mg-confirm)
- [`mg-error`](#mg-error)
- [`mg-if`](#mg-if)
- [`mg-loader`](#mg-loader)
- [`mg-text`](#mg-text)


### `mg-confirm`

A `form` element attribute that displays a confirmation prompt on submit:

```html
<form
post="..."
mg-confirm="Are you sure?"
>
<button>Submit</button>
</form>
```

Use this attribute instead of `hx-confirm` for form submissions that don't use HTMX.


### `mg-error`

If an htmx request returns an error response, Misago will display it in a toast.
Expand Down
131 changes: 131 additions & 0 deletions dev-docs/plugins/hooks/can-see-post-edit-count-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# `can_see_post_edit_count_hook`

This hook wraps a standard Misago function used to check if a user has permission to see a post’s edit count. Returns `True` if they can and `False` if they don't.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import can_see_post_edit_count_hook
```


## Filter

```python
def custom_can_see_post_edit_count_filter(
action: CanSeePostsEditCountHookAction,
permissions: 'UserPermissionsProxy',
category: Category,
thread: Thread,
post: Post,
) -> bool:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CanSeePostsEditCountHookAction`

Next function registered in this hook, either a custom function or Misago's standard one.

See the [action](#action) section for details.


#### `users: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


#### `thread: Thread`

A thread to check permissions for.


#### `post: Post`

A post to check permissions for.


### Return value

A `bool` with `True` if user can see post's edit count, and `False` if they can't.


## Action

```python
def can_see_post_edit_count_action(
permissions: 'UserPermissionsProxy',
category: Category,
thread: Thread,
post: Post,
) -> bool:
...
```

Misago function used to check if a user has permission to see a post’s edit count. Returns `True` if they can and `False` if they don't.


### Arguments

#### `users: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


#### `thread: Thread`

A thread to check permissions for.


#### `post: Post`

A post to check permissions for.


### Return value

A `bool` with `True` if user can see post's edit count, and `False` if they can't.


## Example

The code below implements a custom filter function that blocks a user from seeing a specific post's edit count if it has a flag.

```python
from django.core.exceptions import PermissionDenied
from django.utils.translation import pgettext
from misago.categories.models import Category
from misago.permissions.hooks import can_see_post_edit_count_hook
from misago.permissions.proxy import UserPermissionsProxy
from misago.threads.models import Post, Thread

@can_see_post_edit_count_hook.append_filter
def check_user_can_see_post_edits(
action,
permissions: UserPermissionsProxy,
category: Category,
thread: Thread,
post: Post,
) -> bool:
if post.plugin_data.get("hide_edits"):
return False

return action(permissions, category, thread, post)
```
4 changes: 2 additions & 2 deletions dev-docs/plugins/hooks/can-see-post-likes-count-hook.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `can_see_post_likes_count_hook`

This hook wraps a standard Misago function used to check if a user has permission to see a post’s likes count. Returns `True` if they can and `False` if they can't.
This hook wraps a standard Misago function used to check if a user has permission to see a post’s likes count. Returns `True` if they can and `False` if they don't.


## Location
Expand Down Expand Up @@ -74,7 +74,7 @@ def can_see_post_likes_count_action(
...
```

Misago function used to check if a user has permission to see a post’s likes count. Returns `True` if they can and `False` if they can't.
Misago function used to check if a user has permission to see a post’s likes count. Returns `True` if they can and `False` if they don't.


### Arguments
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `check_access_category_permission_hook`

This hook wraps a standard Misago function used to check if a user has permission to access a category of unknown type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they can't.
This hook wraps a standard Misago function used to check if a user has permission to access a category of any type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they don't.


## Location
Expand Down Expand Up @@ -54,7 +54,7 @@ def check_access_category_permission_action(
...
```

Misago function used to check if a user has permission to access a category of unknown type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they can't.
Misago function used to check if a user has permission to access a category of any type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they don't.


### Arguments
Expand Down
4 changes: 2 additions & 2 deletions dev-docs/plugins/hooks/check-access-post-permission-hook.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `check_access_post_permission_hook`

This hook wraps a standard Misago function used to check if a user has permission to access a post of unknown type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they can't.
This hook wraps a standard Misago function used to check if a user has permission to access a post of any type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they don't.


## Location
Expand Down Expand Up @@ -69,7 +69,7 @@ def check_access_post_permission_action(
...
```

Misago function used to check if a user has permission to access a post of unknown type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they can't.
Misago function used to check if a user has permission to access a post of any type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they don't.


### Arguments
Expand Down
4 changes: 2 additions & 2 deletions dev-docs/plugins/hooks/check-access-thread-permission-hook.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `check_access_thread_permission_hook`

This hook wraps a standard Misago function used to check if a user has permission to access a thread of unknown type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they can't.
This hook wraps a standard Misago function used to check if a user has permission to access a thread of any type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they don't.


## Location
Expand Down Expand Up @@ -62,7 +62,7 @@ def check_access_thread_permission_action(
...
```

Misago function used to check if a user has permission to access a thread of unknown type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they can't.
Misago function used to check if a user has permission to access a thread of any type (threads, private threads, or plugin-defined). Raises Django’s `Http404` or `PermissionDenied` if they don't.


### Arguments
Expand Down
141 changes: 141 additions & 0 deletions dev-docs/plugins/hooks/check-delete-post-edit-permission-hook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
# `check_delete_post_edit_permission_hook`

This hook wraps the standard Misago function used to check whether a user has permission to delete a post edit. Raises Django’s `PermissionDenied` if they don’t.


## Location

This hook can be imported from `misago.permissions.hooks`:

```python
from misago.permissions.hooks import check_delete_post_edit_permission_hook
```


## Filter

```python
def custom_check_delete_post_edit_permission_filter(
action: CheckDeletePostEditPermissionHookAction,
permissions: 'UserPermissionsProxy',
category: Category,
thread: Thread,
post: Post,
post_edit: PostEdit,
) -> None:
...
```

A function implemented by a plugin that can be registered in this hook.


### Arguments

#### `action: CheckDeletePostEditPermissionHookAction`

Next function registered in this hook, either a custom function or Misago's standard one.

See the [action](#action) section for details.


#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


#### `thread: Thread`

A thread to check permissions for.


#### `post: Post`

A post to check permissions for.


#### `post_edit: PostEdit`

A post edit to check permissions for.


## Action

```python
def check_delete_post_edit_permission_action(
permissions: 'UserPermissionsProxy',
category: Category,
thread: Thread,
post: Post,
post_edit: PostEdit,
) -> None:
...
```

Misago function used to check if a user has permission to delete a post edit. Raises Django’s `PermissionDenied` if they don't.


### Arguments

#### `user_permissions: UserPermissionsProxy`

A proxy object with the current user's permissions.


#### `category: Category`

A category to check permissions for.


#### `thread: Thread`

A thread to check permissions for.


#### `post: Post`

A post to check permissions for.


#### `post_edit: PostEdit`

A post edit to check permissions for.


## Example

The code below implements a custom filter function that blocks a user from deleting a post edit record if it has a protected flag.

```python
from django.core.exceptions import PermissionDenied
from django.utils.translation import pgettext
from misago.categories.models import Category
from misago.edits.models import PostEdit
from misago.permissions.hooks import check_delete_post_edit_permission_hook
from misago.permissions.proxy import UserPermissionsProxy
from misago.threads.models import Post, Thread

@check_delete_post_edit_permission_hook.append_filter
def check_user_can_delete_protected_post_edit(
action,
permissions: UserPermissionsProxy,
category: Category,
thread: Thread,
post: Post,
post_edit: PostEdit,
) -> None:
# Run standard permission checks
action(permissions, category, thread, post, post_edit)

if post.plugin_data.get("is_protected"):
raise PermissionDenied(
pgettext(
"edits permission error",
"You can't delete this post edit."
)
)
```
Loading