---
title: Posts tagged GhentCDH
canonical: https://0110.be/tags/GhentCDH
markdown_url: https://0110.be/tags/GhentCDH.md
page: 0
posts_per_page: 30
total_posts: 7
filters:
  tag: GhentCDH
previous:
next:
---

# Posts tagged GhentCDH

## [Sampo-UI Meets Ontop: Publishing Relational Digital Humanities Data - Semantics 2026](https://0110.be/posts/Sampo-UI_Meets_Ontop%3A_Publishing_Relational_Digital_Humanities_Data_-_Semantics_2026.md)

- Published: 2026-09-16T00:00:00Z
- Updated: 2026-09-16T07:46:02Z
- Author: Joren
- ID: 582
- Canonical: https://0110.be/posts/Sampo-UI_Meets_Ontop%3A_Publishing_Relational_Digital_Humanities_Data_-_Semantics_2026

- Tags: [Code](https://0110.be/tags/Code.md), [GhentCDH](https://0110.be/tags/GhentCDH.md), [Presentation](https://0110.be/tags/Presentation.md), [UGent](https://0110.be/tags/UGent.md)

The [SEMANTiCS conference](https://2026-eu.semantics.cc/) took place in Ghent from 15 to 17 September 2026. Our contribution was a collaboration between GhentCDH and the Semantic Computing Research Group at Aalto University on publishing humanities data with Sampo-UI and Ontop.

> *[Sampo-UI Meets Ontop: Publishing Relational Digital Humanities Data on the Semantic Web](https://0110.be/files/attachments/582/semantics-poster-sampo-ui.pdf)*, Joren Six¹, Jahid Chetti¹, Annastiina Ahola², Frederic Lamsens¹, Heikki Rantala², Eero Hyvönen²<br>
> ¹ Ghent University, Ghent Centre for Digital Humanities ([GhentCDH](https://www.ghentcdh.ugent.be)) <br>
> ² Aalto University, Department of Computer Science, Semantic Computing Research Group ([SeCo](https://seco.cs.aalto.fi))

At GhentCDH, we often publish research datasets in the digital humanities. Several projects need similar search filters, map visualizations and data exports. Sampo-UI makes it possible to reuse these components when the data is available as Linked Data. In collaboration with the original Sampo-UI team, we worked on modernizing the framework. Our first contribution separates the shared core from project-specific configuration, making updates and reuse more manageable. The second uses Ontop to expose existing *relational databases* through a SPARQL endpoint. This lets us use Sampo-UI while keeping the database infrastructure and tooling we already have. Having one fewer database system to maintain is welcome.

> **Abstract**: *The Sampo model and its Sampo-UI framework have become an established approach for publishing Cultural Heritage and Digital Humanities data on the Semantic Web. Sampo-UI enables exploration of data originating from SPARQL endpoints through faceted search across multiple views with seamlessly integrated visualization and data analytic tools. Here, we present two contributions to the Sampo-UI ecosystem: (i) a separation of Sampo-UI core from application-specific configuration; decoupling core and application simplifies updates and facilitates reuse of efforts, and (ii) the use of Ontop --- a virtual knowledge graph system --- to expose relational databases through a SPARQL endpoint and Sampo-UI. The use of relational databases and reuse of tooling and expertise around relational databases lower the operational burden of publishing small-to-medium-sized datasets typical of digital humanities projects. These contributions originated outside the original Sampo-UI team but were developed in collaboration with it, and are being prepared for upstream integration. We illustrate the approach with two projects at Ghent University: one on Roman coin finds in Belgium (NuMAD) and one on historic Belgian company data (BelHisFirm). Both portals run the same Sampo-UI core with a different configuration, and operate on existing institutional relational database infrastructure without a dedicated graph database.*

The demo below shows the NuMAD portal for exploring Roman coin finds in Belgium through the modernized Sampo-UI. Another [demo presents historical records of Belgian companies](https://0110.be/files/attachments/582/belhisfirm_demo.mp4) through the BelHisFirm portal. Both portals run the same Sampo-UI core with different configurations, demonstrating the flexibility of the system.

Alongside the [Sampo-UI Meets Ontop paper](https://0110.be/files/attachments/582/sampo-ui_ontop-semantics_2026.pdf), a [conference poster on Sampo-UI](https://0110.be/files/attachments/582/semantics-poster-sampo-ui.pdf) that I prepared is also available.

<video style="width: 100%; height: auto;" src="https://0110.be/files/attachments/582/numad_demo.mp4" controls playsinline preload="metadata"></video>
<small>Video: NuMAD — exploring Roman coin finds in Belgium.</small>
<br>


---

## [ Introduction to Sampo-UI at FedOSC Linked Open Data Visualisation Workshop](https://0110.be/posts/_Introduction_to_Sampo-UI_at_FedOSC_Linked_Open_Data_Visualisation_Workshop.md)

- Published: 2026-09-08T00:00:00Z
- Updated: 2026-09-08T12:02:58Z
- Author: Joren
- ID: 583
- Canonical: https://0110.be/posts/_Introduction_to_Sampo-UI_at_FedOSC_Linked_Open_Data_Visualisation_Workshop

- Tags: [GhentCDH](https://0110.be/tags/GhentCDH.md), [Presentation](https://0110.be/tags/Presentation.md), [UGent](https://0110.be/tags/UGent.md)

FedOSC, the Belgian Federal Open Science Cloud, supports open science and research data management at Belgium's federal scientific institutions. On 8 September 2026, it organised a [day on data visualisation and Linked Open Data](https://fedosc.miraheze.org/wiki/Events/DataViz) at KIK-IRPA in Brussels, with talks, demos and a approaches on cultural heritage datasets.

My contribution to the closing talks was an introduction to Sampo-UI, an open-source framework for building search and visualisation interfaces on top of Linked Open Data. I explained why we use it at the Ghent Centre for Digital Humanities: several projects need similar filters, maps and data exports, so it makes sense to reuse a common framework. The presentation covers how Sampo-UI works, our contributions to it, and a practical example with the NuMAD coin database.

The [Sampo-UI presentation](https://0110.be/attachment/cors/2026.09.08-sampo-ui-fedosc-brussels/index.html) is available online and embedded below.

<iframe src="https://0110.be/attachment/cors/2026.09.08-sampo-ui-fedosc-brussels/index.html" title="Introduction to Sampo-UI at FedOSC" style="width: 100%; aspect-ratio: 16 / 9; border: 0;" loading="lazy" allowfullscreen></iframe>

<br>

---

## [GhentCDH at the Faculty Research Day](https://0110.be/posts/GhentCDH_at_the_Faculty_Research_Day.md)

- Published: 2024-11-27T00:00:00Z
- Updated: 2024-11-27T10:07:51Z
- Author: Joren
- ID: 551
- Canonical: https://0110.be/posts/GhentCDH_at_the_Faculty_Research_Day

- Tags: [GhentCDH](https://0110.be/tags/GhentCDH.md), [Presentation](https://0110.be/tags/Presentation.md), [UGent](https://0110.be/tags/UGent.md)

The [research day of the faculty of Arts and Philosophy of Ghent University](https://www.lwresearchday.ugent.be/) took place last November. The theme of the day was ‘*From Source to Understanding*’ and the program gave an overview of the breadth of research at our faculty with topics as logic, history, archeology, chemistry, geography, language studies, ... There were several contributions by our group: the Ghent Center for Digital Humanities. The contribution by me and my close colleagues [was a poster about a reusable text annotation](https://0110.be/files/attachments/551/poster_text_annotation.webp) building block.

<center>
<img style="max-height:550px" src="https://0110.be/files/attachments/551/poster_text_annotation.webp" /><br>
<small>Fig: Poster on a text annotation component.</small>
</center>

At GhentCDH we support several text annotation projects and have extracted a text annotation component for reuse. The abstract reads: 

> "*Text annotation is essential for analyzing ancient texts, identifying entities in texts, or documenting evolving grammar. There is a need for reusable annotation methods which copes with challenges such as overlapping annotations, filtering annotation types, and enabling large-scale collaboration and computational analysis on text annotation work.*
> 
> *We present a reusable text annotation component built with TypeScript and Vue 3. It provides an intuitive interface for creating, visualizing, and editing annotations, it allows component users to enrich annotations with complex metadata, and facilitates flexible annotation filtering. This solution meets many needs of researchers in digital humanities and ancient language studies and will be used in several GhentCDH projects.*"

Get more info, try it out and use it in your project by checking the [text annotator source code repository](https://github.com/GhentCDH/vue_component_annotated_text).




---

## [Offloading authentication and user management to Keycloak - A minimal example with Nuxt and Litestar](https://0110.be/posts/Offloading_authentication_and_user_management_to_Keycloak_-_A_minimal_example_with_Nuxt_and_Litestar.md)

- Published: 2024-03-13T00:00:00Z
- Updated: 2024-03-19T09:13:26Z
- Author: Joren
- ID: 542
- Canonical: https://0110.be/posts/Offloading_authentication_and_user_management_to_Keycloak_-_A_minimal_example_with_Nuxt_and_Litestar

- Tags: [GhentCDH](https://0110.be/tags/GhentCDH.md), [UGent](https://0110.be/tags/UGent.md)

<div style="width:30%;float:right;margin-bottom:10px;margin-left:10px">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 193.036 39.861"><path fill="#4d4d4d" d="M5.795 9.869 11.511.003 34.53 0l5.685 9.964.007 19.932-5.691 9.958-23.012.008-5.782-9.965z"/><path fill="#ededed" d="M5.738 29.894h10.374l-5.698-10.041 4.634-9.982-9.252-.002L0 19.934"/><path fill="#e0e0e0" d="M19.258 29.894h7.583l6.705-9.773-6.588-10.156h-8.92l-5.373 9.814z"/><path fill="#acacac" d="m0 19.933 5.738 9.964h10.375l-5.636-9.93z"/><path fill="#9e9e9e" d="m12.774 19.935 6.485 9.962h7.582l6.6-9.958z"/><path fill="#00b8e3" d="m15.342 19.94-1.957.57-1.878-.571 7.667-13.29 1.918 3.318"/><path fill="#33c6e9" d="m21.084 29.894-1.908 3.332-5.093-5.487-2.58-7.797v-.004h3.838"/><path fill="#008aaa" d="M11.508 19.939h-.004v.003l-1.917 3.322-1.925-3.307 1.952-3.386 5.728-9.92h3.834"/><path fill="#d4d4d4" d="M32.604 29.894h11.612l-.007-19.93H32.604Z"/><path fill="#919191" d="M32.604 19.966v9.93h11.591v-9.93z"/><path fill="#00b8e3" d="M19.178 33.23h-3.837l-5.754-9.967 1.917-3.32z"/><path fill="#008aaa" d="M34.519 19.939 26.85 33.227c-.705-1.036-1.913-3.33-1.913-3.33l5.753-9.96z"/><path fill="#00b8e3" d="m30.68 33.227-3.83-.001 7.67-13.288 1.916-3.318 1.922 3.34m-3.839-.021h-3.828l-5.755-9.973 1.905-3.314 4.658 5.922z"/><path fill="#33c6e9" d="M36.436 16.618v.003l-1.917 3.318-7.677-13.286 3.841.002z"/><path fill="#626262" d="M175.972 9.98a.193.193 0 0 0-.195.196v19.503c0 .106.086.195.195.195h4.049c.106 0 .195-.09.195-.195V24.31c0-.046.016-.093.05-.13l.181-.204 1.6-1.782a.196.196 0 0 1 .302.016l1.528 2.06 2.735 3.68 1.002 1.347.367.497c.04.05.096.08.159.08h4.7a.2.2 0 0 0 .162-.312l-.973-1.356-1.389-1.954c-.413-.576-.856-1.198-1.333-1.866l-.215-.304-1.76-2.48a1565.7 1565.7 0 0 0-1.934-2.706.19.19 0 0 1 .016-.241l1.551-1.724 3.725-4.14 2.239-2.487a.218.218 0 0 0 .05-.123.195.195 0 0 0-.196-.201h-4.97a.195.195 0 0 0-.143.062l-1.558 1.694-3.324 3.614-2.235 2.428a.194.194 0 0 1-.338-.132v-7.471a.195.195 0 0 0-.195-.195Z"/><path fill="#6f6f6f" d="M161.562 9.98a.198.198 0 0 0-.178.12l-5.213 12.065-.003.003-.007.013-.003.01-.674 1.565-.04.096-.087.195h.001l-.073.166v.003l-2.027 4.693-.298.69a.196.196 0 0 0 .178.275h4.3a.196.196 0 0 0 .175-.112c0-.004.004-.004.004-.007l1.498-3.485.248-.576a.199.199 0 0 1 .182-.12h8.08a.19.19 0 0 1 .178.12l1.664 3.866 1.865-6.618-1.499-3.47-1.339-3.098-2.712-6.273a.191.191 0 0 0-.179-.12h-2.526zm7.905 19.58v.003l.086.192c.03.073.099.12.178.12h4.3a.197.197 0 0 0 .179-.276l-.04-.09-2.838-6.567zm-5.87-13.362c.074 0 .147.04.181.117l.943 2.2.952 2.225.285.664a.194.194 0 0 1-.179.272h-4.389a.194.194 0 0 1-.178-.272l.516-1.19 1.69-3.9a.195.195 0 0 1 .18-.116z"/><path fill="#7d7d7d" d="M143.452 9.524c-.826 0-1.617.076-2.368.235v.004-.004h-.003a9.78 9.78 0 0 0-3.556 1.488 10.59 10.59 0 0 0-1.497 1.224c-1.486 1.453-2.428 3.197-2.815 5.176l-.002.003-.014.076-.005.023-.042.225v-.001l-.003.012v.006l-.01.085v.009a11.29 11.29 0 0 0-.126 1.715c0 2.63.816 4.872 2.45 6.727.175.206.367.404.565.599.506.496 1.043.93 1.608 1.3 1.68 1.098 3.619 1.647 5.818 1.647.245 0 .486-.006.724-.023 2.13-.12 4.001-.784 5.615-1.991a10.44 10.44 0 0 0 1.089-.933l.01-.01a9.983 9.983 0 0 0 1.922-2.583c.148-.288.28-.582.396-.887.46-1.174.688-2.457.688-3.845 0-.374-.016-.742-.05-1.1v-.006a9.841 9.841 0 0 0-.783-3.1c-.5-1.15-1.227-2.191-2.183-3.124-.397-.39-.814-.74-1.25-1.052-1.76-1.263-3.817-1.895-6.178-1.895zm.017 3.873c1.66 0 3.059.625 4.197 1.875.062.067.122.136.175.205 1.022 1.214 1.531 2.66 1.531 4.336 0 1.17-.248 2.223-.744 3.162a6.456 6.456 0 0 1-1.138 1.545 5.658 5.658 0 0 1-1.382 1.048c-.79.423-1.67.635-2.64.635a5.57 5.57 0 0 1-2.56-.592 5.46 5.46 0 0 1-1.12-.77 5.668 5.668 0 0 1-.516-.503c-1.14-1.243-1.71-2.751-1.71-4.524 0-.053 0-.103.003-.156.03-1.707.599-3.168 1.707-4.386.83-.912 1.802-1.495 2.913-1.74a6.03 6.03 0 0 1 1.284-.135z"/><path fill="#888" d="M120.252 9.98a.193.193 0 0 0-.195.196v19.503c0 .106.086.195.195.195h12.528c.11 0 .196-.09.196-.195v-3.57a.195.195 0 0 0-.196-.194h-8.09a.192.192 0 0 1-.194-.191V10.176a.19.19 0 0 0-.113-.176.174.174 0 0 0-.083-.02h-2.242z"/><path fill="#949494" d="M109.792 9.525c-2.923 0-5.394.989-7.415 2.96-.367.36-.7.738-1.002 1.13v.004c-1.352 1.756-2.027 3.84-2.027 6.25 0 1.377.215 2.64.649 3.794l.006-.002-.005.003c.254.695.592 1.336.999 1.948v.003c.003 0 .003.003.003.003a9.828 9.828 0 0 0 1.323 1.58 10.01 10.01 0 0 0 1.984 1.512h.003a9.831 9.831 0 0 0 .953.484h.007l.003.003h.003c1.37.602 2.907.903 4.617.903.503 0 .996-.037 1.475-.106h.01c.308-.043.612-.102.913-.175 1.683-.404 3.225-1.257 4.63-2.557v-.002l.001.002c.281-.258.559-.54.83-.837a.199.199 0 0 0-.007-.27l-2.566-2.643a.19.19 0 0 0-.172-.057.212.212 0 0 0-.116.07c-.685.81-1.465 1.419-2.338 1.822-.867.4-1.826.6-2.874.6-.718 0-1.39-.113-2.011-.341a5.641 5.641 0 0 1-2.057-1.34 5.433 5.433 0 0 1-1.3-2.066h-.007l.007-.001c-.255-.715-.38-1.508-.38-2.385 0-1.723.512-3.118 1.544-4.183.076-.076.152-.153.235-.23 1.184-1.09 2.612-1.636 4.283-1.636.611 0 1.197.076 1.75.229v-.001c1.27.344 2.384 1.085 3.343 2.216.076.09.215.096.29.007l2.498-2.832a.201.201 0 0 0-.003-.264c-1.955-2.147-4.323-3.334-7.1-3.556-.322-.025-.646-.04-.977-.04z"/><path fill="#aaa" d="M82.588 9.98a.195.195 0 0 0-.17.29l1.892 3.309 3.423 5.983 1.38 2.41a.2.2 0 0 1 .026.097v7.61c0 .106.086.195.195.195h4.049c.109 0 .194-.09.194-.195v-7.61c0-.033.01-.066.027-.096l.976-1.706 3.704-6.476.757-1.32.503-.88h-.007l.007-.003.754-1.316a.194.194 0 0 0-.168-.29h-4.363a.196.196 0 0 0-.168.095l-3.953 6.803-.003.003v.003l-.212.156-.159.122a.203.203 0 0 1-.082-.076l-.067-.112-.099-.17-3.905-6.73a.196.196 0 0 0-.169-.095zm15.537 2.04v.002l-.004.002z"/><path fill="#bcbcbc" d="M66.598 9.98a.193.193 0 0 0-.196.196v19.503c0 .106.086.195.195.195h14.264c.11 0 .196-.09.196-.195v-3.54a.196.196 0 0 0-.196-.194h-9.825a.195.195 0 0 1-.196-.195v-3.737c0-.106.09-.196.196-.196h8.519a.195.195 0 0 0 .195-.194v-3.394c0-.11-.09-.195-.195-.195h-8.52a.196.196 0 0 1-.195-.195V14.13c0-.11.09-.195.196-.195h9.515a.195.195 0 0 0 .195-.195v-3.565a.195.195 0 0 0-.195-.195h-7.829z"/><path fill="#b8b8b8" d="M47.256 9.98a.193.193 0 0 0-.195.196v19.503c0 .106.086.195.195.195h4.048c.11 0 .196-.09.196-.195V24.31c0-.046.016-.093.05-.13l.842-.942.94-1.044a.196.196 0 0 1 .3.016l2.808 3.777.002.002 2.016 2.713.81 1.09a.19.19 0 0 0 .156.08h4.703a.197.197 0 0 0 .158-.31l-.171-.241a693.927 693.927 0 0 1-1.846-2.587c-.566-.79-1.194-1.673-1.888-2.652l-.07-.1v.002-.002a1569.226 1569.226 0 0 0-3.628-5.086.195.195 0 0 1 .017-.241l1.772-1.968h-.006l.006-.001v-.003l1.459-1.62 1.402-1.558 2.88-3.202a.194.194 0 0 0-.145-.324H59.1a.196.196 0 0 0-.146.063l-3.079 3.345-4.038 4.39a.194.194 0 0 1-.338-.132V10.17a.193.193 0 0 0-.195-.192h-2.11zm.091 9.823v.01h-.001zm12.27 8.34v.002h-.001z"/><path fill="#a0a0a0" d="M89.222 29.806c-.024-.025-.045-1.79-.045-3.92V22.01l-3.38-5.904c-1.996-3.487-3.364-5.945-3.342-6.003.032-.084.357-.098 2.278-.098 2.052 0 2.25.01 2.342.115.055.064.986 1.649 2.069 3.523 1.082 1.873 2.003 3.443 2.045 3.488.194.21.46-.181 2.48-3.662l2.01-3.465h2.275c1.894 0 2.28.016 2.31.094.02.05-1.477 2.737-3.326 5.969l-3.362 5.876-.066 7.872-2.121.018c-1.167.01-2.142-.003-2.167-.028z"/><path fill="#acacac" d="M66.456 29.767c-.017-.045-.023-4.503-.014-9.905l.017-9.823h14.22v3.837l-4.855.017c-3.453.012-4.88.038-4.944.09-.13.109-.13 3.91 0 4.018.063.052 1.362.079 4.448.09l4.36.018v3.638l-4.36.017c-3.086.012-4.385.039-4.448.09-.07.06-.089.465-.089 1.98 0 1.047.018 1.95.04 2.009.036.094.538.104 4.999.104 3.29 0 5 .023 5.086.069.122.065.128.156.128 1.872 0 1.314-.022 1.825-.08 1.883-.118.118-14.463.115-14.508-.003z"/></svg>
</div>

At the [Ghent Center for Digital Humanities](https://www.ghentcdh.ugent.be/) we provide software services for researchers. Think about, for example, annotation platforms for ancient texts or collaborative databases with geographically referenced historical data. Each of those services need some kind of authentication and user management: some parts of the service might be public, some only accessible for researchers at Ghent University and other parts need to be accessible e.g. to external researchers or collaborators. Providing authentication, login-flows and user management for each and every service quickly becomes tedious and, frankly, boring.

We went looking for a solution and stumbled on [Keycloak](https://www.keycloak.org/). Keycloak is an open source __Identity and Access Management__ system and is able to either authenticate users itself or pass through authenticate to other authentication providers like LDAP, GitHub, OAuth accounts, or others. It avoids the need to setup application-specific user management system. Flows like 'forget password', 'verify email', 'two factor authentication' are not part of your application itself but are provided by Keycloak. Leaving the developer to focus on application specific tasks.

<center>
<video src="https://0110.be/files/attachments/542/keycloak_screen-recording.mp4" style="width:70%" controls autoplay></video><br>
<small>Video: An API call to a protected back-end first fails. After authentication and receiving a JWT token, the back-end call succeeds. The authenticated session is then shown in Keycloak.</small>
</center>


Integration with Keycloak is a bit of work and not straightforward. As part of trying out Keycloak I have created a [minimal working example of a front-end / back-end system which uses Keycloak for authentication](https://github.com/GhentCDH/nuxt-keycloak-jwt-auth/). To get full access to the back-end API the user first needs a valid JWT-token provided by Keycloak. The flow can be seen in the video above. The dockerized environment can perhaps serve as inspiration for similar setups. Please do try out the [dockerized minimal working example](https://github.com/GhentCDH/nuxt-keycloak-jwt-auth/) and see if Keycloak can fit your use-case.





---

## [Containerized development - Dockerized Python database development](https://0110.be/posts/Containerized_development_-_Dockerized_Python_database_development.md)

- Published: 2024-01-22T00:00:00Z
- Updated: 2024-01-22T10:31:50Z
- Author: Joren
- ID: 540
- Canonical: https://0110.be/posts/Containerized_development_-_Dockerized_Python_database_development

- Tags: [GhentCDH](https://0110.be/tags/GhentCDH.md), [UGent](https://0110.be/tags/UGent.md)

<div style="float:right;width:35%;max-width:300px;margin-left:10px;margin-bottom:10px;box-shadow: 0 3px 5px rgba(0, 0, 0, 0.4);">
<center>
<img loading="lazy" style="width:100%" src="https://0110.be/files/attachments/540/containerized_development.webp"><br>
<small>Fig: Containerized development.</small>
</center>
</div>

At the [Ghent Center for Digital Humanities](https://www.ghentcdh.ugent.be/) (GhentCDH) we offer IT-services mainly for researchers in the Humanities at Ghent University. The services range from internal collaborative research tools to publicly facing science communication platforms. Technically, it is a mix of off the shelve software with or without modifications and custom solutions using several technical stacks. It is a challenge to keep these services running, secure and up-to-date for years with a limited budget.

In an attempt to make maintenance of these services more manageable we are in the process of [containerizing](https://en.wikipedia.org/wiki/Containerization_(computing)) our software. __Running software in containers has advantages__. One of the advantages is a guaranteed consistency across environments. Also, isolated software containers can be beneficial for security and stability. It also allows one to run different versions of a stack on the same server without running into compatibility problems. 

Next to running software in containers, __development in containers also has advantages__. It allows you to switch projects easily without needing to install dependencies - e.g a specific database system version - directly on a development machine. The main advantage I see is that containerization promotes developer hygiene. Stereotypically, developers do not have the best hygiene and can use any available help. Containerization forces developers to think about separation of code and configuration, code and data and it forces to be explicit about dependencies and environmental assumptions.

The main disadvantage is that some configuration is needed to get the containers running and that there is a small performance penalty. The following might help with that first part.


## Dockerized Python database development

To put the theory to the test my colleagues and I put together a [GitHub repository with a dockerized Python development setup](https://github.com/GhentCDH/Python-db-dev). It shows interaction between Python and a PostgreSQL database. The database system runs in a container and the development environment is also kept in a container. Both containers are started with `docker compose` and configured via a `.env` file.

The stack uses a recent Python version, [PDM](https://pdm-project.org/latest/) to resolve Python dependencies and SQLAlchemy to interact with the PostgreSQL database. The VS code editor allows developers to __run and debug software in a container__. The video below shows the startup procedure and setting a breakpoint in some Python code.

<center>
<video style="width:50%" poster="https://0110.be/files/attachments/540/screengrab.webp" controls preload="none">
<source src="https://0110.be/files/attachments/540/dev_in_container.mp4" type="video/mp4">
</video><br>
<small>Vid: Starting a database server and development container. Running and debugging Python code in a container.</small>
</center>
<br>

Note that this is just an example setup, your setup might look quite different. You might need a different stack, use a different container environment (e.g. podman) or IDE but the principle of container based development could stay the same. 

I have put off using containers for quite a while and I am quite a late convert, but now that I am doing more technical work in a small team I do see the advantages of an easy-to-set up, controlled, containerized development with explicitly defined dependencies. If you have no experience with containers yet, I would encourage you to at least __try container based development__ out and see where it could help you!


---

## [Printing a part of the world - a 3D-printed cityscape](https://0110.be/posts/Printing_a_part_of_the_world_-_a_3D-printed_cityscape.md)

- Published: 2024-01-09T00:00:00Z
- Updated: 2025-11-13T22:55:02Z
- Author: Joren
- ID: 537
- Canonical: https://0110.be/posts/Printing_a_part_of_the_world_-_a_3D-printed_cityscape

- Tags: [0110.be](https://0110.be/tags/0110.be.md), [GhentCDH](https://0110.be/tags/GhentCDH.md), [UGent](https://0110.be/tags/UGent.md)

<div style="float:right;width:20%;max-width:190px;margin-left:10px;margin-bottom:10px">
<center>
<img  style="width:100%" src="https://0110.be/files/attachments/537/3dprinting-globe.jpg"><br>
<small>Fig: 3D printing your part of the world.</small>
</center>
</div>
My ex-girlfriend and current wife likes maps. While looking for a gift for the new-years I got the idea to give her a 3D map of the nearby [historic city center of Ghent with its three iconic towers](https://earth.google.com/web/@51.05385689,3.72537111,16.45165093a,593.4748548d,35y,19.92318437h,59.99406466t,359.99999999r/data=OgMKATA). I have a 3D printer at home but still need to find a printable 3D model of Ghent.

Luckily, a couple of days ago a piece of software appeared to [capture Google Earth tiles -cubes- into a single 3D file](https://github.com/OmarShehata/google-earth-as-gltf). There you can select an area of interest via google maps and download a GLTF file which captures the landscape in 3D. The software needs an API key which can be requested via the Google Developer tools. 

After downloading a GLTF file, the 3D model needs to be made 3D-printable. There are online [GLTF to STL converters](https://products.aspose.app/3d/conversion/gltf-to-stl) but a bit of care needs to be taken to end up with an actually **printable** STL. My selected area of interest only has slight height differences in the landscape which are handled by placing the STL file on a base which compensates for these differences. Your 3D slicer can also generate structure to support inclinations in the landscape.

The 3D model generated by Google Earth is quite noisy and can contain floating parts and holes. It may be needed to edit the STL mesh directly. Selecting a slightly shifted area of interest may also solve problems with the edges of the print: take care to chop less buildings in two. 

Have fun printing your own piece of the world!

<center>
<iframe  src="https://0110.be/attachment/cors/2023.12.stlviewer/index.html" loading="lazy" style="border:none;box-shadow: 0 3px 5px rgba(0, 0, 0, 0.4);width: 100%;height:15rem" ></iframe>
<small>
Fig: a 3D model for the Ghent city center visualized with an <a href="https://tonybox.net/posts/simple-stl-viewer/">Three.js STL viewer</a>. 
</small>
</center>

&nbsp;

![Unfinished 3D printed map](https://0110.be/files/photos/537/3d-printing.jpg)

![Finished 3D printed map](https://0110.be/files/photos/537/Ghent-city-center-3d-print.jpg)

![Ghent framed ](https://0110.be/files/photos/537/PXL_20231226_182335084.MP.jpg)

![Framed Ghent](https://0110.be/files/photos/537/PXL_20231226_182355545.MP.jpg)

---

## [Look, Ma! No Javascript! A case against the overuse of Javascript](https://0110.be/posts/Look%2C_Ma%21_No_Javascript%21_A_case_against_the_overuse_of_Javascript.md)

- Published: 2023-12-20T00:00:00Z
- Updated: 2023-12-21T07:59:13Z
- Author: Joren
- ID: 534
- Canonical: https://0110.be/posts/Look%2C_Ma%21_No_Javascript%21_A_case_against_the_overuse_of_Javascript

- Tags: [Code](https://0110.be/tags/Code.md), [GhentCDH](https://0110.be/tags/GhentCDH.md), [UGent](https://0110.be/tags/UGent.md)

<div style="float:right;width:20%;max-width:190px;margin-left:10px;margin-bottom:10px">
<center>
<img  style="width:100%" src="https://0110.be/files/attachments/534/hammer_vs_screw.jpeg"><br>
<small>Fig: Hammer vs. screw. Not the right tool for the job.</small>
</center>
</div> For the last couple of years this blog has not been using any Javascript. During the last decade this has become quite rare. Only [1.2% of websites do not use Javascript](https://w3techs.com/technologies/details/cp-javascript) I see this as a problem. In this text I want to argue that Javascript is perhaps not always the right tool for the job. Especially for web-pages which visitors simply want to read and where *no explicit interactive actions* are wanted from a user perspective, I see Javascript as detrimental. 

I was triggered to write this by a few observations. One is by a Rails frontend framework which claims that [*"the only technology we should be using to create web UI is JavaScript"*](https://github.com/rage-rb/rage). This implies that the whole DOM should be rendered by Javascript. On the other hand there are frameworks which now advertise server side rendering as new feature like [Blazor](https://community.devexpress.com/blogs/aspnet/archive/2023/12/13/blazor-new-net-8-render-modes-v23-2.aspx) and [Nuxt](https://v2.nuxt.com/docs/concepts/server-side-rendering/). The old thing is new again. 

Let's look at a few examples. Take visiting news website. On a news site, a user expects to be able to read current news, reviews, opinions, .. and there is no expectation of interactivity.  Basically, a news site could work equally well on physical paper, as was the case for the last century or more. Ideally, a news site is a static HTML page with an easy to follow layout and some images, perhaps some static ads, with information flowing in a single direction. 

If we look at, for example, the Guardian, we do not get this ideal experience, instead 82 Javascript files are loaded and the full website takes six full seconds to load on a fast fiber connection. The site even tries to load files from other domains. This bloat results in 8 website programming errors and [CORS](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing)-issues. The Guardian website is far from the worst example of this sprawl of Javascript, the [front-end for the Guaridan](https://github.com/guardian/frontend) is even developed in the open.

Another news site is [Hacker News](https://news.ycombinator.com/). With its focus on Sillicon valley and technical news, this site has probably one of the most tech-savvy readers and ... it does not rely on Javascript for functioning. There is a [single small, **readable** 150 line script](https://news.ycombinator.com/hn.js) to improve usability but that is it. The  makes the the website fast, easily indexable, straightforward to maintain, accessible, future-proof, failsafe, and compatible with even the most basic browsers and screen-readers.

Similarly, this blog is a dynamic [Rails](https://rubyonrails.org/) site but thanks to extensive use of server-side rendering and caching it behaves more like a static site generator: once everything is cached, the application mostly serves static HTML fragments. The client-side requirements are minimal as well: since no Javascript is used to modify the DOM - or even at all - lay-outing is straightforward.


Note that some blog posts feature advanced web *application* prototypes which do use a boatload of Javascript e.g. to [convert audio](https://0110.be/posts/An_audio_focused_ffmpeg_build_for_the_web), [visualize audio](https://0110.be/posts/Gabber_-_Visualizing_constant-Q_transform_in_the_browser), [interact with micro-controllers or MIDI instruments](https://0110.be/posts/mot_-_MIDI_and_OSC_Tools_-_Sending_UDP_messages_from_the_browser),... . These prototypes use many of the available browser APIs like the Web Audio API, WebAssembly, Web MIDI API, Web Bluetooth API, WebGL, .... I really do like targeting modern browsers with offer many possibilities to build easy-to-use *applications*. But that is exactly a distinction that needs to be made: *applications versus pages*. Javascript versus No Javascript.


---
