Article and Forms API

Molo extends the Wagtail API for serving content from the CMS as JSON. This documentation will only cover additions to the functionality. For more information please see the documentation for the Wagtail API

The documentation also covers endpoints added in the molo.forms plugin. This plugin can be found on GitHub

Articles

A custom endpoint is used to ensure that draft pages will also be returned (this is required for the content import API).

Pages endpoints

  • List Endpoint /api/v2/pages/

  • Detail Endpoint /api/v2/page/<page_id>/

Notable “?type” options

core.BannerPage

Custom fields:

title, subtitle, banner, banner_link_page, external_link

core.ArticlePage

A special case is added to the MoloPageEndpoint: If filtering with ?type=core.ArticlePage then the pages can also be filtered by the tag attribute of the nav_tags field using nav_tags__tag=<tag_id> Custom fields:

title, subtitle, body, tags, commenting_state, commenting_open_time,
commenting_close_time, social_media_title, social_media_description,
social_media_image, related_sections, featured_in_latest,
featured_in_latest_start_date, featured_in_latest_end_date, featured_in_section,
featured_in_section_start_date, featured_in_section_end_date,
featured_in_homepage, featured_in_homepage_start_date,
featured_in_homepage_end_date, feature_as_hero_article, promote_date,
demote_date, metadata_tags, latest_revision_created_at, image, social_media_image,
social_media_description, social_media_title, nav_tags,
recommended_articles, related_sections, go_live_at, expire_at, expired, live

core.SectionPage

Custom fields:

title, live, description, image, extra_style_hints, commenting_state,
commenting_open_time, commenting_close_time, time, monday_rotation,
tuesday_rotation, wednesday_rotation, thursday_rotation, friday_rotation,
saturday_rotation, sunday_rotation, content_rotation_start_date,
content_rotation_end_date, section_tags, enable_next_section,
enable_recommended_section, go_live_at, expire_at, expired

core.Tag

Custom fields:

id, title, feature_in_homepage, go_live_at, expire_at, expired

forms.MoloFormPage

Custom fields:

live, form_fields, introduction, image, thank_you_text, allow_anonymous_submissions

core.FooterPage

core.ReactionQuestion

core.ReactionQuestionChoice

profiles.SecurityQuestionforms.PersonalisableForm

Examples

List endpoint:

 1GET /api/v2/pages/?type=core.ArticlePage&live=true
 2
 3HTTP 200 OK
 4Content-Type: application/json
 5{
 6    "meta": {
 7        "total_count": 10
 8    },
 9    "items": [
10        {
11            "id": 66,
12            "meta": {
13                "type": "core.ArticlePage",
14                "detail_url": "http://api.example.com/api/v2/pages/66/",
15                "html_url": "http://api.example.com/sections/my-life/be-the-best-to-your-bestie/",
16                "slug": "be-the-best-to-your-bestie",
17                "first_published_at": "2016-09-23T17:42:31.776234+02:00"
18            },
19            "title": "Be the best to your bestie"
20        },
21        {
22            "id": 72,
23            "meta": {
24                "type": "core.ArticlePage",
25                "detail_url": "http://api.example.com/api/v2/pages/72/",
26                "html_url": "http://api.example.com/sections/my-life/too-many-selfies-yes-or-no/",
27                "slug": "too-many-selfies-yes-or-no",
28                "first_published_at": "2016-09-23T17:42:33.611393+02:00"
29            },
30            "title": "Too many selfies?"
31        },
32
3334    ]
35}

