Browse Source

documentation - migrate api section to markdown

Thiago Costa de Souza 2 years ago
parent
commit
7e73349dc1

+ 1 - 1
CHANGELOG.txt

@@ -5,7 +5,7 @@ Changelog
 ~~~~~~~~~~~~~~~~
 
  * Add clarity to confirmation when being asked to convert an external link to an internal one (Thijs Kramer)
- * Convert various pages in the documentation to Markdown (Khanh Hoang, Vu Pham, Daniel Kirkham, LB (Ben) Johnston)
+ * Convert various pages in the documentation to Markdown (Khanh Hoang, Vu Pham, Daniel Kirkham, LB (Ben) Johnston, Thiago Costa de Souza)
  * Add `base_url_path` to `ModelAdmin` so that the default URL structure of app_label/model_name can be overridden (Vu Pham, Khanh Hoang)
  * Add `full_url` to the API output of `ImageRenditionField` (Paarth Agarwal)
  * Fix issue where `ModelAdmin` index listings with export list enabled would show buttons with an incorrect layout (Josh Woodcock)

+ 1 - 0
CONTRIBUTORS.rst

@@ -598,6 +598,7 @@ Contributors
 * Josh Woodcock
 * Christian Franke
 * Tom Hu
+* Thiago Costa de Souza
 
 Translators
 ===========

+ 9 - 9
docs/advanced_topics/api/index.rst → docs/advanced_topics/api/index.md

@@ -1,17 +1,17 @@
-===========
-Wagtail API
-===========
+# Wagtail API
 
 The API module provides a public-facing, JSON-formatted API to allow retrieving
 content as raw field data. This is useful for cases like serving content to
 non-web clients (such as a mobile phone app) or pulling content out of Wagtail
 for use in another site.
 
