# Customize a GeoNode project model In this section, we will patch the `ResourceBase` of `GeoNode` and update the `templates` to add one more field to the `Metadata Schema`. We will add a `custom_md` field to the `ResourceBase` model and modify the templates to show the new field in the `Metadata Wizard` and the `Layer Details` page. ## Activate the virtualenv We should already be working in the right directory, and have the proper virtualenv (virtual environment) activated. If not, run: ```shell workon my_geonode cd /opt/geonode-project/my_geonode/src/ ``` - Update the GeoNode `ResourceBase` model ```shell vim /opt/geonode/geonode/base/models.py ``` ```diff --- /opt/geonode/geonode/base/models.py.org 2022-03-18 10:03:35.403505308 +0000 +++ /opt/geonode/geonode/base/models.py 2022-03-18 10:05:23.985766322 +0000 @@ -1081,6 +1081,13 @@ blank=True, help_text=extra_metadata_help_text) + custom_md_help_text = _('a custom metadata field') + custom_md = models.TextField( + _("Custom Md"), + blank=True, + null=True, + help_text=custom_md_help_text) + objects = ResourceBaseManager() class Meta: ``` - Add the new field to the DB ```shell ./manage_dev.sh makemigrations ./manage_dev.sh migrate ``` - Add the new field to `templates` ```shell mkdir my_geonode/templates/layouts/ cp /opt/geonode/geonode/layers/templates/layouts/panels.html my_geonode/templates/layouts/panels.html ``` ```shell vim my_geonode/templates/layouts/panels.html ``` ```diff --- /opt/geonode/geonode/layers/templates/layouts/panels.html 2022-03-03 15:30:15.670185376 +0000 +++ my_geonode/templates/layouts/panels.html 2022-03-18 10:08:33.660551116 +0000 @@ -322,6 +322,10 @@ {% endblock thumbnail %}
+
+ + {{ dataset_form.custom_md }} +
{% block dataset_title %}
``` - Let's check the changes ```shell ./paver_dev.sh start_django ``` ![image](img/133050035-f86bf268-37fa-44e3-a370-7f4a756ebe6a.png) - Update the `custom_md` text field to a `rich HTML` one ```shell vim /opt/geonode/geonode/base/forms.py ``` ```diff diff --git a/geonode/base/forms.py b/geonode/base/forms.py index 48a0ef7f1..e0284988c 100644 --- a/geonode/base/forms.py +++ b/geonode/base/forms.py @@ -416,6 +416,10 @@ class ResourceBaseForm(TranslationModelForm): label=_("Data quality statement"), required=False, widget=TinyMCE()) + custom_md = forms.CharField( + label=_("Custom Md"), + required=True, + widget=TinyMCE()) owner = forms.ModelChoiceField( empty_label=_("Owner"), ``` ![image](img/133050807-bb921fcc-0b1e-413b-8664-3b896b46ceb2.png) ## Detail Panel Update The detail panel configuration could be updated by editing the json configuration (localConfig) of two plugins inside the GeoNode MapStore client: DetailViewer and ResourcesGrid. It's possible to update the configuration with the html template `_geonode_config.html`. The project should provide the config template called `_geonode_config.html` in the following location: ``` /opt/geonode-project/my_geonode/src/my_geonode/ |-- ... |-- templates/ | |-- ... | +-- geonode-mapstore-client/ | +-- _geonode_config.html |-- ... ``` ### Update the Detail Panel Info box The following snippet shows how to loop through all the pages in the GeoNode MapStore client and how to change the details tabs configuration for DetailViewer and ResourcesGrid plugins. ```django {% extends 'geonode-mapstore-client/_geonode_config.html' %} {% block override_local_config %} {% endblock %} ``` - Go to the datastet details (upload a new one if none is present); you most probably won't see any value for the `custom_md` field even if you provided a value. This is because the json configuration leverage on the `REST APIs` in order to get the values ## API REST (v2) - Let's add the new `custom_md` field to the `REST API` of GeoNode The APIs are reachable through the endpoint: `http://localhost:8000/api/v2/` Looking at the `http://localhost:8000/api/v2/resources`, you will notice that the new field we just added is not visible. ![image](img/133063348-69beee93-9a10-4c39-b869-69c593eee441.png) - Modify the GeoNode `base` rest API endpoints to add the new field ```shell vim /opt/geonode/geonode/base/api/serializers.py ``` ```diff --- /opt/geonode/geonode/base/api/serializers.py.org 2022-03-18 10:41:19.663006942 +0000 +++ /opt/geonode/geonode/base/api/serializers.py 2022-03-18 10:42:07.590957618 +0000 @@ -471,6 +471,7 @@ self.fields['processed'] = serializers.BooleanField(read_only=True) self.fields['state'] = serializers.CharField(read_only=True) self.fields['sourcetype'] = serializers.CharField(read_only=True) + self.fields['custom_md'] = serializers.CharField() self.fields['embed_url'] = EmbedUrlField(required=False) self.fields['thumbnail_url'] = ThumbnailUrlField(read_only=True) @@ -513,7 +514,7 @@ 'raw_abstract', 'raw_purpose', 'raw_constraints_other', 'raw_supplemental_information', 'raw_data_quality_statement', 'metadata_only', 'processed', 'state', 'data', 'subtype', 'sourcetype', 'is_copyable', - 'blob', "metadata", 'executions' + 'blob', "metadata", 'executions', 'custom_md' # TODO # csw_typename, csw_schema, csw_mdsource, csw_insert_date, csw_type, csw_anytext, csw_wkt_geometry, # metadata_uploaded, metadata_uploaded_preserve, metadata_xml, ``` - `http://localhost:8000/api/v2/resources?filter{custom_md.isnull}=False` ![image](img/133064948-84e0a153-7cb7-4911-b0a9-42ac286f7c93.png) - More info about `dynamic-rest` filtering options can be found at: [`https://github.com/AltSchool/dynamic-rest#filtering`](https://github.com/AltSchool/dynamic-rest#filtering) #### [Next Section: Save changes to GitHub](060_GEONODE_PROJ_SAVE_GITHUB.md)