diff --git a/docs/manual/forms/examples/form_with_geometry.rst b/docs/manual/forms/examples/form_with_geometry.rst new file mode 100644 index 0000000000..1b78ea3569 --- /dev/null +++ b/docs/manual/forms/examples/form_with_geometry.rst @@ -0,0 +1,115 @@ +.. _example_form_with_geometry: + +================================================ +Kaartmateriaal en registratie in de Objecten API +================================================ + +In dit formulier maken we gebruik van de "Kaart"-component om coördinaten van een +locatie uit te vragen en te registreren. Het formulier wordt gekoppeld met de +`Objecten API`_ voor het registreren van de inzendingsgegevens. + +We gaan er van uit dat de koppeling met de Objecten API +:ref:`geconfigureerd ` is, en gebruiken als +objecttype-URL ``https://objecttype-example.nl/api/v2/objecttype/123``. + +Formulier maken +=============== + +We bouwen een formulier met twee kaarten - één kaart wordt gebruikt voor "dé" geometrie +van het hele Object in de Objecten API en de andere kaart wordt als extra/vrije-vorm +attribuut meegestuurd. + +#. Maak een formulier aan met de volgende gegevens: + + * **Naam**: Kaartgegevens registreren in de Objecten API + +#. Klik op het tabblad **Stappen en velden**. +#. Klik aan de linkerkant op **Stap toevoegen** en selecteer **Maak een nieuwe + formulierdefinitie**. +#. Onder de sectie **(Herbruikbare) stapgegevens** vul het volgende in: + + * **Naam**: Kaarten + +#. Scrol naar beneden en klik de sectie **Speciale velden** aan. +#. Sleep een **Kaart** component op het witte vlak en vul de volgende + gegevens in: + + * **Label**: Hoofdgeometrie + +#. Klik vervolgens de **Registratie** tab aan en vul de volgende gegevens in: + + * **Registratie-attribuut**: Locatie > Coördinaten + +#. Druk daarna op **Opslaan**. + +#. Sleep een tweede **Kaart** component op het witte vlak, vul de volgende + gegevens in en druk daarna op **Opslaan**: + + * **Label**: Extra geometrie + +#. Klik op het tabblad **Registratie**. +#. Klik op **Registratiepluginoptie toevoegen** en vul de volgende gegevens in: + + * **Naam**: Objecten API + * **Registratiemethode**: Objecten API registratie + * **Objecttype**: ``https://objecttype-example.nl/api/v2/objecttype/123`` + * **JSON-inhoud sjabloon**: + + .. code-block:: django + + { + "extraGeometrie": {% as_geo_json variables.extraGeometrie %} + } + +#. Druk daarna op **Opslaan en opnieuw bewerken**. Het formulier kan nu ingevuld en + ingestuurd worden. + + +.. note:: Het inrichten van het Objecttype en de Objecten API is geen onderdeel van + dit voorbeeld, maar wel essentieel om zonder fouten formulierinzendingen te kunnen + verwerken. + + +Toelichting +=========== + +De eerste kaart is ingesteld via de "Registratie" tab op het component. Dit zorgt ervoor +dat de Objecten API-registratieplugin dit veld gebruikt voor "de" geometrie van het object +in de Objecten API. Deze kent hiervoor namelijk één vast attribuut. + +Echter, we kunnen extra geometrieën alsnog meesturen (als het objecttype dit modelleert), +dit doen we door het als ``GeoJSON`` te formatteren met de ``{% as_geo_json ... %}`` +sjablooncode. + +.. note:: Het is niet de bedoeling dat meerdere kaarten via de "Registratie" tab gekoppeld + worden aan het Locatie-attribuut - als je dit wel doet, dan zal er slechts één component + meegestuurd worden. + +Het resulterende object wat naar de Objecten API gestuurd wordt ziet er uit als: + +.. code-block:: json + + { + "type": "https://objecttype-example.nl/api/v2/objecttype/123", + "record": { + "typeVersion": "1", + "data": { + "extraGeometrie": { + "type": "Point", + "coordinates": [52.37403, 4.88969] + } + }, + "startAt": "2023-01-01", + "geometry": { + "type": "Point", + "coordinates": [51.9225, 4.47917] + } + } + } + +.. seealso:: + + De :ref:`sjabloondocumentatie ` heeft een referentie van beschikbare + template tags, met details voor de :ref:`objecten_api_registratie`. + +.. _Objecten API: https://objects-and-objecttypes-api.readthedocs.io/ diff --git a/docs/manual/forms/examples/index.rst b/docs/manual/forms/examples/index.rst index 168d575a1e..7f76fa91f7 100644 --- a/docs/manual/forms/examples/index.rst +++ b/docs/manual/forms/examples/index.rst @@ -22,6 +22,7 @@ Voorbeelden dynamic_options_3 service_fetch suwinet + form_with_geometry ====================== Verouderde voorbeelden diff --git a/docs/manual/templates.rst b/docs/manual/templates.rst index 0ba9f1bc8a..ef24a4efa9 100644 --- a/docs/manual/templates.rst +++ b/docs/manual/templates.rst @@ -445,6 +445,7 @@ Voorbeeld Mede-ondertekend door: N. Doe (BSN: 123456789) +.. _objecten_api_registratie: Objecten API registratie ======================== @@ -471,6 +472,9 @@ alle gegevens uit het formulier en de waarden ingevuld door de gebruiker. ``{{ voornaam }}``. Echter, in de sjablonen voor de Objecten API dient u deze als ``variables.`` te refereren, bijvoorbeeld ``{{ variables.voornaam }}``. Dit zal in de toekomst voor alle sjablonen gelden. +.. seealso :: + + See :ref:`example_form_with_geometry` for a more detailed example. **Speciale instructies** @@ -489,6 +493,7 @@ Variabele Beschrijving ``{{ submission.csv_url }}`` De URL van het inzendingsrapport (in CSV formaat) in de documenten API. Dit document is mogelijk niet aangemaakt ``{% json_summary %}`` JSON met ``"": ""`` van alle formuliervelden. ``{% uploaded_attachment_urls %}`` Een lijst met de URLs van documenten toegevoegd door de inzender. De URLs verwijzen naar het geregistreerde document in de Documenten API. +``{% as_geo_json variables.map %}`` Sluit de gerefereerde variabele (`variables.map`) in als JSON. ===================================== =========================================================================== diff --git a/src/openforms/forms/models/form.py b/src/openforms/forms/models/form.py index 6c2d024d62..1bc7a5aabb 100644 --- a/src/openforms/forms/models/form.py +++ b/src/openforms/forms/models/form.py @@ -66,6 +66,7 @@ class Form(models.Model): product = models.ForeignKey( "products.Product", null=True, blank=True, on_delete=models.CASCADE ) + category = models.ForeignKey( "forms.Category", null=True, blank=True, on_delete=models.PROTECT ) diff --git a/src/openforms/registrations/contrib/objects_api/templatetags/registrations/contrib/objects_api/json_tags.py b/src/openforms/registrations/contrib/objects_api/templatetags/registrations/contrib/objects_api/json_tags.py index 8ec8bfdb9c..ad692d835d 100644 --- a/src/openforms/registrations/contrib/objects_api/templatetags/registrations/contrib/objects_api/json_tags.py +++ b/src/openforms/registrations/contrib/objects_api/templatetags/registrations/contrib/objects_api/json_tags.py @@ -11,24 +11,40 @@ @register.simple_tag(takes_context=True) -def uploaded_attachment_urls(context): +def uploaded_attachment_urls(context: template.Context) -> SafeString: """ Output a sequence of attachment URLs as a JSON-serialized list. """ - # attachments is a list of URLs attachments = context.get("submission", {}).get("uploaded_attachment_urls", []) return SafeString(json.dumps(attachments)) @register.simple_tag(takes_context=True) -def json_summary(context): +def json_summary(context: template.Context) -> SafeString: submission = context.get("_submission") - if not submission: - return {} - json_data = render_json(submission) + json_data = render_json(submission) if submission else {} if settings.ESCAPE_REGISTRATION_OUTPUT: json_data = html_escape_json(json_data) return SafeString(json.dumps(json_data)) + + +@register.simple_tag +def as_geo_json(value: list[float] | str) -> SafeString: + """Output the ``value`` as a safe GeoJSON dumped string. + + As of today, this only supports coordinates. This essentially does the same thing as + :func:`_transform_coordinates`, but for any map component. + """ + data = ( + { + "type": "Point", + "coordinates": [value[0], value[1]], + } + if value + else {} + ) + + return SafeString(json.dumps(data)) diff --git a/src/openforms/registrations/contrib/objects_api/tests/test_templatetags.py b/src/openforms/registrations/contrib/objects_api/tests/test_templatetags.py index 68ea272298..14e4fda66f 100644 --- a/src/openforms/registrations/contrib/objects_api/tests/test_templatetags.py +++ b/src/openforms/registrations/contrib/objects_api/tests/test_templatetags.py @@ -119,3 +119,29 @@ def test_render_json_summary_no_submission(self): ) self.assertEqual(rendered, "{}") + + +class AsGeoJsonTests(TestCase): + def test_render_as_geo_json(self): + rendered = render_from_string( + "{% as_geo_json variables.0.value %}", + context={"variables": [{"value": [1.0, 2.0]}]}, + backend=openforms_backend, + disable_autoescape=True, + ) + + expected = '{"type": "Point", "coordinates": [1.0, 2.0]}' + + self.assertEqual(rendered, expected) + + def test_render_as_geo_json_no_value(self): + rendered = render_from_string( + "{% as_geo_json variables.0.value %}", + context={"variables": [{"value": ""}]}, + backend=openforms_backend, + disable_autoescape=True, + ) + + expected = "{}" + + self.assertEqual(rendered, expected)