-See `RFC 8: Wagtail API <https://github.com/wagtail/rfcs/blob/main/text/008-wagtail-api.md#12---stable-and-unstable-versions>`_
+See [RFC 8: Wagtail API](https://github.com/wagtail/rfcs/blob/main/text/008-wagtail-api.md#12---stable-and-unstable-versions)
 for full details on our stabilisation policy.
 
-.. toctree::
-    :maxdepth: 2
-
-    v2/configuration
-    v2/usage
+```{toctree}
+---
+maxdepth: 2
+---
+v2/configuration
+v2/usage
+```

+ 271 - 0
docs/advanced_topics/api/v2/configuration.md

@@ -0,0 +1,271 @@
+(api_v2_configuration)=
+
+# Wagtail API v2 Configuration Guide
+
+This section of the docs will show you how to set up a public API for your
+Wagtail site.
+
+Even though the API is built on Django REST Framework, you do not need to
+install this manually as it is already a dependency of Wagtail.
+
+## Basic configuration
+
+### Enable the app
+
+Firstly, you need to enable Wagtail's API app so Django can see it.
+Add `wagtail.api.v2` to `INSTALLED_APPS` in your Django project settings:
+
+```python
+# settings.py
+
+INSTALLED_APPS = [
+    ...
+
+    'wagtail.api.v2',
+
+    ...
+]
+```
+
+Optionally, you may also want to add `rest_framework` to `INSTALLED_APPS`.
+This would make the API browsable when viewed from a web browser but is not
+required for basic JSON-formatted output.
+
+### Configure endpoints
+
+Next, it's time to configure which content will be exposed on the API. Each
+content type (such as pages, images and documents) has its own endpoint.
+Endpoints are combined by a router, which provides the url configuration you
+can hook into the rest of your project.
+
+Wagtail provides three endpoint classes you can use:
+
+```{eval-rst}
+- Pages :class:`wagtail.api.v2.views.PagesAPIViewSet`
+- Images :class:`wagtail.images.api.v2.views.ImagesAPIViewSet`
+- Documents :class:`wagtail.documents.api.v2.views.DocumentsAPIViewSet`
+```
+
+You can subclass any of these endpoint classes to customize their functionality.
+Additionally, there is a base endpoint class you can use for adding different
+content types to the API: `wagtail.api.v2.views.BaseAPIViewSet`
+
+For this example, we will create an API that includes all three builtin content
+types in their default configuration:
+
+```python
+# api.py
+
+from wagtail.api.v2.views import PagesAPIViewSet
+from wagtail.api.v2.router import WagtailAPIRouter
+from wagtail.images.api.v2.views import ImagesAPIViewSet
+from wagtail.documents.api.v2.views import DocumentsAPIViewSet
+
+# Create the router. "wagtailapi" is the URL namespace
+api_router = WagtailAPIRouter('wagtailapi')
+
+# Add the three endpoints using the "register_endpoint" method.
+# The first parameter is the name of the endpoint (eg. pages, images). This
+# is used in the URL of the endpoint
+# The second parameter is the endpoint class that handles the requests
+api_router.register_endpoint('pages', PagesAPIViewSet)
+api_router.register_endpoint('images', ImagesAPIViewSet)
+api_router.register_endpoint('documents', DocumentsAPIViewSet)
+```
+
+Next, register the URLs so Django can route requests into the API:
+
+```python
+# urls.py
+
+from .api import api_router
+
+urlpatterns = [
+    ...
+
+    path('api/v2/', api_router.urls),
+
+    ...
+
+    # Ensure that the api_router line appears above the default Wagtail page serving route
+    re_path(r'^', include(wagtail_urls)),
+]
+```
+
+With this configuration, pages will be available at `/api/v2/pages/`, images
+at `/api/v2/images/` and documents at `/api/v2/documents/`
+
+(apiv2_page_fields_configuration)=
+
+### Adding custom page fields
+
+It's likely that you would need to export some custom fields over the API. This
+can be done by adding a list of fields to be exported into the `api_fields`
+attribute for each page model.
+
+For example:
+
+```python
+# blog/models.py
+
+from wagtail.api import apifield
+
+class blogpageauthor(orderable):
+    page = models.foreignkey('blog.blogpage', on_delete=models.cascade, related_name='authors')
+    name = models.charfield(max_length=255)
+
+    api_fields = [
+        apifield('name'),
+    ]
+
+
+class blogpage(page):
+    published_date = models.datetimefield()
+    body = richtextfield()
+    feed_image = models.foreignkey('wagtailimages.image', on_delete=models.set_null, null=true, ...)
+    private_field = models.charfield(max_length=255)
+
+    # export fields over the api
+    api_fields = [
+        apifield('published_date'),
+        apifield('body'),
+        apifield('feed_image'),
+        apifield('authors'),  # this will nest the relevant blogpageauthor objects in the api response
+    ]
+```
+
+This will make `published_date`, `body`, `feed_image` and a list of
+`authors` with the `name` field available in the API. But to access these
+fields, you must select the `blog.BlogPage` type using the `?type`
+[parameter in the API itself](apiv2_custom_page_fields).
+
+### Custom serializers
+
+[Serializers](https://www.django-rest-framework.org/api-guide/fields) are used to convert the database representation of a model into
+JSON format. You can override the serializer for any field using the
+`serializer` keyword argument:
+
+```python
+from rest_framework.fields import DateField
+
+class BlogPage(Page):
+    ...
+
+    api_fields = [
+        # Change the format of the published_date field to "Thursday 06 April 2017"
+        APIField('published_date', serializer=DateField(format='%A %d %B %Y')),
+        ...
+    ]
+```
+
+Django REST framework's serializers can all take a [source](https://www.django-rest-framework.org/api-guide/fields/#source) argument allowing you
+to add API fields that have a different field name or no underlying field at all:
+
+```python
+from rest_framework.fields import DateField
+
+class BlogPage(Page):
+    ...
+
+    api_fields = [
+        # Date in ISO8601 format (the default)
+        APIField('published_date'),
+
+        # A separate published_date_display field with a different format
+        APIField('published_date_display', serializer=DateField(format='%A %d %B %Y', source='published_date')),
+        ...
+    ]
+```
+
+This adds two fields to the API (other fields omitted for brevity):
+
+```json
+{
+    "published_date": "2017-04-06",
+    "published_date_display": "Thursday 06 April 2017"
+}
+```
+
+### Images in the API
+
+The `ImageRenditionField` serializer
+allows you to add renditions of images into your API. It requires an image
+filter string specifying the resize operations to perform on the image. It can
+also take the `source` keyword argument described above.
+
+For example:
+
+```python
+from wagtail.api import APIField
+from wagtail.images.api.fields import ImageRenditionField
+
+class BlogPage(Page):
+    ...
+
+    api_fields = [
+        # Adds information about the source image (eg, title) into the API
+        APIField('feed_image'),
+
+        # Adds a URL to a rendered thumbnail of the image to the API
+        APIField('feed_image_thumbnail', serializer=ImageRenditionField('fill-100x100', source='feed_image')),
+        ...
+    ]
+```
+
+This would add the following to the JSON:
+
+```json
+{
+    "feed_image": {
+        "id": 45529,
+        "meta": {
+            "type": "wagtailimages.Image",
+            "detail_url": "http://www.example.com/api/v2/images/12/",
+            "download_url": "/media/images/a_test_image.jpg",
+            "tags": []
+        },
+        "title": "A test image",
+        "width": 2000,
+        "height": 1125
+    },
+    "feed_image_thumbnail": {
+        "url": "/media/images/a_test_image.fill-100x100.jpg",
+        "full_url": "http://www.example.com/media/images/a_test_image.fill-100x100.jpg",
+        "width": 100,
+        "height": 100,
+        "alt": "image alt text"
+    }
+}
+```
+
+Note: `download_url` is the original uploaded file path, whereas
+`feed_image_thumbnail['url']` is the url of the rendered image.
+When you are using another storage backend, such as S3, `download_url` will return
+a URL to the image if your media files are properly configured.
+
+## Additional settings
+
+### `WAGTAILAPI_BASE_URL`
+
+(required when using frontend cache invalidation)
+
+This is used in two places, when generating absolute URLs to document files and
+invalidating the cache.
+
+Generating URLs to documents will fall back the the current request's hostname
+if this is not set. Cache invalidation cannot do this, however, so this setting
+must be set when using this module alongside the `wagtailfrontendcache` module.
+
+### `WAGTAILAPI_SEARCH_ENABLED`
+
+(default: True)
+
+Setting this to false will disable full text search. This applies to all
+endpoints.
+
+### `WAGTAILAPI_LIMIT_MAX`
+
+(default: 20)
+
+This allows you to change the maximum number of results a user can request at a
+time. This applies to all endpoints. Set to `None` for no limit.

+ 0 - 285
docs/advanced_topics/api/v2/configuration.rst

@@ -1,285 +0,0 @@
-.. _api_v2_configuration:
-
-==================================
-Wagtail API v2 Configuration Guide
-==================================
-
-This section of the docs will show you how to set up a public API for your
-Wagtail site.
-
-Even though the API is built on Django REST Framework, you do not need to
-install this manually as it is already a dependency of Wagtail.
-
-Basic configuration
-===================
-
-Enable the app
---------------
-
-Firstly, you need to enable Wagtail's API app so Django can see it.
-Add ``wagtail.api.v2`` to ``INSTALLED_APPS`` in your Django project settings:
-
-.. code-block:: python
-
-    # settings.py
-
-    INSTALLED_APPS = [
-        ...
-
-        'wagtail.api.v2',
-
-        ...
-    ]
-
-Optionally, you may also want to add ``rest_framework`` to ``INSTALLED_APPS``.
-This would make the API browsable when viewed from a web browser but is not
-required for basic JSON-formatted output.
-
-Configure endpoints
--------------------
-
-Next, it's time to configure which content will be exposed on the API. Each
-content type (such as pages, images and documents) has its own endpoint.
-Endpoints are combined by a router, which provides the url configuration you
-can hook into the rest of your project.
-
-Wagtail provides three endpoint classes you can use:
-
-- Pages :class:`wagtail.api.v2.views.PagesAPIViewSet`
-- Images :class:`wagtail.images.api.v2.views.ImagesAPIViewSet`
-- Documents :class:`wagtail.documents.api.v2.views.DocumentsAPIViewSet`
-
-You can subclass any of these endpoint classes to customise their functionality.
-Additionally, there is a base endpoint class you can use for adding different
-content types to the API: :class:`wagtail.api.v2.views.BaseAPIViewSet`
-
-For this example, we will create an API that includes all three builtin content
-types in their default configuration:
-
-.. code-block:: python
-
-    # api.py
-
-    from wagtail.api.v2.views import PagesAPIViewSet
-    from wagtail.api.v2.router import WagtailAPIRouter
-    from wagtail.images.api.v2.views import ImagesAPIViewSet
-    from wagtail.documents.api.v2.views import DocumentsAPIViewSet
-
-    # Create the router. "wagtailapi" is the URL namespace
-    api_router = WagtailAPIRouter('wagtailapi')
-
-    # Add the three endpoints using the "register_endpoint" method.
-    # The first parameter is the name of the endpoint (eg. pages, images). This
-    # is used in the URL of the endpoint
-    # The second parameter is the endpoint class that handles the requests
-    api_router.register_endpoint('pages', PagesAPIViewSet)
-    api_router.register_endpoint('images', ImagesAPIViewSet)
-    api_router.register_endpoint('documents', DocumentsAPIViewSet)
-
-Next, register the URLs so Django can route requests into the API:
-
-.. code-block:: python
-
-    # urls.py
-
-    from .api import api_router
-
-    urlpatterns = [
-        ...
-
-        path('api/v2/', api_router.urls),
-
-        ...
-
-        # Ensure that the api_router line appears above the default Wagtail page serving route
-        re_path(r'^', include(wagtail_urls)),
-    ]
-
-With this configuration, pages will be available at ``/api/v2/pages/``, images
-at ``/api/v2/images/`` and documents at ``/api/v2/documents/``
-
-.. _apiv2_page_fields_configuration:
-
-Adding custom page fields
--------------------------
-
-It's likely that you would need to export some custom fields over the API. This
-can be done by adding a list of fields to be exported into the ``api_fields``
-attribute for each page model.
-
-For example:
-
-.. code-block:: python
-
-    # blog/models.py
-
-    from wagtail.api import APIField
-
-    class BlogPageAuthor(Orderable):
-        page = models.ForeignKey('blog.BlogPage', on_delete=models.CASCADE, related_name='authors')
-        name = models.CharField(max_length=255)
-
-        api_fields = [
-            APIField('name'),
-        ]
-
-
-    class BlogPage(Page):
-        published_date = models.DateTimeField()
-        body = RichTextField()
-        feed_image = models.ForeignKey('wagtailimages.Image', on_delete=models.SET_NULL, null=True, ...)
-        private_field = models.CharField(max_length=255)
-
-        # Export fields over the API
-        api_fields = [
-            APIField('published_date'),
-            APIField('body'),
-            APIField('feed_image'),
-            APIField('authors'),  # This will nest the relevant BlogPageAuthor objects in the API response
-        ]
-
-This will make ``published_date``, ``body``, ``feed_image`` and a list of
-``authors`` with the ``name`` field available in the API. But to access these
-fields, you must select the ``blog.BlogPage`` type using the ``?type``
-:ref:`parameter in the API itself <apiv2_custom_page_fields>`.
-
-Custom serialisers
-------------------
-
-Serialisers_ are used to convert the database representation of a model into
-JSON format. You can override the serialiser for any field using the
-``serializer`` keyword argument:
-
-.. code-block:: python
-
-    from rest_framework.fields import DateField
-
-    class BlogPage(Page):
-        ...
-
-        api_fields = [
-            # Change the format of the published_date field to "Thursday 06 April 2017"
-            APIField('published_date', serializer=DateField(format='%A %d %B %Y')),
-            ...
-        ]
-
-Django REST framework's serializers can all take a source_ argument allowing you
-to add API fields that have a different field name or no underlying field at all:
-
-.. code-block:: python
-
-    from rest_framework.fields import DateField
-
-    class BlogPage(Page):
-        ...
-
-        api_fields = [
-            # Date in ISO8601 format (the default)
-            APIField('published_date'),
-
-            # A separate published_date_display field with a different format
-            APIField('published_date_display', serializer=DateField(format='%A %d %B %Y', source='published_date')),
-            ...
-        ]
-
-This adds two fields to the API (other fields omitted for brevity):
-
-.. code-block:: json
-
-    {
-        "published_date": "2017-04-06",
-        "published_date_display": "Thursday 06 April 2017"
-    }
-
-.. _Serialisers: https://www.django-rest-framework.org/api-guide/fields/
-.. _source: https://www.django-rest-framework.org/api-guide/fields/#source
-
-Images in the API
------------------
-
-The :class:`~wagtail.images.api.fields.ImageRenditionField` serialiser
-allows you to add renditions of images into your API. It requires an image
-filter string specifying the resize operations to perform on the image. It can
-also take the ``source`` keyword argument described above.
-
-For example:
-
-.. code-block:: python
-
-    from wagtail.api import APIField
-    from wagtail.images.api.fields import ImageRenditionField
-
-    class BlogPage(Page):
-        ...
-
-        api_fields = [
-            # Adds information about the source image (eg, title) into the API
-            APIField('feed_image'),
-
-            # Adds a URL to a rendered thumbnail of the image to the API
-            APIField('feed_image_thumbnail', serializer=ImageRenditionField('fill-100x100', source='feed_image')),
-            ...
-        ]
-
-This would add the following to the JSON:
-
-.. code-block:: json
-
-    {
-        "feed_image": {
-            "id": 45529,
-            "meta": {
-                "type": "wagtailimages.Image",
-                "detail_url": "http://www.example.com/api/v2/images/12/",
-                "download_url": "/media/images/a_test_image.jpg",
-                "tags": []
-            },
-            "title": "A test image",
-            "width": 2000,
-            "height": 1125
-        },
-        "feed_image_thumbnail": {
-            "url": "/media/images/a_test_image.fill-100x100.jpg",
-            "full_url": "http://www.example.com/media/images/a_test_image.fill-100x100.jpg",
-            "width": 100,
-            "height": 100,
-            "alt": "image alt text"
-        }
-    }
-
-
-Note: ``download_url`` is the original uploaded file path, whereas
-``feed_image_thumbnail['url']`` is the url of the rendered image.
-When you are using another storage backend, such as S3, ``download_url`` will return
-a URL to the image if your media files are properly configured.
-
-Additional settings
-===================
-
-``WAGTAILAPI_BASE_URL``
------------------------
-
-(required when using frontend cache invalidation)
-
-This is used in two places, when generating absolute URLs to document files and
-invalidating the cache.
-
-Generating URLs to documents will fall back the the current request's hostname
-if this is not set. Cache invalidation cannot do this, however, so this setting
-must be set when using this module alongside the ``wagtailfrontendcache`` module.
-
-``WAGTAILAPI_SEARCH_ENABLED``
------------------------------
-
-(default: True)
-
-Setting this to false will disable full text search. This applies to all
-endpoints.
-
-``WAGTAILAPI_LIMIT_MAX``
-------------------------
-
-(default: 20)
-
-This allows you to change the maximum number of results a user can request at a
-time. This applies to all endpoints. Set to ``None`` for no limit.

+ 603 - 0
docs/advanced_topics/api/v2/usage.md

@@ -0,0 +1,603 @@
+# Wagtail API v2 Usage Guide
+
+The Wagtail API module exposes a public, read only, JSON-formatted API which
+can be used by external clients (such as a mobile app) or the site's frontend.
+
+This document is intended for developers using the API exposed by Wagtail. For
+documentation on how to enable the API module in your Wagtail site, see
+[Wagtail API v2 Configuration Guide](/advanced_topics/api/v2/configuration)
+
+Contents
+
+```{contents}
+---
+local:
+depth: 3
+---
+```
+
+## Fetching content
+
+To fetch content over the API, perform a `GET` request against one of the
+following endpoints:
+
+-   Pages `/api/v2/pages/`
+-   Images `/api/v2/images/`
+-   Documents `/api/v2/documents/`
+
+```{note}
+The available endpoints and their URLs may vary from site to site, depending
+on how the API has been configured.
+```
+
+### Example response
+
+Each response contains the list of items (`items`) and the total count
+(`meta.total_count`). The total count is irrespective of pagination.
+
+```text
+GET /api/v2/endpoint_name/
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": "total number of results"
+    },
+    "items": [
+        {
+            "id": 1,
+            "meta": {
+                "type": "app_name.ModelName",
+                "detail_url": "http://api.example.com/api/v2/endpoint_name/1/"
+            },
+            "field": "value"
+        },
+        {
+            "id": 2,
+            "meta": {
+                "type": "app_name.ModelName",
+                "detail_url": "http://api.example.com/api/v2/endpoint_name/2/"
+            },
+            "field": "different value"
+        }
+    ]
+}
+```
+
+(apiv2_custom_page_fields)=
+
+### Custom page fields in the API
+
+Wagtail sites contain many page types, each with their own set of fields. The
+`pages` endpoint will only expose the common fields by default (such as
+`title` and `slug`).
+
+To access custom page fields with the API, select the page type with the
+`?type` parameter. This will filter the results to only include pages of that
+type but will also make all the exported custom fields for that type available
+in the API.
+
+For example, to access the `published_date`, `body` and `authors` fields
+on the `blog.BlogPage` model in the [configuration docs](apiv2_page_fields_configuration):
+
+```
+GET /api/v2/pages/?type=blog.BlogPage&fields=published_date,body,authors(name)
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 10
+    },
+    "items": [
+        {
+            "id": 1,
+            "meta": {
+                "type": "blog.BlogPage",
+                "detail_url": "http://api.example.com/api/v2/pages/1/",
+                "html_url": "http://www.example.com/blog/my-blog-post/",
+                "slug": "my-blog-post",
+                "first_published_at": "2016-08-30T16:52:00Z"
+            },
+            "title": "Test blog post",
+            "published_date": "2016-08-30",
+            "authors": [
+                {
+                    "id": 1,
+                    "meta": {
+                        "type": "blog.BlogPageAuthor",
+                    },
+                    "name": "Karl Hobley"
+                }
+            ]
+        },
+
+        ...
+    ]
+}
+```
+
+```{note}
+Only fields that have been explicitly exported by the developer may be used
+in the API. This is done by adding a `api_fields` attribute to the page
+model. You can read about configuration [here](apiv2_page_fields_configuration).
+```
+
+This doesn't apply to images/documents as there is only one model exposed in
+those endpoints. But for projects that have customized image/document models,
+the `api_fields` attribute can be used to export any custom fields into the
+API.
+
+### Pagination
+
+The number of items in the response can be changed by using the `?limit`
+parameter (default: 20) and the number of items to skip can be changed by using
+the `?offset` parameter.
+
+For example:
+
+```
+GET /api/v2/pages/?offset=20&limit=20
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 50
+    },
+    "items": [
+        pages 20 - 40 will be listed here.
+    ]
+}
+```
+
+```{note}
+There may be a maximum value for the `?limit` parameter. This can be
+modified in your project settings by setting `WAGTAILAPI_LIMIT_MAX` to
+either a number (the new maximum value) or `None` (which disables maximum
+value check).
+```
+
+### Ordering
+
+The results can be ordered by any field by setting the `?order` parameter to
+the name of the field to order by.
+
+```
+GET /api/v2/pages/?order=title
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 50
+    },
+    "items": [
+        pages will be listed here in ascending title order (a-z)
+    ]
+}
+```
+
+The results will be ordered in ascending order by default. This can be changed
+to descending order by prefixing the field name with a `-` sign.
+
+```
+GET /api/v2/pages/?order=-title
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 50
+    },
+    "items": [
+        pages will be listed here in descending title order (z-a)
+    ]
+}
+```
+
+```{note}
+Ordering is case-sensitive so lowercase letters are always ordered after
+uppercase letters when in ascending order.
+```
+
+#### Random ordering
+
+Passing `random` into the `?order` parameter will make results return in a
+random order. If there is no caching, each request will return results in a
+different order.
+
+```
+GET /api/v2/pages/?order=random
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 50
+    },
+    "items": [
+        pages will be listed here in random order
+    ]
+}
+```
+
+```{note}
+It's not possible to use `?offset` while ordering randomly because
+consistent random ordering cannot be guaranteed over multiple requests
+(so requests for subsequent pages may return results that also appeared in
+previous pages).
+```
+
+### Filtering
+
+Any field may be used in an exact match filter. Use the filter name as the
+parameter and the value to match against.
+
+For example, to find a page with the slug "about":
+
+```
+GET /api/v2/pages/?slug=about
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 1
+    },
+    "items": [
+        {
+            "id": 10,
+            "meta": {
+                "type": "standard.StandardPage",
+                "detail_url": "http://api.example.com/api/v2/pages/10/",
+                "html_url": "http://www.example.com/about/",
+                "slug": "about",
+                "first_published_at": "2016-08-30T16:52:00Z"
+            },
+            "title": "About"
+        },
+    ]
+}
+```
+
+(apiv2_filter_by_tree_position)=
+
+### Filtering by tree position (pages only)
+
+Pages can additionally be filtered by their relation to other pages in the tree.
+
+The `?child_of` filter takes the id of a page and filters the list of results
+to contain only direct children of that page.
+
+For example, this can be useful for constructing the main menu, by passing the
+id of the homepage to the filter:
+
+```
+GET /api/v2/pages/?child_of=2&show_in_menus=true
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 5
+    },
+    "items": [
+        {
+            "id": 3,
+            "meta": {
+                "type": "blog.BlogIndexPage",
+                "detail_url": "http://api.example.com/api/v2/pages/3/",
+                "html_url": "http://www.example.com/blog/",
+                "slug": "blog",
+                "first_published_at": "2016-09-21T13:54:00Z"
+            },
+            "title": "About"
+        },
+        {
+            "id": 10,
+            "meta": {
+                "type": "standard.StandardPage",
+                "detail_url": "http://api.example.com/api/v2/pages/10/",
+                "html_url": "http://www.example.com/about/",
+                "slug": "about",
+                "first_published_at": "2016-08-30T16:52:00Z"
+            },
+            "title": "About"
+        },
+
+        ...
+    ]
+}
+```
+
+The `?ancestor_of` filter takes the id of a page and filters the list
+to only include ancestors of that page (parent, grandparent etc.) all the
+way down to the site's root page.
+
+For example, when combined with the `type` filter it can be used to
+find the particular `blog.BlogIndexPage` a `blog.BlogPage` belongs
+to. By itself, it can be used to to construct a breadcrumb trail from
+the current page back to the site's root page.
+
+The `?descendant_of` filter takes the id of a page and filter the list
+to only include descendants of that page (children, grandchildren etc.).
+
+### Search
+
+Passing a query to the `?search` parameter will perform a full-text search on
+the results.
+
+The query is split into "terms" (by word boundary), then each term is normalized
+(lowercased and unaccented).
+
+For example: `?search=James+Joyce`
+
+#### Search operator
+
+The `search_operator` specifies how multiple terms in the query should be
+handled. There are two possible values:
+
+-   `and` - All terms in the search query (excluding stop words) must exist in
+    each result
+-   `or` - At least one term in the search query must exist in each result
+
+The `or` operator is generally better than `and` as it allows the user to be
+inexact with their query and the ranking algorithm will make sure that
+irrelevant results are not returned at the top of the page.
+
+The default search operator depends on whether the search engine being used by
+the site supports ranking. If it does (Elasticsearch), the operator will default
+to `or`. Otherwise (database), it will default to `and`.
+
+For the same reason, it's also recommended to use the `and` operator when
+using `?search` in conjunction with `?order` (as this disables ranking).
+
+For example: `?search=James+Joyce&order=-first_published_at&search_operator=and`
+
+(apiv2_i18n_filters)=
+
+### Special filters for internationalized sites
+
+When `WAGTAIL_I18N_ENABLED` is set to `True` (see
+[](enabling_internationalisation) for more details) two new filters are made
+available on the pages endpoint.
+
+#### Filtering pages by locale
+
+The `?locale=` filter is used to filter the listing to only include pages in
+the specified locale. For example:
+
+```
+GET /api/v2/pages/?locale=en-us
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 5
+    },
+    "items": [
+        {
+            "id": 10,
+            "meta": {
+                "type": "standard.StandardPage",
+                "detail_url": "http://api.example.com/api/v2/pages/10/",
+                "html_url": "http://www.example.com/usa-page/",
+                "slug": "usa-page",
+                "first_published_at": "2016-08-30T16:52:00Z",
+                "locale": "en-us"
+            },
+            "title": "American page"
+        },
+
+        ...
+    ]
+}
+```
+
+#### Getting translations of a page
+
+The `?translation_of` filter is used to filter the listing to only include
+pages that are a translation of the specified page ID. For example:
+
+```
+GET /api/v2/pages/?translation_of=10
+
+HTTP 200 OK
+Content-Type: application/json
+
+{
+    "meta": {
+        "total_count": 2
+    },
+    "items": [
+        {
+            "id": 11,
+            "meta": {
+                "type": "standard.StandardPage",
+                "detail_url": "http://api.example.com/api/v2/pages/11/",
+                "html_url": "http://www.example.com/gb-page/",
+                "slug": "gb-page",
+                "first_published_at": "2016-08-30T16:52:00Z",
+                "locale": "en-gb"
+            },
+            "title": "British page"
+        },
+        {
+            "id": 12,
+            "meta": {
+                "type": "standard.StandardPage",
+                "detail_url": "http://api.example.com/api/v2/pages/12/",
+                "html_url": "http://www.example.com/fr-page/",
+                "slug": "fr-page",
+                "first_published_at": "2016-08-30T16:52:00Z",
+                "locale": "fr"
+            },
+            "title": "French page"
+        },
+    ]
+}
+```
+
+### Fields
+
+By default, only a subset of the available fields are returned in the response.
+The `?fields` parameter can be used to both add additional fields to the
+response and remove default fields that you know you won't need.
+
+#### Additional fields
+
+Additional fields can be added to the response by setting `?fields` to a
+comma-separated list of field names you want to add.
+
+For example, `?fields=body,feed_image` will add the `body` and `feed_image`
+fields to the response.
+
+This can also be used across relationships. For example,
+`?fields=body,feed_image(width,height)` will nest the `width` and `height`
+of the image in the response.
+
+#### All fields
+
+Setting `?fields` to an asterisk (`*`) will add all available fields to the
+response. This is useful for discovering what fields have been exported.
+
+For example: `?fields=*`
+
+#### Removing fields
+
+Fields you know that you do not need can be removed by prefixing the name with a
+`-` and adding it to `?fields`.
+
+For example, `?fields=-title,body` will remove `title` and add `body`.
+
+This can also be used with the asterisk. For example, `?fields=*,-body`
+adds all fields except for `body`.
+
+#### Removing all default fields
+
+To specify exactly the fields you need, you can set the first item in fields to
+an underscore (`_`) which removes all default fields.
+
+For example, `?fields=_,title` will only return the title field.
+
+### Detail views
+
+You can retrieve a single object from the API by appending its id to the end of
+the URL. For example:
+
+-   Pages `/api/v2/pages/1/`
+-   Images `/api/v2/images/1/`
+-   Documents `/api/v2/documents/1/`
+
+All exported fields will be returned in the response by default. You can use the
+`?fields` parameter to customize which fields are shown.
+
+For example: `/api/v2/pages/1/?fields=_,title,body` will return just the
+`title` and `body` of the page with the id of 1.
+
+(apiv2_finding_pages_by_path)=
+
+### Finding pages by HTML path
+
+You can find an individual page by its HTML path using the `/api/v2/pages/find/?html_path=<path>` view.
+
+This will return either a `302` redirect response to that page's detail view, or a `404` not found response.
+
+For example: `/api/v2/pages/find/?html_path=/` always redirects to the homepage of the site
+
+## Default endpoint fields
+
+### Common fields
+
+These fields are returned by every endpoint.
+
+**`id` (number)**  
+The unique ID of the object
+
+```{note}
+Except for page types, every other content type has its own id space
+so you must combine this with the ``type`` field in order to get a
+unique identifier for an object.
+```
+
+**`type` (string)**  
+The type of the object in `app_label.ModelName` format
+
+**`detail_url` (string)**  
+The URL of the detail view for the object
+
+### Pages
+
+**`title` (string)**  
+**`meta.slug` (string)**  
+**`meta.show_in_menus` (boolean)**  
+**`meta.seo_title` (string)**  
+**`meta.search_description` (string)**  
+**`meta.first_published_at` (date/time)**  
+These values are taken from their corresponding fields on the page
+
+**`meta.html_url` (string)**  
+If the site has an HTML frontend that's generated by Wagtail, this
+field will be set to the URL of this page
+
+**`meta.parent`**  
+Nests some information about the parent page (only available on detail
+views)
+
+**`meta.alias_of` (dictionary)**  
+If the page marked as an alias return original page id and full url
+
+### Images
+
+**`title` (string)**  
+The value of the image's title field. Within Wagtail, this is used in
+the image's `alt` HTML attribute.
+
+**`width` (number)**  
+**`height` (number)**  
+The size of the original image file
+
+**`meta.tags` (list of strings)**  
+A list of tags associated with the image
+
+### Documents
+
+**`title` (string)**  
+The value of the document's title field
+
+**`meta.tags` (list of strings)**  
+A list of tags associated with the document
+
+**`meta.download_url` (string)**  
+A URL to the document file
+
+## Changes since v1
+
+### Breaking changes
+
+-   The results list in listing responses has been renamed to `items` (was previously either `pages`, `images` or `documents`)
+
+### Major features
+
+-   The `fields` parameter has been improved to allow removing fields, adding all fields and customising nested fields
+
+### Minor features
+
+-   `html_url`, `slug`, `first_published_at`, `expires_at` and `show_in_menus` fields have been added to the pages endpoint
+-   `download_url` field has been added to the documents endpoint
+-   Multiple page types can be specified in `type` parameter on pages endpoint
+-   `true` and `false` may now be used when filtering boolean fields
+-   `order` can now be used in conjunction with `search`
+-   `search_operator` parameter was added

+ 0 - 652
docs/advanced_topics/api/v2/usage.rst

@@ -1,652 +0,0 @@
-==========================
-Wagtail API v2 Usage Guide
-==========================
-
-The Wagtail API module exposes a public, read only, JSON-formatted API which
-can be used by external clients (such as a mobile app) or the site's frontend.
-
-This document is intended for developers using the API exposed by Wagtail. For
-documentation on how to enable the API module in your Wagtail site, see
-:doc:`/advanced_topics/api/v2/configuration`
-
-.. contents::
-
-Fetching content
-================
-
-To fetch content over the API, perform a ``GET`` request against one of the
-following endpoints:
-
-- Pages ``/api/v2/pages/``
-- Images ``/api/v2/images/``
-- Documents ``/api/v2/documents/``
-
-.. note::
-
-    The available endpoints and their URLs may vary from site to site, depending
-    on how the API has been configured.
-
-Example response
-----------------
-
-Each response contains the list of items (``items``) and the total count
-(``meta.total_count``). The total count is irrespective of pagination.
-
-.. code-block:: text
-
-    GET /api/v2/endpoint_name/
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": "total number of results"
-        },
-        "items": [
-            {
-                "id": 1,
-                "meta": {
-                    "type": "app_name.ModelName",
-                    "detail_url": "http://api.example.com/api/v2/endpoint_name/1/"
-                },
-                "field": "value"
-            },
-            {
-                "id": 2,
-                "meta": {
-                    "type": "app_name.ModelName",
-                    "detail_url": "http://api.example.com/api/v2/endpoint_name/2/"
-                },
-                "field": "different value"
-            }
-        ]
-    }
-
-.. _apiv2_custom_page_fields:
-
-Custom page fields in the API
------------------------------
-
-Wagtail sites contain many page types, each with their own set of fields. The
-``pages`` endpoint will only expose the common fields by default (such as
-``title`` and ``slug``).
-
-To access custom page fields with the API, select the page type with the
-``?type`` parameter. This will filter the results to only include pages of that
-type but will also make all the exported custom fields for that type available
-in the API.
-
-For example, to access the ``published_date``, ``body`` and ``authors`` fields
-on the ``blog.BlogPage`` model in the :ref:`configuration docs <apiv2_page_fields_configuration>`:
-
-.. code-block:: text
-
-    GET /api/v2/pages/?type=blog.BlogPage&fields=published_date,body,authors(name)
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 10
-        },
-        "items": [
-            {
-                "id": 1,
-                "meta": {
-                    "type": "blog.BlogPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/1/",
-                    "html_url": "http://www.example.com/blog/my-blog-post/",
-                    "slug": "my-blog-post",
-                    "first_published_at": "2016-08-30T16:52:00Z"
-                },
-                "title": "Test blog post",
-                "published_date": "2016-08-30",
-                "authors": [
-                    {
-                        "id": 1,
-                        "meta": {
-                            "type": "blog.BlogPageAuthor",
-                        },
-                        "name": "Karl Hobley"
-                    }
-                ]
-            },
-
-            ...
-        ]
-    }
-
-.. note::
-
-    Only fields that have been explicitly exported by the developer may be used
-    in the API. This is done by adding a ``api_fields`` attribute to the page
-    model. You can read about configuration :ref:`here <apiv2_page_fields_configuration>`.
-
-This doesn't apply to images/documents as there is only one model exposed in
-those endpoints. But for projects that have customised image/document models,
-the ``api_fields`` attribute can be used to export any custom fields into the
-API.
-
-Pagination
-----------
-
-The number of items in the response can be changed by using the ``?limit``
-parameter (default: 20) and the number of items to skip can be changed by using
-the ``?offset`` parameter.
-
-For example:
-
-.. code-block:: text
-
-    GET /api/v2/pages/?offset=20&limit=20
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 50
-        },
-        "items": [
-            pages 20 - 40 will be listed here.
-        ]
-    }
-
-.. note::
-
-    There may be a maximum value for the ``?limit`` parameter. This can be
-    modified in your project settings by setting ``WAGTAILAPI_LIMIT_MAX`` to
-    either a number (the new maximum value) or ``None`` (which disables maximum
-    value check).
-
-Ordering
---------
-
-The results can be ordered by any field by setting the ``?order`` parameter to
-the name of the field to order by.
-
-.. code-block:: text
-
-    GET /api/v2/pages/?order=title
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 50
-        },
-        "items": [
-            pages will be listed here in ascending title order (a-z)
-        ]
-    }
-
-The results will be ordered in ascending order by default. This can be changed
-to descending order by prefixing the field name with a ``-`` sign.
-
-.. code-block:: text
-
-    GET /api/v2/pages/?order=-title
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 50
-        },
-        "items": [
-            pages will be listed here in descending title order (z-a)
-        ]
-    }
-
-.. note::
-
-    Ordering is case-sensitive so lowercase letters are always ordered after
-    uppercase letters when in ascending order.
-
-Random ordering
-^^^^^^^^^^^^^^^
-
-Passing ``random`` into the ``?order`` parameter will make results return in a
-random order. If there is no caching, each request will return results in a
-different order.
-
-.. code-block:: text
-
-    GET /api/v2/pages/?order=random
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 50
-        },
-        "items": [
-            pages will be listed here in random order
-        ]
-    }
-
-.. note::
-
-    It's not possible to use ``?offset`` while ordering randomly because
-    consistent random ordering cannot be guaranteed over multiple requests
-    (so requests for subsequent pages may return results that also appeared in
-    previous pages).
-
-Filtering
----------
-
-Any field may be used in an exact match filter. Use the filter name as the
-parameter and the value to match against.
-
-For example, to find a page with the slug "about":
-
-.. code-block:: text
-
-    GET /api/v2/pages/?slug=about
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 1
-        },
-        "items": [
-            {
-                "id": 10,
-                "meta": {
-                    "type": "standard.StandardPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/10/",
-                    "html_url": "http://www.example.com/about/",
-                    "slug": "about",
-                    "first_published_at": "2016-08-30T16:52:00Z"
-                },
-                "title": "About"
-            },
-        ]
-    }
-
-.. _apiv2_filter_by_tree_position:
-
-Filtering by tree position (pages only)
----------------------------------------
-
-Pages can additionally be filtered by their relation to other pages in the tree.
-
-The ``?child_of`` filter takes the id of a page and filters the list of results
-to contain only direct children of that page.
-
-For example, this can be useful for constructing the main menu, by passing the
-id of the homepage to the filter:
-
-.. code-block:: text
-
-    GET /api/v2/pages/?child_of=2&show_in_menus=true
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 5
-        },
-        "items": [
-            {
-                "id": 3,
-                "meta": {
-                    "type": "blog.BlogIndexPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/3/",
-                    "html_url": "http://www.example.com/blog/",
-                    "slug": "blog",
-                    "first_published_at": "2016-09-21T13:54:00Z"
-                },
-                "title": "About"
-            },
-            {
-                "id": 10,
-                "meta": {
-                    "type": "standard.StandardPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/10/",
-                    "html_url": "http://www.example.com/about/",
-                    "slug": "about",
-                    "first_published_at": "2016-08-30T16:52:00Z"
-                },
-                "title": "About"
-            },
-
-            ...
-        ]
-    }
-
-The ``?ancestor_of`` filter takes the id of a page and filters the list
-to only include ancestors of that page (parent, grandparent etc.) all the
-way down to the site's root page.
-
-For example, when combined with the ``type`` filter it can be used to
-find the particular ``blog.BlogIndexPage`` a ``blog.BlogPage`` belongs
-to. By itself, it can be used to to construct a breadcrumb trail from
-the current page back to the site's root page.
-
-The ``?descendant_of`` filter takes the id of a page and filter the list
-to only include descendants of that page (children, grandchildren etc.).
-
-Search
-------
-
-Passing a query to the ``?search`` parameter will perform a full-text search on
-the results.
-
-The query is split into "terms" (by word boundary), then each term is normalised
-(lowercased and unaccented).
-
-For example: ``?search=James+Joyce``
-
-Search operator
-^^^^^^^^^^^^^^^
-
-The ``search_operator`` specifies how multiple terms in the query should be
-handled. There are two possible values:
-
-- ``and`` - All terms in the search query (excluding stop words) must exist in
-  each result
-- ``or`` - At least one term in the search query must exist in each result
-
-The ``or`` operator is generally better than ``and`` as it allows the user to be
-inexact with their query and the ranking algorithm will make sure that
-irrelevant results are not returned at the top of the page.
-
-The default search operator depends on whether the search engine being used by
-the site supports ranking. If it does (Elasticsearch), the operator will default
-to ``or``. Otherwise (database), it will default to ``and``.
-
-For the same reason, it's also recommended to use the ``and`` operator when
-using ``?search`` in conjunction with ``?order`` (as this disables ranking).
-
-For example: ``?search=James+Joyce&order=-first_published_at&search_operator=and``
-
-.. _apiv2_i18n_filters:
-
-Special filters for internationalised sites
--------------------------------------------
-
-When ``WAGTAIL_I18N_ENABLED`` is set to ``True`` (see
-:ref:`enabling_internationalisation` for more details) two new filters are made
-available on the pages endpoint.
-
-Filtering pages by locale
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``?locale=`` filter is used to filter the listing to only include pages in
-the specified locale. For example:
-
-.. code-block:: text
-
-    GET /api/v2/pages/?locale=en-us
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 5
-        },
-        "items": [
-            {
-                "id": 10,
-                "meta": {
-                    "type": "standard.StandardPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/10/",
-                    "html_url": "http://www.example.com/usa-page/",
-                    "slug": "usa-page",
-                    "first_published_at": "2016-08-30T16:52:00Z",
-                    "locale": "en-us"
-                },
-                "title": "American page"
-            },
-
-            ...
-        ]
-    }
-
-Getting translations of a page
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The ``?translation_of`` filter is used to filter the listing to only include
-pages that are a translation of the specified page ID. For example:
-
-.. code-block:: text
-
-    GET /api/v2/pages/?translation_of=10
-
-    HTTP 200 OK
-    Content-Type: application/json
-
-    {
-        "meta": {
-            "total_count": 2
-        },
-        "items": [
-            {
-                "id": 11,
-                "meta": {
-                    "type": "standard.StandardPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/11/",
-                    "html_url": "http://www.example.com/gb-page/",
-                    "slug": "gb-page",
-                    "first_published_at": "2016-08-30T16:52:00Z",
-                    "locale": "en-gb"
-                },
-                "title": "British page"
-            },
-            {
-                "id": 12,
-                "meta": {
-                    "type": "standard.StandardPage",
-                    "detail_url": "http://api.example.com/api/v2/pages/12/",
-                    "html_url": "http://www.example.com/fr-page/",
-                    "slug": "fr-page",
-                    "first_published_at": "2016-08-30T16:52:00Z",
-                    "locale": "fr"
-                },
-                "title": "French page"
-            },
-        ]
-    }
-
-Fields
-------
-
-By default, only a subset of the available fields are returned in the response.
-The ``?fields`` parameter can be used to both add additional fields to the
-response and remove default fields that you know you won't need.
-
-Additional fields
-^^^^^^^^^^^^^^^^^
-
-Additional fields can be added to the response by setting ``?fields`` to a
-comma-separated list of field names you want to add.
-
-For example, ``?fields=body,feed_image`` will add the ``body`` and ``feed_image``
-fields to the response.
-
-This can also be used across relationships. For example,
-``?fields=body,feed_image(width,height)`` will nest the ``width`` and ``height``
-of the image in the response.
-
-All fields
-^^^^^^^^^^
-
-Setting ``?fields`` to an asterisk (``*``) will add all available fields to the
-response. This is useful for discovering what fields have been exported.
-
-For example: ``?fields=*``
-
-Removing fields
-^^^^^^^^^^^^^^^
-
-Fields you know that you do not need can be removed by prefixing the name with a
-``-`` and adding it to ``?fields``.
-
-For example, ``?fields=-title,body`` will remove ``title`` and add ``body``.
-
-This can also be used with the asterisk. For example, ``?fields=*,-body``
-adds all fields except for ``body``.
-
-Removing all default fields
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To specify exactly the fields you need, you can set the first item in fields to
-an underscore (``_``) which removes all default fields.
-
-For example, ``?fields=_,title`` will only return the title field.
-
-Detail views
-------------
-
-You can retrieve a single object from the API by appending its id to the end of
-the URL. For example:
-
-- Pages ``/api/v2/pages/1/``
-- Images ``/api/v2/images/1/``
-- Documents ``/api/v2/documents/1/``
-
-All exported fields will be returned in the response by default. You can use the
-``?fields`` parameter to customise which fields are shown.
-
-For example: ``/api/v2/pages/1/?fields=_,title,body`` will return just the
-``title`` and ``body`` of the page with the id of 1.
-
-
-.. _apiv2_finding_pages_by_path:
-
-Finding pages by HTML path
---------------------------
-
-You can find an individual page by its HTML path using the ``/api/v2/pages/find/?html_path=<path>`` view.
-
-This will return either a ``302`` redirect response to that page's detail view, or a ``404`` not found response.
-
-For example: ``/api/v2/pages/find/?html_path=/`` always redirects to the homepage of the site
-
-Default endpoint fields
-=======================
-
-Common fields
--------------
-
-These fields are returned by every endpoint.
-
-.. glossary::
-
-    ``id``  (number)
-
-        The unique ID of the object
-
-        .. note::
-
-            Except for page types, every other content type has its own id space
-            so you must combine this with the ``type`` field in order to get a
-            unique identifier for an object.
-
-    ``type`` (string)
-
-        The type of the object in ``app_label.ModelName`` format
-
-    ``detail_url``  (string)
-
-        The URL of the detail view for the object
-
-Pages
------
-
-.. glossary::
-
-    ``title``  (string)
-    ``meta.slug``  (string)
-    ``meta.show_in_menus``  (boolean)
-    ``meta.seo_title``  (string)
-    ``meta.search_description``  (string)
-    ``meta.first_published_at``  (date/time)
-
-        These values are taken from their corresponding fields on the page
-
-    ``meta.html_url``  (string)
-
-        If the site has an HTML frontend that's generated by Wagtail, this
-        field will be set to the URL of this page
-
-    ``meta.parent``
-
-        Nests some information about the parent page (only available on detail
-        views)
-
-    ``meta.alias_of`` (dictionary)
-
-        If the page marked as an alias return original page id and full url
-
-Images
-------
-
-.. glossary::
-
-    ``title``  (string)
-
-        The value of the image's title field. Within Wagtail, this is used in
-        the image's ``alt`` HTML attribute.
-
-    ``width``  (number)
-    ``height``  (number)
-
-        The size of the original image file
-
-    ``meta.tags``  (list of strings)
-
-        A list of tags associated with the image
-
-Documents
----------
-
-.. glossary::
-
-    ``title``  (string)
-
-        The value of the document's title field
-
-    ``meta.tags``  (list of strings)
-
-        A list of tags associated with the document
-
-    ``meta.download_url``  (string)
-
-        A URL to the document file
-
-Changes since v1
-================
-
-Breaking changes
-----------------
-
-- The results list in listing responses has been renamed to ``items`` (was
-  previously either ``pages``, ``images`` or ``documents``)
-
-Major features
---------------
-
-- The ``fields`` parameter has been improved to allow removing fields, adding
-  all fields and customising nested fields
-
-Minor features
---------------
-
-- ``html_url``, ``slug``, ``first_published_at``, ``expires_at`` and
-  ``show_in_menus`` fields have been added to the pages endpoint
-- ``download_url`` field has been added to the documents endpoint
-- Multiple page types can be specified in ``type`` parameter on pages endpoint
-- ``true`` and ``false`` may now be used when filtering boolean fields
-- ``order`` can now be used in conjunction with ``search``
-- ``search_operator`` parameter was added

+ 1 - 1
docs/releases/4.0.md

@@ -12,7 +12,7 @@ depth: 1
 ### Other features
 
  * Add clarity to confirmation when being asked to convert an external link to an internal one (Thijs Kramer)
- * Convert various pages in the documentation to Markdown (Khanh Hoang, Vu Pham, Daniel Kirkham, LB (Ben) Johnston)
+ * Convert various pages in the documentation to Markdown (Khanh Hoang, Vu Pham, Daniel Kirkham, LB (Ben) Johnston, Thiago Costa de Souza)
  * Add `base_url_path` to `ModelAdmin` so that the default URL structure of app_label/model_name can be overridden (Vu Pham, Khanh Hoang)
  * Add `full_url` to the API output of `ImageRenditionField` (Paarth Agarwal)
  * Use `InlinePanel`'s label when available for field comparison label (Sandil Ranasinghe)