kopia lustrzana https://github.com/wagtail/wagtail
Add full set of Documents app features
- Added customizing document upload form subsection in documents section - Added storing and serving subpage - Added overview section, including RichText and StreamField usage - Closes #2001pull/10998/head
rodzic
570b9a410c
commit
8932c67270
|
@ -19,6 +19,7 @@ Changelog
|
|||
* Fix: Use the latest draft when copying an unpublished page for translation (Andrey Nehaychik)
|
||||
* Fix: Make Workflow and Aging Pages reports only available to users with page-related permissions (Rohit Sharma)
|
||||
* Docs: Document, for contributors, the use of translate string literals passed as arguments to tags and filters using `_()` within templates (Chiemezuo Akujobi)
|
||||
* Docs: Document all features for the Documents app in one location (Neeraj Yetheendran)
|
||||
* Maintenance: Update BeautifulSoup upper bound to 4.12.x (scott-8)
|
||||
* Maintenance: Migrate initialization of classes (such as `body.ready`) from multiple JavaScript implementations to one Stimulus controller `w-init` (Chiemezuo Akujobi)
|
||||
* Maintenance: Adopt the usage of of translate string literals using `arg=_('...')` in all `wagtailadmin` module templates (Chiemezuo Akujobi)
|
||||
|
|
|
@ -24,6 +24,8 @@ See [Django's documentation on deploying static files](django:howto/static-files
|
|||
The JavaScript and CSS files used by the Wagtail admin frequently change between releases of Wagtail - it's important to avoid serving outdated versions of these files due to browser or server-side caching, as this can cause hard-to-diagnose issues.
|
||||
We recommend enabling [ManifestStaticFilesStorage](django.contrib.staticfiles.storage.ManifestStaticFilesStorage) in the `STATICFILES_STORAGE` setting - this ensures that different versions of files are assigned distinct URLs.
|
||||
|
||||
(user_uploaded_files)=
|
||||
|
||||
### User Uploaded Files
|
||||
|
||||
Wagtail follows [Django's conventions for managing uploaded files](django:topics/files).
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
(custom_document_model)=
|
||||
|
||||
# Custom document model
|
||||
|
||||
An alternate `Document` model can be used to add custom behaviour and
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# Custom document upload form
|
||||
|
||||
Wagtail provides a way to use a custom document form by modifying the [`WAGTAILDOCS_DOCUMENT_FORM_BASE`](wagtaildocs_document_form_base) setting. This setting allows you to extend the default document form with your custom fields and logic.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```python
|
||||
# settings.py
|
||||
WAGTAILDOCS_DOCUMENT_FORM_BASE = 'myapp.forms.CustomDocumentForm'
|
||||
```
|
||||
|
||||
```python
|
||||
# myapp/forms.py
|
||||
from django import forms
|
||||
|
||||
from wagtail.documents.forms import BaseDocumentForm
|
||||
|
||||
class CustomDocumentForm(BaseDocumentForm):
|
||||
terms_and_conditions = forms.BooleanField(
|
||||
label="I confirm that this document was not created by AI.",
|
||||
required=True,
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super().clean()
|
||||
if not cleaned_data.get("terms_and_conditions"):
|
||||
raise forms.ValidationError(
|
||||
"You must confirm the document was not created by AI."
|
||||
)
|
||||
return cleaned_data
|
||||
```
|
||||
|
||||
```{note}
|
||||
Any custom document form should extend the built-in `BaseDocumentForm` class.
|
||||
```
|
|
@ -4,6 +4,9 @@
|
|||
---
|
||||
maxdepth: 2
|
||||
---
|
||||
overview
|
||||
custom_document_model
|
||||
custom_document_upload_form
|
||||
storing_and_serving
|
||||
title_generation_on_upload
|
||||
```
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
(overview)=
|
||||
|
||||
# Documents overview
|
||||
|
||||
This page provides an overview of the basics of using the `'wagtail.documents'` app in your Wagtail project.
|
||||
|
||||
## Including `'wagtail.documents'` in `INSTALLED_APPS`
|
||||
|
||||
To use the `wagtail.documents` app, you need to include it in the `INSTALLED_APPS` list in your Django project's settings. Simply add it to the list like this:
|
||||
|
||||
```python
|
||||
# settings.py
|
||||
|
||||
INSTALLED_APPS = [
|
||||
# ...
|
||||
'wagtail.documents',
|
||||
# ...
|
||||
]
|
||||
```
|
||||
|
||||
## Setting up URLs
|
||||
|
||||
Next, you need to set up URLs for the `wagtail.documents` app. You can include these URLs in your project's main urls.py file. To do this, add the following lines:
|
||||
|
||||
```python
|
||||
# urls.py
|
||||
|
||||
from wagtail.documents import urls as wagtaildocs_urls
|
||||
|
||||
urlpatterns = [
|
||||
# ...
|
||||
path('documents/', include(wagtaildocs_urls)),
|
||||
# ...
|
||||
]
|
||||
```
|
||||
|
||||
New documents saved are stored in the [reference index](managing_the_reference_index) by default.
|
||||
|
||||
## Using documents in a Page
|
||||
|
||||
To include a document file in a Wagtail page, you can use `FieldPanel` in your page model.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```python
|
||||
# models.py
|
||||
|
||||
from wagtail.admin.panels import FieldPanel
|
||||
from wagtail.documents import get_document_model
|
||||
|
||||
|
||||
class YourPage(Page):
|
||||
# ...
|
||||
document = models.ForeignKey(
|
||||
get_document_model(),
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
)
|
||||
|
||||
content_panels = Page.content_panels + [
|
||||
# ...
|
||||
FieldPanel('document'),
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
This allows you to select a document file when creating or editing a page, and link to it in your page template.
|
||||
|
||||
Here's an example template to access the document field and render it:
|
||||
|
||||
```html
|
||||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
{% if page.document %}
|
||||
<h2>Document: {{ page.document.title }}</h2>
|
||||
<p>File Type: {{ page.document.file_extension }}</p>
|
||||
<a href="{{ page.document.url }}" target="_blank">View Document</a>
|
||||
{% else %}
|
||||
<p>No document attached to this page.</p>
|
||||
{% endif %}
|
||||
<div>{{ page.body }}</div>
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
## Using documents within `RichTextFields`
|
||||
|
||||
Links to documents can be made in pages using the [`RichTextField`](rich_text_docs). By default, Wagtail will include the features for adding links to documents see [](rich_text_features).
|
||||
|
||||
|
||||
You can either exclude or include these by passing the `features` to your `RichTextField`. In the example below we create a `RichTextField` with only documents and basic formatting.
|
||||
|
||||
|
||||
```python
|
||||
# models.py
|
||||
from wagtail.fields import RichTextField
|
||||
|
||||
class BlogPage(Page):
|
||||
# ...other fields
|
||||
document_footnotes = RichTextField(
|
||||
blank=True,
|
||||
features=["bold", "italic", "ol", "document-link"]
|
||||
)
|
||||
|
||||
panels = [
|
||||
# ...other panels
|
||||
FieldPanel("document_footnotes"),
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Using documents within `StreamField`
|
||||
|
||||
`StreamField` provides a content editing model suitable for pages that do not follow a fixed structure. To add links to documents using `StreamField`, include it in your models and also include the `DocumentChooserBlock`.
|
||||
|
||||
Create a `Page` model with a `StreamField` named `doc` and a `DocumentChooserBlock` named `doc_link` inside the field:
|
||||
|
||||
```python
|
||||
# models.py
|
||||
|
||||
from wagtail.fields import StreamField
|
||||
from wagtail.documents.blocks import DocumentChooserBlock
|
||||
|
||||
|
||||
class BlogPage(Page):
|
||||
# ... other fields
|
||||
|
||||
documents = StreamField([
|
||||
('document', DocumentChooserBlock())
|
||||
],
|
||||
null=True,
|
||||
blank=True,
|
||||
use_json_field=True,
|
||||
)
|
||||
|
||||
panels = [
|
||||
# ... other panels
|
||||
FieldPanel("documents"),
|
||||
]
|
||||
```
|
||||
|
||||
In `blog_page.html`, add the following block of code to display the document link in the page:
|
||||
|
||||
```html
|
||||
{% for block in page.documents %}
|
||||
<a href="{{ block.value.url }}">{{ block.value.title }}</a>
|
||||
{% endfor %}
|
||||
```
|
||||
|
||||
|
||||
## Working documents and collections
|
||||
|
||||
Documents in Wagtail can be organized within [collections](https://docs.wagtail.org/en/v4.0/editor_manual/documents_images_snippets/collections.html). Collections provide a way to group related documents. You can cross-link documents between collections and make them accessible through different parts of your site.
|
||||
|
||||
Here's an example:
|
||||
|
||||
```python
|
||||
from wagtail.documents import get_document_model
|
||||
|
||||
class PageWithCollection(Page):
|
||||
collection = models.ForeignKey(
|
||||
"wagtailcore.Collection",
|
||||
null=True,
|
||||
blank=True,
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='+',
|
||||
verbose_name='Document Collection',
|
||||
)
|
||||
|
||||
content_panels = Page.content_panels + [
|
||||
FieldPanel("collection"),
|
||||
]
|
||||
|
||||
def get_context(self, request):
|
||||
context = super().get_context(request)
|
||||
documents = get_document_model().objects.filter(collection=self.collection)
|
||||
context['documents'] = documents
|
||||
return context
|
||||
|
||||
```
|
||||
|
||||
Here’s an example template to access the document collection and render it:
|
||||
|
||||
```html
|
||||
{% extends "base.html" %}
|
||||
{% load wagtailcore_tags %}
|
||||
|
||||
{% block content %}
|
||||
{% if documents %}
|
||||
<h3>Documents:</h3>
|
||||
<ul>
|
||||
{% for document in documents %}
|
||||
<li>
|
||||
<a href="{{ document.url }}" target="_blank">{{ document.title }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
```
|
||||
|
||||
## Making documents private
|
||||
|
||||
If you want to restrict access to certain documents, you can place them in [private collections](https://guide.wagtail.org/en-latest/how-to-guides/manage-collections/#privacy-settings).
|
||||
|
||||
Private collections are not publicly accessible, and their contents are only available to users with the appropriate permissions.
|
||||
|
||||
## API access
|
||||
|
||||
Documents in Wagtail can be accessed through the API via the `wagtail.documents.api.v2.views.DocumentsAPIViewSet`. This allows you to programmatically interact with documents, retrieve their details, and perform various operations.
|
||||
|
||||
For more details, you can refer to the [API section](api_v2_configure_endpoints) that provides additional information and usage examples.
|
|
@ -0,0 +1,60 @@
|
|||
(storing_and_serving)=
|
||||
|
||||
# Storing and serving
|
||||
|
||||
Wagtail follows [Django’s conventions for managing uploaded files](django:topics/files). For configuration of `FileSystemStorage` and more information on handling user uploaded files, see [](user_uploaded_files).
|
||||
|
||||
## File storage location
|
||||
|
||||
Wagtail uses the [DEFAULT_FILE_STORAGE](https://docs.djangoproject.com/en/stable/ref/settings/#std:setting-DEFAULT_FILE_STORAGE) setting to determine where and how user-uploaded files are stored. By default, Wagtail stores files in the local filesystem.
|
||||
|
||||
## Serving documents
|
||||
|
||||
Document serving is controlled by the [WAGTAILDOCS_SERVE_METHOD](wagtaildocs_serve_method) method. It provides a number of serving methods which trade some of the strictness of the permission check that occurs when normally handling a document request for performance.
|
||||
|
||||
The serving methods provided are `direct`, `redirect` and `serve_view`, with `redirect` method being the default when `WAGTAILDOCS_SERVE_METHOD` is unspecified or set to `None`. For example:
|
||||
|
||||
```python
|
||||
WAGTAILDOCS_SERVE_METHOD = "redirect"
|
||||
```
|
||||
|
||||
## Content types
|
||||
|
||||
Wagtail provides the [WAGTAILDOCS_CONTENT_TYPES](wagtaildocs_content_types) setting to specify which document content types are allowed to be uploaded. For example:
|
||||
|
||||
```python
|
||||
WAGTAILDOCS_CONTENT_TYPES = {
|
||||
'pdf': 'application/pdf',
|
||||
'txt': 'text/plain',
|
||||
}
|
||||
```
|
||||
|
||||
## Inline content types
|
||||
|
||||
Inline content types can be specified using [WAGTAILDOCS_INLINE_CONTENT_TYPES](wagtaildocs_inline_content_types), are displayed within the rich text editor.
|
||||
|
||||
For example:
|
||||
|
||||
```python
|
||||
WAGTAILDOCS_INLINE_CONTENT_TYPES = ['application/pdf', 'text/plain']
|
||||
```
|
||||
|
||||
## File extensions
|
||||
|
||||
Wagtail allows you to specify the permitted file extensions for document uploads using the [WAGTAILDOCS_EXTENSIONS](wagtaildocs_extensions) setting.
|
||||
|
||||
It also validates the extensions using Django's [FileExtensionValidator](django:ref/validators#fileextensionvalidator). For example:
|
||||
|
||||
```python
|
||||
WAGTAILDOCS_EXTENSIONS = ['pdf', 'docx']
|
||||
```
|
||||
|
||||
## Document password required template
|
||||
|
||||
Wagtail provides the `DOCUMENT_PASSWORD_REQUIRED_TEMPLATE` setting to use a custom template when a password is required to access a protected document. Read more about [](private_pages).
|
||||
|
||||
Here's an example:
|
||||
|
||||
```python
|
||||
DOCUMENT_PASSWORD_REQUIRED_TEMPLATE = 'myapp/document_password_required.html'
|
||||
```
|
|
@ -12,7 +12,7 @@ You can customise the resolved value of this title using a JavaScript [event lis
|
|||
|
||||
The simplest way to add JavaScript to the editor is via the [`insert_global_admin_js` hook](insert_global_admin_js). However, any JavaScript that adds an event listener will work.
|
||||
|
||||
## DOM Event
|
||||
## DOM event
|
||||
|
||||
The event name to listen to is `'wagtail:documents-upload'`. It will be dispatched on the document upload `form`. The event's `detail` attribute will contain:
|
||||
|
||||
|
@ -30,7 +30,7 @@ The event will 'bubble' up so that you can simply add a global `document` listen
|
|||
|
||||
See MDN for more information about [custom JavaScript events](https://developer.mozilla.org/en-US/docs/Web/Events/Creating_and_triggering_events).
|
||||
|
||||
## Code Examples
|
||||
## Code examples
|
||||
|
||||
### Adding the file extension to the start of the title
|
||||
|
||||
|
|
|
@ -373,6 +373,8 @@ WAGTAILDOCS_DOCUMENT_MODEL = 'myapp.MyDocument'
|
|||
|
||||
This setting lets you provide your own document model for use in Wagtail, which should extend the built-in `AbstractDocument` class.
|
||||
|
||||
(wagtaildocs_document_form_base)=
|
||||
|
||||
### `WAGTAILDOCS_DOCUMENT_FORM_BASE`
|
||||
|
||||
```python
|
||||
|
|
|
@ -35,6 +35,7 @@ depth: 1
|
|||
### Documentation
|
||||
|
||||
* Document, for contributors, the use of translate string literals passed as arguments to tags and filters using `_()` within templates (Chiemezuo Akujobi)
|
||||
* Document all features for the Documents app in one location, see [](../advanced_topics/documents/index) (Neeraj Yetheendran)
|
||||
|
||||
### Maintenance
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue