kopia lustrzana https://github.com/wagtail/wagtail
Update docs and changelog to reflect changes for #9817
rodzic
5f4a2ed38d
commit
ad3ef5875d
|
@ -30,6 +30,7 @@ Changelog
|
|||
* Make the rich text block trigger and slash-commands always available regardless of where the cursor is (Thibaud Colas)
|
||||
* Adjust the size of panel labels on the "Account" form (Thibaud Colas)
|
||||
* Delay hiding the contents of the side panels when closing, so the animation is smoother (Thibaud Colas)
|
||||
* Added ability to submit snippets for moderation with `WorkflowMixin` (Sage Abdullah)
|
||||
* Fix: Make sure workflow timeline icons are visible in high-contrast mode (Loveth Omokaro)
|
||||
* Fix: Ensure authentication forms (login, password reset) have a visible border in Windows high-contrast mode (Loveth Omokaro)
|
||||
* Fix: Ensure visual consistency between buttons and links as buttons in Windows high-contrast mode (Albina Starykova)
|
||||
|
@ -75,6 +76,11 @@ Changelog
|
|||
* Fix: Prevent memory exhaustion when purging a large number of revisions (Jake Howard)
|
||||
* Fix: Add right-to-left (RTL) support for the following form components: Switch, Minimap, live preview (Thibaud Colas)
|
||||
* Fix: Improve right-to-left (RTL) positioning for the following components: Page explorer, Sidebar sub-menu, rich text tooltips, rich text toolbar trigger, editor section headers (Thibaud Colas)
|
||||
* Fix: Use the workflow name as the workflow information dialog title (Sage Abdullah)
|
||||
* Fix: Link to workflow history view instead of page history view in the workflow information dialog (Sage Abdullah)
|
||||
* Fix: Fix in-progress count in warning message when disabling workflows (Sage Abdullah)
|
||||
* Fix: Show workflow name on workflow history index page (Sage Abdullah)
|
||||
* Fix: Fix workflow history detail timeline content from showing on initial load (Sage Abdullah)
|
||||
* Docs: Add custom permissions section to permissions documentation page (Dan Hayden)
|
||||
* Docs: Add documentation for how to get started with contributing translations for the Wagtail admin (Ogunbanjo Oluwadamilare)
|
||||
* Docs: Officially recommend `fnm` over `nvm` in development documentation (LB (Ben) Johnston)
|
||||
|
|
|
@ -85,7 +85,7 @@ class UserApprovalTask(Task):
|
|||
## Custom TaskState models
|
||||
|
||||
You might also need to store custom state information for the task: for example, a rating left by an approving user.
|
||||
Normally, this is done on an instance of `TaskState`, which is created when a page starts the task. However, this can
|
||||
Normally, this is done on an instance of `TaskState`, which is created when an object starts the task. However, this can
|
||||
also be subclassed equivalently to `Task`:
|
||||
|
||||
```python
|
||||
|
@ -124,26 +124,30 @@ class UserApprovalTask(Task):
|
|||
|
||||
Both `Task` and `TaskState` have a number of methods that can be overridden to implement custom behaviour. Here are some of the most useful:
|
||||
|
||||
`Task.user_can_access_editor(page, user)`, `Task.user_can_lock(page, user)`, `Task.user_can_unlock(page, user)`:
|
||||
`Task.user_can_access_editor(obj, user)`, `Task.user_can_lock(obj, user)`, `Task.user_can_unlock(obj, user)`:
|
||||
|
||||
These methods determine if users usually without permission can access the editor, and lock, or unlock the page, by returning True or False.
|
||||
These methods determine if users usually without permission can access the editor, and lock, or unlock the object, by returning True or False.
|
||||
Note that returning `False` will not prevent users who would normally be able to perform those actions. For example, for our `UserApprovalTask`:
|
||||
|
||||
```python
|
||||
def user_can_access_editor(self, page, user):
|
||||
def user_can_access_editor(self, obj, user):
|
||||
return user == self.user
|
||||
```
|
||||
|
||||
`Task.page_locked_for_user(page, user)`:
|
||||
`Task.locked_for_user(obj, user)`:
|
||||
|
||||
This returns `True` if the page should be locked and uneditable by the user. It is used by `GroupApprovalTask` to lock the page to any users not in the approval group.
|
||||
This returns `True` if the object should be locked and uneditable by the user. It is used by `GroupApprovalTask` to lock the object to any users not in the approval group.
|
||||
|
||||
```python
|
||||
def page_locked_for_user(self, page, user):
|
||||
def locked_for_user(self, obj, user):
|
||||
return user != self.user
|
||||
```
|
||||
|
||||
`Task.get_actions(page, user)`:
|
||||
```{versionchanged} 4.2
|
||||
This method was previously named ``page_locked_for_user``, using ``page_locked_for_user`` will be removed in a future release. Along with the other similar methods, the ``obj`` parameter was previously named ``page``.
|
||||
```
|
||||
|
||||
`Task.get_actions(obj, user)`:
|
||||
|
||||
This returns a list of `(action_name, action_verbose_name, action_requires_additional_data_from_modal)` tuples, corresponding to the actions available for the task in the edit view menu.
|
||||
`action_requires_additional_data_from_modal` should be a boolean, returning `True` if choosing the action should open a modal for additional data input - for example, entering a comment.
|
||||
|
@ -151,7 +155,7 @@ This returns a list of `(action_name, action_verbose_name, action_requires_addit
|
|||
For example:
|
||||
|
||||
```python
|
||||
def get_actions(self, page, user):
|
||||
def get_actions(self, obj, user):
|
||||
if user == self.user:
|
||||
return [
|
||||
('approve', "Approve", False),
|
||||
|
@ -172,7 +176,7 @@ Returns the name of a custom template to be used in rendering the data entry mod
|
|||
|
||||
`Task.on_action(task_state, user, action_name, **kwargs)`:
|
||||
|
||||
This performs the actions specified in `Task.get_actions(page, user)`: it is passed an action name, for example, `approve`, and the relevant task state. By default, it calls `approve` and `reject` methods on the task state when the corresponding action names are passed through. Any additional data entered in a modal (see `get_form_for_action` and `get_actions`) is supplied as kwargs.
|
||||
This performs the actions specified in `Task.get_actions(obj, user)`: it is passed an action name, for example, `approve`, and the relevant task state. By default, it calls `approve` and `reject` methods on the task state when the corresponding action names are passed through. Any additional data entered in a modal (see `get_form_for_action` and `get_actions`) is supplied as kwargs.
|
||||
|
||||
For example, let's say we wanted to add an additional option: cancelling the entire workflow:
|
||||
|
||||
|
@ -186,7 +190,7 @@ def on_action(self, task_state, user, action_name):
|
|||
|
||||
`Task.get_task_states_user_can_moderate(user, **kwargs)`:
|
||||
|
||||
This returns a QuerySet of `TaskStates` (or subclasses) the given user can moderate - this is currently used to select pages to display on the user's dashboard.
|
||||
This returns a QuerySet of `TaskStates` (or subclasses) the given user can moderate - this is currently used to select objects to display on the user's dashboard.
|
||||
|
||||
For example:
|
||||
|
||||
|
@ -237,13 +241,13 @@ class BaseUserApprovalTaskStateEmailNotifier(EmailNotificationMixin, Notifier):
|
|||
|
||||
def can_handle(self, instance, **kwargs):
|
||||
if super().can_handle(instance, **kwargs) and isinstance(instance.task.specific, UserApprovalTask):
|
||||
# Don't send notifications if a Task has been cancelled and then resumed - when page was updated to a new revision
|
||||
# Don't send notifications if a Task has been cancelled and then resumed - when object was updated to a new revision
|
||||
return not TaskState.objects.filter(workflow_state=instance.workflow_state, task=instance.task, status=TaskState.STATUS_CANCELLED).exists()
|
||||
return False
|
||||
|
||||
def get_context(self, task_state, **kwargs):
|
||||
context = super().get_context(task_state, **kwargs)
|
||||
context['page'] = task_state.workflow_state.page
|
||||
context['object'] = task_state.workflow_state.content_object
|
||||
context['task'] = task_state.task.specific
|
||||
return context
|
||||
|
||||
|
|
|
@ -645,10 +645,10 @@ The model is added to allow snippets to be locked. See [](wagtailsnippets_lockin
|
|||
## `WorkflowMixin`
|
||||
|
||||
`WorkflowMixin` is a mixin class that can be added to any non-page Django model to allow its instances to be submitted to workflows.
|
||||
This mixin requires {class}`~wagtail.models.RevisionMixin`, {class}`~wagtail.models.DraftStateMixin`, and {class}`~wagtail.models.LockableMixin` to be applied. Pages already include this mixin, so there is no need to add it.
|
||||
This mixin requires {class}`~wagtail.models.RevisionMixin` and {class}`~wagtail.models.DraftStateMixin` to be applied. Pages already include this mixin, so there is no need to add it.
|
||||
|
||||
```{versionadded} 4.2
|
||||
The model is added to allow snippets to be submitted to workflows. See [](wagtailsnippets_enabling_workflows) for more details.
|
||||
The model is added to allow snippets to be submitted for moderation. See [](wagtailsnippets_enabling_workflows) for more details.
|
||||
```
|
||||
|
||||
### Methods and properties
|
||||
|
@ -873,7 +873,7 @@ The model has been renamed from ``PageRevision`` to ``Revision`` and it now refe
|
|||
|
||||
## `Workflow`
|
||||
|
||||
Workflows represent sequences of tasks which much be approved for an action to be performed on a page - typically publication.
|
||||
Workflows represent sequences of tasks which must be approved for an action to be performed on an object - typically publication.
|
||||
|
||||
### Database fields
|
||||
|
||||
|
@ -890,7 +890,7 @@ Workflows represent sequences of tasks which much be approved for an action to b
|
|||
|
||||
(boolean)
|
||||
|
||||
Whether or not the workflow is active: active workflows can be added to pages, and started. Inactive workflows cannot.
|
||||
Whether or not the workflow is active: active workflows can be added to pages and snippets, and started. Inactive workflows cannot.
|
||||
```
|
||||
|
||||
### Methods and properties
|
||||
|
@ -910,18 +910,40 @@ Workflows represent sequences of tasks which much be approved for an action to b
|
|||
|
||||
## `WorkflowState`
|
||||
|
||||
Workflow states represent the status of a started workflow on a page.
|
||||
Workflow states represent the status of a started workflow on an object.
|
||||
|
||||
### Database fields
|
||||
|
||||
```{eval-rst}
|
||||
.. class:: WorkflowState
|
||||
|
||||
.. attribute:: page
|
||||
.. attribute:: content_object
|
||||
|
||||
(foreign key to ``Page``)
|
||||
(generic foreign key)
|
||||
|
||||
The page on which the workflow has been started
|
||||
The object on which the workflow has been started. For page workflows, the object is an instance of the base ``Page`` model.
|
||||
|
||||
.. versionchanged:: 4.2
|
||||
|
||||
This field has been changed from a ``ForeignKey`` to ``Page`` into a :class:`~django.contrib.contenttypes.fields.GenericForeignKey` to any Django model instance.
|
||||
|
||||
.. attribute:: content_type
|
||||
|
||||
(foreign key to :class:`~django.contrib.contenttypes.models.ContentType`)
|
||||
|
||||
The content type of the object this workflow state belongs to. For page workflows, this means the content type of the specific page type.
|
||||
|
||||
.. attribute:: base_content_type
|
||||
|
||||
(foreign key to :class:`~django.contrib.contenttypes.models.ContentType`)
|
||||
|
||||
The base content type of the object this workflow state belongs to. For page workflows, this means the content type of the :class:`~wagtail.models.Page` model.
|
||||
|
||||
.. attribute:: object_id
|
||||
|
||||
(string)
|
||||
|
||||
The primary key of the object this revision belongs to.
|
||||
|
||||
.. attribute:: workflow
|
||||
|
||||
|
@ -1056,7 +1078,7 @@ Tasks represent stages in a workflow which must be approved for the workflow to
|
|||
|
||||
## `TaskState`
|
||||
|
||||
Task states store state information about the progress of a task on a particular page revision.
|
||||
Task states store state information about the progress of a task on a particular revision.
|
||||
|
||||
### Database fields
|
||||
|
||||
|
@ -1065,19 +1087,23 @@ Task states store state information about the progress of a task on a particular
|
|||
|
||||
.. attribute:: workflow_state
|
||||
|
||||
(foreign key to ``WorkflowState``)
|
||||
(foreign key to :class:`~wagtail.models.WorkflowState`)
|
||||
|
||||
The workflow state which started this task state.
|
||||
|
||||
.. attribute:: revision
|
||||
|
||||
(foreign key to ``Revision``)
|
||||
(foreign key to :class:`~wagtail.models.Revision`)
|
||||
|
||||
The revision this task state was created on.
|
||||
|
||||
.. versionchanged:: 4.2
|
||||
|
||||
This field has been renamed from ``page_revision`` to ``revision``.
|
||||
|
||||
.. attribute:: task
|
||||
|
||||
(foreign key to ``Task``)
|
||||
(foreign key to :class:`~wagtail.models.Task`)
|
||||
|
||||
The task that this task state is storing state information for.
|
||||
|
||||
|
@ -1183,11 +1209,32 @@ Represents the assignment of a workflow to a page and its descendants.
|
|||
|
||||
.. attribute:: workflow
|
||||
|
||||
(foreign key to ``Workflow``)
|
||||
(foreign key to :class:`~wagtail.models.Workflow`)
|
||||
|
||||
.. attribute:: page
|
||||
|
||||
(foreign key to ``Page``)
|
||||
(foreign key to :class:`~wagtail.models.Page`)
|
||||
```
|
||||
|
||||
## `WorkflowContentType`
|
||||
|
||||
Represents the assignment of a workflow to a Django model.
|
||||
|
||||
### Database fields
|
||||
|
||||
```{eval-rst}
|
||||
.. class:: WorkflowContentType
|
||||
|
||||
.. attribute:: workflow
|
||||
|
||||
(foreign key to :class:`~wagtail.models.Workflow`)
|
||||
|
||||
.. attribute:: content_type
|
||||
|
||||
(foreign key to :class:`~django.contrib.contenttypes.models.ContentType`)
|
||||
|
||||
A foreign key to the ``ContentType`` object that represents the model that is assigned to the workflow.
|
||||
|
||||
```
|
||||
|
||||
## `BaseLogEntry`
|
||||
|
|
|
@ -21,6 +21,12 @@ Snippets can now be locked by users to prevent other users from editing, through
|
|||
|
||||
This feature was developed by Sage Abdullah.
|
||||
|
||||
### Workflows for snippets
|
||||
|
||||
Snippets can now be assigned to workflows through the use of the `WorkflowMixin`, allowing new changes to be submitted for moderation before they are published. For more details, see [](wagtailsnippets_enabling_workflows).
|
||||
|
||||
This feature was developed by Sage Abdullah.
|
||||
|
||||
### `fullpageurl` template tag
|
||||
|
||||
Wagtail now provides a `fullpageurl` template tag (for both Django templates and Jinja2) to output a page's full URL including the domain. For more details, see [](fullpageurl_tag).
|
||||
|
@ -245,3 +251,18 @@ If you are using the front-end cache invalidator module (`wagtail.contrib.fronte
|
|||
* For Azure Front Door: upgrade `azure-mgmt-frontdoor` to version 1 or above
|
||||
|
||||
Support for older versions will be dropped in a future release.
|
||||
|
||||
### Changes to `Workflow` and `Task` methods
|
||||
|
||||
To accommodate workflows support for snippets, the `page` parameter in {meth}`Workflow.start() <wagtail.models.Workflow.start>` has been renamed to `obj`.
|
||||
|
||||
In addition, some methods on the base {class}`~wagtail.models.Task` model have been changed. If you have {doc}`custom Task types </extending/custom_tasks>`, make sure to update the methods to reflect the following changes:
|
||||
|
||||
- `page_locked_for_user()` is now {meth}`~wagtail.models.Task.locked_for_user`. Using `page_locked_for_user()` is deprecated and will be removed in a future release.
|
||||
- The `page` parameter in `user_can_access_editor()`, `locked_for_user()`, `user_can_lock()`, `user_can_unlock()`, `get_actions()`, has been renamed to `obj`.
|
||||
|
||||
### Changes to `WorkflowState` and `TaskState` models
|
||||
|
||||
To accommodate workflows support for snippets, the `WorkflowState.page` foreign key has been replaced with a `GenericForeignKey` as `WorkflowState.content_object`. The generic foreign key is defined using a combination of the new `WorkflowState.base_content_type` and `WorkflowState.object_id` fields.
|
||||
|
||||
The `TaskState.page_revision` foreign key has been renamed to `TaskState.revision`.
|
||||
|
|
Ładowanie…
Reference in New Issue