Extend the application¶
To add an additional component in the project in simple mode we should:
use an interface in canvas mode
add a custom docker compose service
add a custom JavaScript file
In this tutorial, we will:
Create a new Docker image for the new service
Integrate it to the project
Create the new interface based on canvas
Create a new WebComponent
Build it in the config image
Add it to the interface template
Debugging Custom JavaScript and service
Create a new Docker image for the new service¶
In this chapter we will create a new Pyramid application that uses Cornice in a Docker image.
We will use the Pyramid Cookiecutter starter, we can use it directly
(by running cookiecutter gh:Pylons/pyramid-cookiecutter-starter
) if you want to do your
image by your own, but in this tutorial we will get the files directly from the demo.
For that run the following command:
cd /tmp
git clone git@github.com:camptocamp/demo_geomapfish.git
cd -
cp --recursive /tmp/demo_geomapfish/custom /tmp/demo_geomapfish/haproxy .
Add in .prettierignore
the following line:
custom/Pipfile.lock
Apply the following diff in the setup.cfg
:
- known_first_party=c2cgeoportal_commons,c2cgeoportal_geoportal,c2cgeoportal_admin,geomapfish_geoportal
+ known_first_party=c2cgeoportal_commons,c2cgeoportal_geoportal,c2cgeoportal_admin,geomapfish_geoportal,custom
Note
The important files are:
The Database model custom/custom/models/feedback.py
The view custom/custom/views/feedback.py
Integrate it to the project¶
Add the following service in the docker-compose.yaml
, with that we will be able to build and run the image:
custom:
image: ${DOCKER_BASE}-custom:${DOCKER_TAG}
build:
context: custom
args:
GIT_HASH: ${GIT_HASH}
environment:
- VISIBLE_WEB_HOST
- GEOPORTAL_INTERNAL_URL
- PGSCHEMA
- SQLALCHEMY_POOL_RECYCLE
- SQLALCHEMY_POOL_SIZE
- SQLALCHEMY_MAX_OVERFLOW
- SQLALCHEMY_SLAVE_POOL_RECYCLE
- SQLALCHEMY_SLAVE_POOL_SIZE
- SQLALCHEMY_SLAVE_MAX_OVERFLOW
- SQLALCHEMY_URL=postgresql://${PGUSER}:${PGPASSWORD}@${PGHOST}:${PGPORT}/${PGDATABASE}?sslmode=${PGSSLMODE}
- SQLALCHEMY_SLAVE_URL=postgresql://${PGUSER}:${PGPASSWORD}@${PGHOST_SLAVE}:${PGPORT_SLAVE}/${PGDATABASE}?sslmode=${PGSSLMODE}
Add the following service in the docker-compose.override.sample.yaml
, To be able to run the service
in debugging mode with auto reloading:
custom:
command:
- /venv/bin/pserve
- --reload
- c2c://development.ini
volumes:
- ./custom/custom:/app/custom
Note
If you need the user credentials, you can do:
requests.get(
"http://geoportal:8080/loginuser",
headers={"Cookie": request.headers.get("Cookie"), "Referrer": request.referrer},
).json()
Create the new interface based on canvas¶
Get the files from the CONST_create_template
:
mkdir -p geoportal/interfaces/
cp CONST_create_template/geoportal/interfaces/desktop_alt.html.mako \
geoportal/interfaces/desktop.html.mako
mkdir -p geoportal/<package>_geoportal/static/images/
cp CONST_create_template/geoportal/<package>_geoportal/static/images/background-layer-button.png \
geoportal/<package>_geoportal/static/images/
In the vars.yaml
file your interface should be declared like that:
interfaces:
- name: desktop
type: canvas
layout: desktop
default: true
The name
is the interface name as usual.
The type
should be set to ‘canvas’ to be able to get the canvas based interface present in the config image.
The layout
is used to get the JavaScript and CSS files from ngeo.
The default
is used to set the default interface as usual.
In the file geoportal/interfaces/desktop.html.mako
you will use the following variables:
request
-> the Pyramid request.header
-> the header additional part of the page, thedynamicUrl
andinterface
meta, and the CSS inclusion.spinner
-> the spinner SVG image content.footer
-> the footer additional part of the page, for the JavaScript inclusion.
You can also see that there is some HTML tags that have an attribute slot. The slot says where the component should be added:
header
-> in the header part of the page.data
-> in the data panel on the left of the map.tool-button
-> in the tools on the right of the map.tool-button-separate
-> in the tools on the right of the map, for the shared button.tool-<panel-name>
-> in the tools panel on the right of the map, when the tool is activated.footer-<panel-name>
-> in the footer part of the page, when the panel is activated.
Add the following lines in the project.yaml
as managed_files
:
- geoportal/interfaces/desktop_alt\.html\.mako
Create a new WebComponent¶
In this tutorial we will create a new WebComponent based on Lit, and build by Vite.
We will add a button in the tools bar which opens a new tool panel and that can be used to send a feedback.
The tool button should be an instance of gmfapi.elements.ToolButtonElement.
We will directly use gmf-tool-button.
And panel should be an instance of: gmfapi.elements.ToolPanelElement.
We will directly get the existing component from the demo.
cd /tmp
git clone git@github.com:camptocamp/demo_geomapfish.git
cd -
cp --recursive /tmp/demo_geomapfish/webcomponents \
/tmp/demo_geomapfish/package.json \
/tmp/demo_geomapfish/package-lock.json \
/tmp/demo_geomapfish/tsconfig.json \
/tmp/demo_geomapfish/vite.config.ts .
Add the following lines in the .gitignore
:
/node_modules
Note
The web component file is custom/webcomponents/feedback.tspy.
Build it in the config image¶
In the Dockerfile
we will add two stages, one to build the WebComponent and an other just to add the
build artifacts to the config image.
Add the following lines at the end of Dockerfile
:
###############################################################################
FROM node:16-slim AS custom-build
WORKDIR /app
COPY package.json ./
RUN npm install
COPY tsconfig.json vite.config.ts ./
COPY webcomponents/ ./webcomponents/
RUN npm run build
###############################################################################
FROM gmf_config AS config
COPY --from=custom-build /app/dist/ /etc/geomapfish/static/custom/
Add the following lines in the .dockerignore
:
!webcomponents/
!package.json
!package-lock.json
!tsconfig.json
!vite.config.ts
Add the following lines in the project.yaml
as managed_files
:
- Dockerfile
- \.dockerignore
Add it to the interface template¶
Then we will include the following HTML in the canvas element, in geoportal/interfaces/desktop.html.mako
:
`html
<gmf-tool-button slot="tool-button" iconClasses="fas fa-file-signature" panelName="feedback"></gmf-tool-button>
`
The panel will be included with the following HTML:
`html
<proj-feedback slot="tool-panel-feedback"></proj-feedback>
`
The modifications in the vars
file are:
- Add the JavaScript file as gmfCustomJavascriptUrl
.
- Be sure that we have the CSS file as gmfCustomStylesheetUrl
.
- Add in comment all the needed configuration to be able to debug.
Apply the following diff in the geoportal/vars.yaml
:
vars:
interfaces_config:
desktop:
constants:
+
+ # For dev, the corresponding values in static should also be commented.
+ # gmfCustomJavascriptUrl:
+ # - https://localhost:3001/@vite/client
+ # - https://localhost:3001/webcomponents/index.ts
+
+ # Used in the web component to get the service URL based on `gmfBase`.
+ sitnFeedbackPath: custom/feedback
+
+ static:
+ # Those two lines should be commented in dev mode.
+ gmfCustomJavascriptUrl:
+ name: '/etc/geomapfish/static/custom/custom.es.js'
+ gmfCustomStylesheetUrl:
+ name: /etc/geomapfish/static/css/desktop_alt.css
+
+ routes:
+ gmfBase:
+ name: base
+ # For dev this line is needed to allow the page to load the files from Vite dev server.
+ # content_security_policy_main_script_src_extra: "http://localhost:3001"
Debugging Custom JavaScript and service¶
The usual build and run will also work for the custom JavaScript and service. Build and run as usual:
To have a development environment with auto-reload mode, we will start the Vite dev server
locally on port 3001
.
We also need to get the file from the Vite dev server, for that we need to do the following modifications
in the geoportal/vars.yaml
(don’t commit them):
# For dev, the corresponding values in static should also be removed.
- # gmfCustomJavascriptUrl:
- # - https://localhost:3001/@vite/client
- # - https://localhost:3001/webcomponents/index.ts
+ gmfCustomJavascriptUrl:
+ - https://localhost:3001/@vite/client
+ - https://localhost:3001/webcomponents/index.ts
# Those two lines should be commented in dev mode.
- gmfCustomJavascriptUrl:
- name: '/etc/geomapfish/static/custom/custom.es.js'
+ # gmfCustomJavascriptUrl:
+ # name: '/etc/geomapfish/static/custom/custom.es.js'
# For dev this line is needed to allow the page to load the files from Vite dev server.
- # content_security_policy_main_script_src_extra: "http://localhost:3001"
+ content_security_policy_main_script_src_extra: "http://localhost:3001"
Rename the docker-compose.override.sample.yaml
file to docker-compose.override.yaml
.
Build and run as usual.
Download and start the Vite dev server:
npm install
npm run dev
Extend the geoportal image¶
If you need to configure your own authentication you will need to extend the geoportal
Docker image.
For that you will need to create a new folder named geoportal_custom
.
An this folder, add a file named authentication.py
with the content you need, the original content is:
from pyramid.config import Configurator
from pyramid.authorization import ACLAuthorizationPolicy
from c2cgeoportal_geoportal.lib.authentication import create_authentication
def includeme(config: Configurator) -> None:
"""
Initialize the authentication( for a Pyramid app.
"""
config.set_authorization_policy(ACLAuthorizationPolicy())
config.set_authentication_policy(create_authentication(config.get_settings()))
Create a file named Dockerfile
with the following content:
ARG GEOMAPFISH_MAIN_VERSION
FROM camptocamp/geomapfish:${GEOMAPFISH_MAIN_VERSION} as runner
COPY authentication.py /app/geomapfishapp_geoportal/
In the docker-compose.yaml
file do the following changes:
geoportal:
extends:
file: docker-compose-lib.yaml
service: geoportal
+ image: ${DOCKER_BASE}-geoportal:${DOCKER_TAG}
+ build:
+ context: geoportal_custom
+ args:
+ GIT_HASH: ${GIT_HASH}
+ GEOMAPFISH_VERSION: ${GEOMAPFISH_VERSION}
+ GEOMAPFISH_MAIN_VERSION: ${GEOMAPFISH_MAIN_VERSION}
volumes_from:
Warning
With these changes, you can add your own authentication logic, but be aware that this logic may need to be adapted when migrating to future versions of GeoMapFish.