diff --git a/geonode/documents/api/serializers.py b/geonode/documents/api/serializers.py
index 9887eced4df..679b395bc68 100644
--- a/geonode/documents/api/serializers.py
+++ b/geonode/documents/api/serializers.py
@@ -58,4 +58,5 @@ class Meta:
"executions",
"file_path",
"doc_file",
+ "metadata",
)
diff --git a/geonode/documents/api/tests.py b/geonode/documents/api/tests.py
index 2ba5e294050..c0dce1933b9 100644
--- a/geonode/documents/api/tests.py
+++ b/geonode/documents/api/tests.py
@@ -17,9 +17,9 @@
#
#########################################################################
import os
-from django.contrib.auth import get_user_model
import logging
+from django.contrib.auth import get_user_model
from urllib.parse import urljoin
from django.urls import reverse
@@ -27,8 +27,9 @@
from guardian.shortcuts import assign_perm, get_anonymous_user
from geonode import settings
-from geonode.documents.models import Document
+
from geonode.base.populate_test_data import create_models
+from geonode.documents.models import Document
logger = logging.getLogger(__name__)
@@ -76,6 +77,17 @@ def test_documents(self):
# import json
# logger.error(f"{json.dumps(layers_data)}")
+ def test_extra_metadata_included_with_param(self):
+ resource = Document.objects.first()
+ url = urljoin(f"{reverse('documents-list')}/", f"{resource.pk}")
+ data = {"include[]": "metadata"}
+
+ response = self.client.get(url, format="json", data=data)
+ self.assertIsNotNone(response.data["document"].get("metadata"))
+
+ response = self.client.get(url, format="json")
+ self.assertNotIn("metadata", response.data["document"])
+
def test_creation_return_error_if_file_is_not_passed(self):
"""
If file_path is not available, should raise error
diff --git a/geonode/documents/templates/documents/document_metadata.html b/geonode/documents/templates/documents/document_metadata.html
index 9f27df4310b..2f4361c9be8 100644
--- a/geonode/documents/templates/documents/document_metadata.html
+++ b/geonode/documents/templates/documents/document_metadata.html
@@ -56,7 +56,7 @@
{% trans "Metadata" %} {% blocktrans with document.t
{% csrf_token %}
- {% form document_form using "layouts/doc_panels.html" %}
+ {% form document_form using panel_template %}
{# document_form|as_bootstrap #}
diff --git a/geonode/documents/templates/layouts/doc_panels.html b/geonode/documents/templates/layouts/doc_panels.html
index 3f48b433da7..0d21a1d14cd 100644
--- a/geonode/documents/templates/layouts/doc_panels.html
+++ b/geonode/documents/templates/layouts/doc_panels.html
@@ -266,6 +266,8 @@
{% trans "Optional Metadata" %}
{% endif %}
+ {% block extra_metadata_steps %}
+ {% endblock %}
{% block mandatory %}
@@ -580,6 +582,8 @@
+ {% block extra_metadata_content %}
+ {% endblock %}
{% endblock ownership %}
diff --git a/geonode/documents/views.py b/geonode/documents/views.py
index ce54fa812d0..3ba50d2f6bc 100644
--- a/geonode/documents/views.py
+++ b/geonode/documents/views.py
@@ -293,7 +293,14 @@ def form_valid(self, form):
@login_required
@check_keyword_write_perms
-def document_metadata(request, docid, template="documents/document_metadata.html", ajax=True):
+def document_metadata(
+ request,
+ docid,
+ template="documents/document_metadata.html",
+ panel_template="layouts/doc_panels.html",
+ custom_metadata=None,
+ ajax=True,
+):
document = None
try:
document = _resolve_document(request, docid, "base.change_resourcebase_metadata", _PERMISSION_MSG_METADATA)
@@ -503,6 +510,8 @@ def document_metadata(request, docid, template="documents/document_metadata.html
context={
"resource": document,
"document": document,
+ "panel_template": panel_template,
+ "custom_metadata": custom_metadata,
"document_form": document_form,
"poc_form": poc_form,
"author_form": author_form,
@@ -524,7 +533,7 @@ def document_metadata_advanced(request, docid):
return document_metadata(request, docid, template="documents/document_metadata_advanced.html")
-def document_metadata_detail(request, docid, template="documents/document_metadata_detail.html"):
+def document_metadata_detail(request, docid, template="documents/document_metadata_detail.html", custom_metadata=None):
try:
document = _resolve_document(request, docid, "view_resourcebase", _PERMISSION_MSG_METADATA)
except PermissionDenied:
@@ -542,7 +551,12 @@ def document_metadata_detail(request, docid, template="documents/document_metada
group = None
site_url = settings.SITEURL.rstrip("/") if settings.SITEURL.startswith("http") else settings.SITEURL
register_event(request, EventType.EVENT_VIEW_METADATA, document)
- return render(request, template, context={"resource": document, "group": group, "SITEURL": site_url})
+
+ return render(
+ request,
+ template,
+ context={"resource": document, "group": group, "SITEURL": site_url, "custom_metadata": custom_metadata},
+ )
@login_required
diff --git a/geonode/geoapps/api/serializers.py b/geonode/geoapps/api/serializers.py
index 86654832399..9d129dbe4db 100644
--- a/geonode/geoapps/api/serializers.py
+++ b/geonode/geoapps/api/serializers.py
@@ -37,7 +37,7 @@ class Meta:
model = GeoApp
name = "geoapp"
view_name = "geoapps-list"
- fields = ("pk", "uuid", "data", "name", "executions")
+ fields = ("pk", "uuid", "data", "name", "executions", "metadata")
def extra_update_checks(self, validated_data):
_user_profiles = {}
diff --git a/geonode/geoapps/api/tests.py b/geonode/geoapps/api/tests.py
index d37f1f18161..bfc19edbc0d 100644
--- a/geonode/geoapps/api/tests.py
+++ b/geonode/geoapps/api/tests.py
@@ -19,15 +19,16 @@
import json
import logging
from unittest.mock import MagicMock
+from urllib.parse import urljoin
-from django.urls import reverse
from django.contrib.auth import get_user_model
+from django.urls import reverse
from rest_framework.test import APITestCase
+
+from geonode.base.populate_test_data import create_models
from geonode.geoapps.api.exceptions import DuplicateGeoAppException, InvalidGeoAppException
from geonode.geoapps.api.serializers import GeoAppSerializer
-
from geonode.geoapps.models import GeoApp
-from geonode.base.populate_test_data import create_models
logger = logging.getLogger(__name__)
@@ -76,6 +77,17 @@ def test_geoapps_list(self):
json.loads(response.data["geoapps"][0]["data"]), {"test_data": {"test": ["test_1", "test_2", "test_3"]}}
)
+ def test_extra_metadata_included_with_param(self):
+ _app = GeoApp.objects.first()
+ url = urljoin(f"{reverse('geoapps-list')}/", f"{_app.pk}")
+ data = {"include[]": "metadata"}
+
+ response = self.client.get(url, format="json", data=data)
+ self.assertIsNotNone(response.data["geoapp"].get("metadata"))
+
+ response = self.client.get(url, format="json")
+ self.assertNotIn("metadata", response.data["geoapp"])
+
def test_geoapps_crud(self):
"""
Ensure we can create/update GeoApps.
diff --git a/geonode/geoapps/templates/apps/app_metadata.html b/geonode/geoapps/templates/apps/app_metadata.html
index 9e92fad7720..17b2de35a97 100644
--- a/geonode/geoapps/templates/apps/app_metadata.html
+++ b/geonode/geoapps/templates/apps/app_metadata.html
@@ -55,7 +55,7 @@ {% trans "Metadata" %} {% blocktrans with geoapp.tit
{% csrf_token %}
- {% form geoapp_form using "layouts/app_panels.html" %}
+ {% form geoapp_form using panel_template %}
{# geoapp_form|as_bootstrap #}
diff --git a/geonode/geoapps/templates/layouts/app_panels.html b/geonode/geoapps/templates/layouts/app_panels.html
index f4b617bf99d..d46741d8c2e 100644
--- a/geonode/geoapps/templates/layouts/app_panels.html
+++ b/geonode/geoapps/templates/layouts/app_panels.html
@@ -256,6 +256,8 @@
{% trans "Optional Metadata" %}
+ {% block extra_metadata_steps %}
+ {% endblock %}
@@ -510,6 +512,8 @@
+ {% block extra_metadata_content %}
+ {% endblock %}
diff --git a/geonode/geoapps/views.py b/geonode/geoapps/views.py
index cae13037529..4c4879b6b75 100644
--- a/geonode/geoapps/views.py
+++ b/geonode/geoapps/views.py
@@ -154,7 +154,7 @@ def geoapp_edit(request, geoappid, template="apps/app_edit.html"):
return render(request, template, context=_ctx)
-def geoapp_metadata_detail(request, geoappid, template="apps/app_metadata_detail.html"):
+def geoapp_metadata_detail(request, geoappid, template="apps/app_metadata_detail.html", custom_metadata=None):
try:
geoapp_obj = _resolve_geoapp(request, geoappid, "view_resourcebase", _PERMISSION_MSG_METADATA)
except PermissionDenied:
@@ -172,12 +172,29 @@ def geoapp_metadata_detail(request, geoappid, template="apps/app_metadata_detail
group = None
site_url = settings.SITEURL.rstrip("/") if settings.SITEURL.startswith("http") else settings.SITEURL
register_event(request, EventType.EVENT_VIEW_METADATA, geoapp_obj)
- return render(request, template, context={"resource": geoapp_obj, "group": group, "SITEURL": site_url})
+
+ return render(
+ request,
+ template,
+ context={
+ "resource": geoapp_obj,
+ "group": group,
+ "SITEURL": site_url,
+ "custom_metadata": custom_metadata,
+ },
+ )
@login_required
@check_keyword_write_perms
-def geoapp_metadata(request, geoappid, template="apps/app_metadata.html", ajax=True):
+def geoapp_metadata(
+ request,
+ geoappid,
+ template="apps/app_metadata.html",
+ ajax=True,
+ panel_template="layouts/app_panels.html",
+ custom_metadata=None,
+):
geoapp_obj = None
try:
geoapp_obj = _resolve_geoapp(request, geoappid, "base.change_resourcebase_metadata", _PERMISSION_MSG_METADATA)
@@ -394,6 +411,8 @@ def geoapp_metadata(request, geoappid, template="apps/app_metadata.html", ajax=T
context={
"resource": geoapp_obj,
"geoapp": geoapp_obj,
+ "panel_template": panel_template,
+ "custom_metadata": custom_metadata,
"geoapp_form": geoapp_form,
"poc_form": poc_form,
"author_form": author_form,
diff --git a/geonode/layers/api/serializers.py b/geonode/layers/api/serializers.py
index 2f3d9a63b8e..4f974cf29a7 100644
--- a/geonode/layers/api/serializers.py
+++ b/geonode/layers/api/serializers.py
@@ -178,6 +178,7 @@ class Meta:
"styles",
"attribute_set",
"executions",
+ "metadata",
)
name = serializers.CharField(read_only=True)
diff --git a/geonode/layers/api/tests.py b/geonode/layers/api/tests.py
index eaa16e06906..c3c063072e9 100644
--- a/geonode/layers/api/tests.py
+++ b/geonode/layers/api/tests.py
@@ -21,17 +21,17 @@
from unittest.mock import patch
from django.contrib.auth import get_user_model
-
from urllib.parse import urljoin
+from django.conf import settings
from django.urls import reverse
from rest_framework.test import APITestCase
-from geonode.geoserver.createlayer.utils import create_dataset
+
from guardian.shortcuts import assign_perm, get_anonymous_user
+from geonode.geoserver.createlayer.utils import create_dataset
-from django.conf import settings
-from geonode.layers.models import Dataset, Attribute
from geonode.base.populate_test_data import create_models, create_single_dataset
+from geonode.layers.models import Attribute, Dataset
from geonode.maps.models import Map, MapLayer
logger = logging.getLogger(__name__)
@@ -121,6 +121,17 @@ def test_datasets(self):
_dataset.use_featureinfo_custom_template = False
_dataset.save()
+ def test_extra_metadata_included_with_param(self):
+ _dataset = Dataset.objects.first()
+ url = urljoin(f"{reverse('datasets-list')}/", f"{_dataset.pk}")
+ data = {"include[]": "metadata"}
+
+ response = self.client.get(url, format="json", data=data)
+ self.assertIsNotNone(response.data["dataset"].get("metadata"))
+
+ response = self.client.get(url, format="json")
+ self.assertNotIn("metadata", response.data["dataset"])
+
def test_get_dataset_related_maps_and_maplayers(self):
dataset = Dataset.objects.first()
assign_perm("base.view_resourcebase", get_anonymous_user(), dataset.get_self_resource())
diff --git a/geonode/layers/templates/datasets/dataset_metadata.html b/geonode/layers/templates/datasets/dataset_metadata.html
index 9a1fb5aaaee..cfb423709ac 100644
--- a/geonode/layers/templates/datasets/dataset_metadata.html
+++ b/geonode/layers/templates/datasets/dataset_metadata.html
@@ -78,7 +78,7 @@
{% trans "Metadata" %} {% blocktrans with dataset.ti
{% csrf_token %}
- {% form dataset_form using "layouts/panels.html" %}
+ {% form dataset_form using panel_template %}
{# dataset_form|as_bootstrap #}
diff --git a/geonode/layers/templates/layouts/panels.html b/geonode/layers/templates/layouts/panels.html
index 435804aac75..c10634646f3 100644
--- a/geonode/layers/templates/layouts/panels.html
+++ b/geonode/layers/templates/layouts/panels.html
@@ -280,6 +280,8 @@
{% trans "Dataset Attributes" %}
+ {% block extra_metadata_steps%}
+ {% endblock %}
{% endblock breadcrumbs %}
{% block mandatory %}
@@ -644,6 +646,8 @@
{% endblock %}
+ {% block extra_metadata_content %}
+ {% endblock %}
diff --git a/geonode/layers/views.py b/geonode/layers/views.py
index 6a3d6f774bb..b8c68021df2 100644
--- a/geonode/layers/views.py
+++ b/geonode/layers/views.py
@@ -331,7 +331,14 @@ def dataset_feature_catalogue(request, layername, template="../../catalogue/temp
@login_required
@check_keyword_write_perms
-def dataset_metadata(request, layername, template="datasets/dataset_metadata.html", ajax=True):
+def dataset_metadata(
+ request,
+ layername,
+ template="datasets/dataset_metadata.html",
+ panel_template="layouts/panels.html",
+ custom_metadata=None,
+ ajax=True,
+):
try:
layer = _resolve_dataset(request, layername, "base.change_resourcebase_metadata", _PERMISSION_MSG_METADATA)
except PermissionDenied as e:
@@ -686,6 +693,8 @@ def dataset_metadata(request, layername, template="datasets/dataset_metadata.htm
context={
"resource": layer,
"dataset": layer,
+ "panel_template": panel_template,
+ "custom_metadata": custom_metadata,
"dataset_form": dataset_form,
"poc_form": poc_form,
"author_form": author_form,
@@ -942,7 +951,7 @@ def decimal_default(obj):
)
-def dataset_metadata_detail(request, layername, template="datasets/dataset_metadata_detail.html"):
+def dataset_metadata_detail(request, layername, template="datasets/dataset_metadata_detail.html", custom_metadata=None):
try:
layer = _resolve_dataset(request, layername, "view_resourcebase", _PERMISSION_MSG_METADATA)
except PermissionDenied:
@@ -964,7 +973,15 @@ def dataset_metadata_detail(request, layername, template="datasets/dataset_metad
perms_list = list(layer.get_self_resource().get_user_perms(request.user).union(layer.get_user_perms(request.user)))
return render(
- request, template, context={"resource": layer, "perms_list": perms_list, "group": group, "SITEURL": site_url}
+ request,
+ template,
+ context={
+ "resource": layer,
+ "perms_list": perms_list,
+ "group": group,
+ "SITEURL": site_url,
+ "custom_metadata": custom_metadata,
+ },
)
diff --git a/geonode/maps/api/serializers.py b/geonode/maps/api/serializers.py
index 5a1cba0fdfe..2d9c88330e3 100644
--- a/geonode/maps/api/serializers.py
+++ b/geonode/maps/api/serializers.py
@@ -160,7 +160,7 @@ class Meta:
model = Map
name = "map"
view_name = "maps-list"
- fields = ("pk", "uuid", "urlsuffix", "featuredurl", "data", "maplayers", "executions")
+ fields = ("pk", "uuid", "urlsuffix", "featuredurl", "data", "maplayers", "executions", "metadata")
class SimpleMapSerializer(BaseDynamicModelSerializer):
diff --git a/geonode/maps/api/tests.py b/geonode/maps/api/tests.py
index a46f593e5c6..69e55e8c3b2 100644
--- a/geonode/maps/api/tests.py
+++ b/geonode/maps/api/tests.py
@@ -21,9 +21,10 @@
from django.conf import settings
from django.urls import reverse
+
+from guardian.shortcuts import assign_perm, get_anonymous_user
from mock import patch
from rest_framework.test import APITestCase
-from guardian.shortcuts import assign_perm, get_anonymous_user
from geonode.base.populate_test_data import create_models
from geonode.layers.models import Dataset
@@ -112,6 +113,17 @@ def test_maps(self):
self.assertEqual(response.data["map"]["maplayers"][0]["extra_params"], {"foo": "bar"})
self.assertIsNotNone(response.data["map"]["maplayers"][0]["dataset"])
+ def test_extra_metadata_included_with_param(self):
+ resource = Map.objects.first()
+ url = urljoin(f"{reverse('maps-list')}/", f"{resource.pk}")
+ data = {"include[]": "metadata"}
+
+ response = self.client.get(url, format="json", data=data)
+ self.assertIsNotNone(response.data["map"].get("metadata"))
+
+ response = self.client.get(url, format="json")
+ self.assertNotIn("map", response.data["map"])
+
def test_patch_map(self):
"""
Patch to maps/
/
diff --git a/geonode/maps/templates/layouts/map_panels.html b/geonode/maps/templates/layouts/map_panels.html
index 4ce88a199d8..307549913da 100644
--- a/geonode/maps/templates/layouts/map_panels.html
+++ b/geonode/maps/templates/layouts/map_panels.html
@@ -269,6 +269,8 @@
{% trans "Optional Metadata" %}
{% endif %}
+ {% block extra_metadata_steps %}
+ {% endblock %}
@@ -568,6 +570,8 @@
+ {% block extra_metadata_content %}
+ {% endblock %}
diff --git a/geonode/maps/templates/maps/map_metadata.html b/geonode/maps/templates/maps/map_metadata.html
index 2a3969e5c2a..dcc99f734e7 100644
--- a/geonode/maps/templates/maps/map_metadata.html
+++ b/geonode/maps/templates/maps/map_metadata.html
@@ -57,7 +57,7 @@
{% trans "Metadata" %} {% blocktrans with map.title
{% csrf_token %}
- {% form map_form using "layouts/map_panels.html" %}
+ {% form map_form using panel_template %}
{# map_form|as_bootstrap #}
diff --git a/geonode/maps/views.py b/geonode/maps/views.py
index f281c3369e3..ea9450f419c 100644
--- a/geonode/maps/views.py
+++ b/geonode/maps/views.py
@@ -77,7 +77,14 @@ def _resolve_map(request, id, permission="base.change_resourcebase", msg=_PERMIS
@login_required
@check_keyword_write_perms
-def map_metadata(request, mapid, template="maps/map_metadata.html", ajax=True):
+def map_metadata(
+ request,
+ mapid,
+ template="maps/map_metadata.html",
+ ajax=True,
+ panel_template="layouts/map_panels.html",
+ custom_metadata=None,
+):
try:
map_obj = _resolve_map(request, mapid, "base.change_resourcebase_metadata", _PERMISSION_MSG_VIEW)
except PermissionDenied:
@@ -285,6 +292,8 @@ def map_metadata(request, mapid, template="maps/map_metadata.html", ajax=True):
"resource": map_obj,
"map": map_obj,
"config": json.dumps(map_obj.blob),
+ "panel_template": panel_template,
+ "custom_metadata": custom_metadata,
"map_form": map_form,
"poc_form": poc_form,
"author_form": author_form,
@@ -554,7 +563,7 @@ def ajax_url_lookup(request):
return HttpResponse(content=json.dumps(json_dict), content_type="text/plain")
-def map_metadata_detail(request, mapid, template="maps/map_metadata_detail.html"):
+def map_metadata_detail(request, mapid, template="maps/map_metadata_detail.html", custom_metadata=None):
try:
map_obj = _resolve_map(request, mapid, "view_resourcebase")
except PermissionDenied:
@@ -572,7 +581,12 @@ def map_metadata_detail(request, mapid, template="maps/map_metadata_detail.html"
group = None
site_url = settings.SITEURL.rstrip("/") if settings.SITEURL.startswith("http") else settings.SITEURL
register_event(request, EventType.EVENT_VIEW_METADATA, map_obj)
- return render(request, template, context={"resource": map_obj, "group": group, "SITEURL": site_url})
+
+ return render(
+ request,
+ template,
+ context={"resource": map_obj, "group": group, "SITEURL": site_url, "custom_metadata": custom_metadata},
+ )
@login_required
diff --git a/geonode/templates/metadata_detail.html b/geonode/templates/metadata_detail.html
index 42cbfe2d6d5..c04a19e39db 100644
--- a/geonode/templates/metadata_detail.html
+++ b/geonode/templates/metadata_detail.html
@@ -348,6 +348,9 @@ {% trans "Metadata" %} : {{ resource.title }}
{% endif %}
{% endblock supplemental_information %}
+ {% block extra_metadata %}
+ {% endblock extra_metadata %}
+
{% block spatial_representation_type %}
{% if resource.spatial_representation_type %}
{% trans "Spatial Representation Type" %}
diff --git a/requirements.txt b/requirements.txt
index 427ec35629d..54613b185c3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -67,7 +67,7 @@ numpy==1.24.*
# Django Apps
dj-database-url==1.2.0
dj-pagination==2.5.0
-django-select2==8.0.0
+django-select2==8.1.0
django-floppyforms<1.10.0
django-forms-bootstrap<=3.1.0
django-autocomplete-light==3.5.1