Detail endpoint:

  1GET /api/v2/pages/66/
  2
  3HTTP 200 OK
  4Content-Type: application/json
  5{
  6    "id": 66,
  7    "meta": {
  8        "type": "core.ArticlePage",
  9        "detail_url": "http://api.example.com/api/v2/pages/66/",
 10        "html_url": "http://api.example.com/sections/my-life/be-the-best-to-your-bestie/",
 11        "slug": "be-the-best-to-your-bestie",
 12        "show_in_menus": false,
 13        "seo_title": "",
 14        "search_description": "",
 15        "first_published_at": "2016-09-23T17:42:31.776234+02:00",
 16        "parent": {
 17            "id": 194,
 18            "meta": {
 19                "type": "core.SectionPage",
 20                "detail_url": "http://api.example.com/api/v2/pages/194/",
 21                "html_url": "http://api.example.com/sections/my-life/"
 22            },
 23            "title": "My Life"
 24        },
 25        "children": null,
 26        "translations": [
 27            {
 28                "id": 205,
 29                "locale": "th"
 30            }
 31        ],
 32        "main_language_children": null
 33    },
 34    "title": "Be the best to your bestie",
 35    "subtitle": "Not only now, but forever",
 36    "body": [
 37        {
 38            "type": "paragraph",
 39            "value": "...",
 40            "id": "171e98e1-30a6-40ea-b1cf-bfcac4a853a5"
 41        }
 42    ],
 43    "tags": [],
 44    "commenting_state": null,
 45    "commenting_open_time": null,
 46    "commenting_close_time": null,
 47    "social_media_title": "",
 48    "social_media_description": "",
 49    "social_media_image": null,
 50    "related_sections": [],
 51    "featured_in_latest": true,
 52    "featured_in_latest_start_date": "2018-12-31T08:00:00.180000+02:00",
 53    "featured_in_latest_end_date": null,
 54    "featured_in_section": false,
 55    "featured_in_section_start_date": null,
 56    "featured_in_section_end_date": null,
 57    "featured_in_homepage": false,
 58    "featured_in_homepage_start_date": null,
 59    "featured_in_homepage_end_date": null,
 60    "feature_as_hero_article": false,
 61    "promote_date": null,
 62    "demote_date": null,
 63    "metadata_tags": [],
 64    "latest_revision_created_at": "2018-12-31T08:00:00.286037+02:00",
 65    "image": {
 66        "id": 308,
 67        "meta": {
 68            "type": "wagtailimages.Image",
 69            "detail_url": "http://api.example.com/api/v2/images/308/",
 70            "download_url": "http://api.example.com/21_girlpack_friendship_feature_BeTheBestToYourBestie.jpg"
 71        },
 72        "title": "21_girlpack_friendship_feature_BeTheBestToYourBestie.jpg"
 73    },
 74    "nav_tags": [
 75        {
 76            "id": 276,
 77            "meta": {
 78                "type": "core.ArticlePageTags"
 79            },
 80            "tag": {
 81                "id": 395,
 82                "meta": {
 83                    "type": "core.Tag",
 84                    "detail_url": "http://api.example.com/api/v2/pages/395/"
 85                },
 86                "title": "friendship"
 87            }
 88        },
 89 90    ],
 91    "recommended_articles": [
 92        {
 93            "id": 40,
 94            "meta": {
 95                "type": "core.ArticlePageRecommendedSections"
 96            },
 97            "recommended_article": {
 98                "id": 90,
 99                "meta": {
100                    "type": "core.ArticlePage",
101                    "detail_url": "http://api.example.com/api/v2/pages/90/"
102                },
103                "title": "Do you want friends?"
104            }
105        }
106    ],
107    "go_live_at": null,
108    "expire_at": null,
109    "expired": false,
110    "live": true
111}

Forms

Molo.forms uses a custom serializer for the Form fields so that the forms.MoloFormPage detail endpoint returns the necessary information for each field. Available custom fields are as shown above. The API does not currently support viewing or creating submissions for forms.PersonalisableForms as such, these are excluded from the list view.

Forms endpoints

  • List Endpoint /api/v2/forms/

  • Detail Endpoint /api/v2/forms/<page_id>/

  • Submission Endpoint /api/v2/forms/<page_id>/submit_form/

Forms Submissions

A POST request to the form submission endpoint will attempt to create a form submission object from the submitted data. The endpoint accepts a JSON object with the input names as the attribute keys and the user responses as the values. An HTTP 201 is returned if the submission is valid and successful. An HTTP 400 will be returned if the form being submitted to is not live, if any of the data is invalid or if not all required fields are present. Submissions to forms that do not have the allow_multiple_submissions set to True will also return an HTTP 400 since authentication is not currently supported.

Examples

List Endpoint:

 1GET /api/v2/forms/?live=true
 2
 3HTTP 200 OK
 4Content-Type: application/json
 5{
 6    "meta": {
 7        "total_count": 8
 8    },
 9    "items": [
10        {
11            "id": 5,
12            "meta": {
13                "type": "forms.MoloFormPage",
14                "detail_url": "http://api.example.com/api/v2/pages/5/",
15                "html_url": "http://api.example.com/sections/my-future/test-page/",
16                "slug": "test-page",
17                "first_published_at": "2020-01-20T09:33:37.736336+02:00"
18            },
19            "title": "test page"
20        },
21        {
22            "id": 6,
23            "meta": {
24                "type": "forms.MoloFormPage",
25                "detail_url": "http://api.example.com/api/v2/pages/6/",
26                "html_url": "http://api.example.com/sections/my-future/show-me-money/do-you-really-want-see-money/",
27                "slug": "do-you-really-want-see-money",
28                "first_published_at": "2020-01-20T15:06:01.056130+02:00"
29            },
30            "title": "Do you really want to see the money?"
31        },
3233    ]
34}

Detail Endpoint:

 1GET /api/v2/forms/5/
 2
 3HTTP 200 OK
 4Content-Type: application/json
 5{
 6    "id": 5,
 7    "meta": {
 8        "type": "forms.MoloFormPage",
 9        "detail_url": "http://api.example.com/api/v2/pages/5/",
10        "html_url": "http://api.example.com/molo-forms/test-survey/",
11        "slug": "test-survey",
12        "show_in_menus": false,
13        "seo_title": "",
14        "search_description": "",
15        "first_published_at": "2020-01-22T17:49:37.263778+02:00",
16        "parent": {
17            "id": 1045,
18            "meta": {
19                "type": "forms.FormsIndexPage",
20                "detail_url": "http://api.example.com/api/v2/pages/5/",
21                "html_url": "http://api.example.com/molo-forms/"
22            },
23            "title": "Forms"
24        }
25    },
26    "title": "Kaitlyn Test Survey [As Forms]",
27    "live": true,
28    "form_fields": {
29        "items": [
30            {
31                "id": 7,
32                "sort_order": 0,
33                "label": "How do you feel the Content Repository work is going?",
34                "required": false,
35                "default_value": "",
36                "help_text": "",
37                "page_break": false,
38                "admin_label": "how-is-work-going",
39                "choices": "Good,Not great,I'm not sure",
40                "field_type": "dropdown",
41                "input_name": "how-do-you-feel-the-content-repository-work-is-going"
42            },
43            {
44                "id": 8,
45                "sort_order": 1,
46                "label": "Who is working on the content repository api?",
47                "required": true,
48                "default_value": "",
49                "help_text": "",
50                "page_break": false,
51                "admin_label": "who-is-building-it",
52                "choices": "Tom,Mary,Alex",
53                "field_type": "radio",
54                "input_name": "who-is-working-on-the-content-repository-api"
55            },
5657        ]
58    },
59    "introduction": "The goal of the content repository work is to make content accessible across different platforms.",
60    "image": {
61        "id": 563,
62        "meta": {
63            "type": "wagtailimages.Image",
64            "detail_url": "http://api.example.com/api/v2/images/563/",
65            "download_url": "http://api.example.com/original_images/overcomeshyness.png"
66        },
67        "title": "overcomeshyness.png"
68    },
69    "thank_you_text": "Great! Thanks for being involved in this demo!",
70    "allow_anonymous_submissions": true
71}

Submission Endpoint:

 1POST /api/v2/forms/5/submit_form/
 2{
 3    "how-do-you-feel-the-content-repository-work-is-going": "Good",
 4    "who-is-working-on-the-content-repository-api": "Alex"
 5}
 6
 7HTTP 201 CREATED
 8Content-Type: application/json
 9
10{
11    "how-do-you-feel-the-content-repository-work-is-going": "Good",
12    "who-is-working-on-the-content-repository-api": "Alex",
13}