From 5ad5b280120bfd27f70826fab8180d3e35aa15cd Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Tue, 7 Apr 2026 15:55:00 +0200 Subject: [PATCH 01/15] Add configuration to build siemens-internal with different baseURL --- config/siemens-internal/hugo.toml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 config/siemens-internal/hugo.toml diff --git a/config/siemens-internal/hugo.toml b/config/siemens-internal/hugo.toml new file mode 100644 index 00000000000..fce6789fbec --- /dev/null +++ b/config/siemens-internal/hugo.toml @@ -0,0 +1,10 @@ +# Merges with _default/config.toml if --environment internal +# Configuration for internal Siemens documentation deployment +# Need to set _merge = 'deep' to overwrite original value +# ============================================================= + +baseURL = "https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/" +title = "Mendix Documentation (Internal)" + +# Disable robots.txt for internal deployment +enableRobotsTXT = false From d8006b7f2ee134f17e6f167c5430ff36544ada48 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Wed, 22 Apr 2026 09:35:26 +0200 Subject: [PATCH 02/15] Use canonifyURLs to resolve issues with linking in siemens-internal build. --- config/siemens-internal/README.md | 92 +++++++++++++++++++++++++++++++ config/siemens-internal/hugo.toml | 4 ++ scripts/fix-siemens-paths.sh | 26 +++++++++ 3 files changed, 122 insertions(+) create mode 100644 config/siemens-internal/README.md create mode 100644 scripts/fix-siemens-paths.sh diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md new file mode 100644 index 00000000000..150d90ad230 --- /dev/null +++ b/config/siemens-internal/README.md @@ -0,0 +1,92 @@ +# Siemens Internal Deployment Configuration + +This directory contains the Hugo environment configuration for deploying the Mendix documentation to the Siemens internal documentation portal. + +## Deployment URL + +The site is deployed at: +``` +https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/ +``` + +## The Problem + +When deploying a Hugo site to a deep URL path (not at the domain root), CSS, JavaScript, and image references need to include the full path. Hugo generates URLs based on the `baseURL` setting, but with deep paths, the `canonifyURLs` feature can cause some assets (specifically CSS and JS) to have doubled paths. + +For example: +- Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` +- Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` + +## The Solution + +We use a two-step approach: + +1. **Configure Hugo** with `canonifyURLs = true` and the full baseURL to ensure all images and internal links work correctly +2. **Post-process** by copying the affected CSS and JS files to the doubled-path location where Hugo generates references to them + +This approach: +- ✅ Requires no changes to templates or Markdown content +- ✅ Only duplicates 3 small files (~740KB total) +- ✅ Works for all images and page links automatically +- ✅ Simple to maintain + +## How to Build + +Run these two commands from the repository root: + +```bash +# Build the site with the siemens-internal environment +hugo --environment siemens-internal --cleanDestinationDir + +# Copy CSS and JS files to the doubled-path location +bash scripts/fix-siemens-paths.sh +``` + +The built site will be in the `public/` directory, ready for deployment to the Siemens internal portal. + +## Configuration Files + +### hugo.toml +Sets the baseURL and enables `canonifyURLs` to handle the deep deployment path. + +### scripts/fix-siemens-paths.sh +Post-processing script that copies: +- `scss/main.css` and `scss/main.css.map` +- `js/main.js` +- `js/click-to-copy.js` + +to the doubled-path location: `public/documentation/internal/PL20260323299104942/en-US/public/{scss,js}/` + +## Technical Details + +### Why canonifyURLs? +The `canonifyURLs = true` setting converts all root-relative URLs (like `/images/foo.svg`) to absolute URLs using the baseURL. This is necessary because: +- Images in templates use hardcoded paths like `/images/...` and `/icons/...` +- Internal page links need the full path +- Without it, all these references would be broken + +### Why the doubled paths? +Hugo's CSS and JS pipeline generates URLs that already include the baseURL path in some cases, and then `canonifyURLs` prepends the baseURL again, causing the path to appear twice. This is a known Hugo issue with deep basePaths. + +### Why not fix the templates? +Modifying templates to use `absURL` for all images would: +- Require changes to shared Docsy theme files +- Need maintenance across Hugo upgrades +- Affect multiple deployment targets (production, development) + +The post-processing approach isolates the Siemens-specific fix. + +## Updating the Deployment Path + +If the Siemens deployment URL changes, update: +1. `baseURL` in `config/siemens-internal/hugo.toml` +2. `DEEP_PATH` variable in `scripts/fix-siemens-paths.sh` + +## Alternative Approaches Considered + +1. **Using relativeURLs**: Would break the landing page images and require template changes +2. **Path-only baseURL**: Would require web server configuration and wouldn't work with direct file access +3. **Template modifications**: Would require maintaining custom versions of Docsy theme files +4. **HTML post-processing**: Would need to parse and modify thousands of HTML files (slower and more complex) + +The current solution is the simplest and most maintainable approach. diff --git a/config/siemens-internal/hugo.toml b/config/siemens-internal/hugo.toml index fce6789fbec..bd15a90a3c5 100644 --- a/config/siemens-internal/hugo.toml +++ b/config/siemens-internal/hugo.toml @@ -6,5 +6,9 @@ baseURL = "https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/" title = "Mendix Documentation (Internal)" +# Convert all absolute paths (starting with /) to use the full baseURL +# This fixes images and most links. The CSS path doubling issue can be fixed with post-processing. +canonifyURLs = true + # Disable robots.txt for internal deployment enableRobotsTXT = false diff --git a/scripts/fix-siemens-paths.sh b/scripts/fix-siemens-paths.sh new file mode 100644 index 00000000000..865683466dc --- /dev/null +++ b/scripts/fix-siemens-paths.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Post-processing script to fix doubled paths in Siemens internal deployment +# This script copies CSS and JS files to the location where Hugo's canonifyURLs generates doubled paths + +set -e + +DEEP_PATH="documentation/internal/PL20260323299104942/en-US/public" +PUBLIC_DIR="public" + +echo "Fixing doubled paths for Siemens internal deployment..." + +# Create the doubled path directory structure +mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/scss" +mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/js" + +# Copy CSS files +echo "Copying CSS files..." +cp "${PUBLIC_DIR}/scss/main.css" "${PUBLIC_DIR}/${DEEP_PATH}/scss/main.css" +cp "${PUBLIC_DIR}/scss/main.css.map" "${PUBLIC_DIR}/${DEEP_PATH}/scss/main.css.map" + +# Copy JS files +echo "Copying JS files..." +cp "${PUBLIC_DIR}/js/main.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/main.js" +cp "${PUBLIC_DIR}/js/click-to-copy.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/click-to-copy.js" + +echo "Done! Files copied to handle doubled paths." From 865427705b62464303ab96e98651faab04d26a1b Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Thu, 28 May 2026 16:05:30 +0200 Subject: [PATCH 03/15] Turn on uglyURLs to see if Siemens server works better with those. --- config/siemens-internal/hugo.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/siemens-internal/hugo.toml b/config/siemens-internal/hugo.toml index bd15a90a3c5..269162e96b9 100644 --- a/config/siemens-internal/hugo.toml +++ b/config/siemens-internal/hugo.toml @@ -12,3 +12,6 @@ canonifyURLs = true # Disable robots.txt for internal deployment enableRobotsTXT = false + +# Enable ugly URLs to help links work on the Siemens site +uglyURLs = true \ No newline at end of file From d954dd40847918530bc5005627d7c2506f57c559 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Thu, 28 May 2026 16:14:29 +0200 Subject: [PATCH 04/15] Update documentation --- config/siemens-internal/README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 150d90ad230..53b032f5ab2 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -9,7 +9,9 @@ The site is deployed at: https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/ ``` -## The Problem +## The Problems + +### 1. Deep URL Path When deploying a Hugo site to a deep URL path (not at the domain root), CSS, JavaScript, and image references need to include the full path. Hugo generates URLs based on the `baseURL` setting, but with deep paths, the `canonifyURLs` feature can cause some assets (specifically CSS and JS) to have doubled paths. @@ -17,6 +19,10 @@ For example: - Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` - Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` +### 2. Pretty URLs Not Supported + +The Siemens internal server does not properly serve Hugo's default "pretty URLs" (e.g., `/page/` resolving to `/page/index.html`). To work around this, we use `uglyURLs = true` which ensures Hugo generates the traditional directory structure with explicit `index.html` files. + ## The Solution We use a two-step approach: @@ -47,7 +53,11 @@ The built site will be in the `public/` directory, ready for deployment to the S ## Configuration Files ### hugo.toml -Sets the baseURL and enables `canonifyURLs` to handle the deep deployment path. + +Sets the baseURL and enables: + +- `canonifyURLs = true` to handle the deep deployment path +- `uglyURLs = true` to ensure proper URL resolution on the Siemens server ### scripts/fix-siemens-paths.sh Post-processing script that copies: From 25676af7d4828d1b50c6784abb40d4b31803450b Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Fri, 29 May 2026 14:46:57 +0200 Subject: [PATCH 05/15] Add information about ugly urls to README --- config/siemens-internal/README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 53b032f5ab2..6e843813b34 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -21,7 +21,12 @@ For example: ### 2. Pretty URLs Not Supported -The Siemens internal server does not properly serve Hugo's default "pretty URLs" (e.g., `/page/` resolving to `/page/index.html`). To work around this, we use `uglyURLs = true` which ensures Hugo generates the traditional directory structure with explicit `index.html` files. +The Siemens internal server does not properly serve Hugo's default "pretty URLs" (e.g., `/page/` resolving to `/page/index.html`). To work around this, we use `uglyURLs = true` which changes how Hugo generates URLs in the HTML: + +* **Without uglyURLs**: Links like `` rely on the server resolving the directory to `index.html` +* **With uglyURLs**: Links explicitly include `/index.html` where needed, ensuring compatibility with servers that don't automatically serve directory indexes + +Note: The file structure remains the same (directories with `index.html` files inside). The setting only affects how URLs are written in the generated HTML. ## The Solution From bc0e25a15b0a4beb13bedc7c4da3a152ba591923 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Fri, 5 Jun 2026 11:00:14 +0200 Subject: [PATCH 06/15] Fix font loading for Siemens internal deployment Update the post-processing script to copy font directories to the doubled-path location, fixing font loading issues on the Siemens internal portal. Changes: - scripts/fix-siemens-paths.sh: Copy webfonts/ and fonts/ directories - config/siemens-internal/README.md: Document font copying and clarify uglyURLs behavior CSS files reference fonts via relative paths (../webfonts/) and root-relative paths (/fonts/), which need to be available at the doubled-path location for proper loading. Co-Authored-By: Claude Sonnet 4.5 --- config/siemens-internal/README.md | 16 ++++++++++------ scripts/fix-siemens-paths.sh | 9 ++++++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 6e843813b34..f8bfe98cdbb 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -37,7 +37,7 @@ We use a two-step approach: This approach: - ✅ Requires no changes to templates or Markdown content -- ✅ Only duplicates 3 small files (~740KB total) +- ✅ Only duplicates necessary assets (~3.4MB total: CSS, JS, and fonts) - ✅ Works for all images and page links automatically - ✅ Simple to maintain @@ -65,12 +65,16 @@ Sets the baseURL and enables: - `uglyURLs = true` to ensure proper URL resolution on the Siemens server ### scripts/fix-siemens-paths.sh -Post-processing script that copies: -- `scss/main.css` and `scss/main.css.map` -- `js/main.js` -- `js/click-to-copy.js` -to the doubled-path location: `public/documentation/internal/PL20260323299104942/en-US/public/{scss,js}/` +Post-processing script that copies assets to the doubled-path location where Hugo's `canonifyURLs` generates references: + +* `scss/main.css` and `scss/main.css.map` +* `js/main.js` +* `js/click-to-copy.js` +* `webfonts/*` (Font Awesome fonts - referenced via relative paths in CSS) +* `fonts/*` (Noto Sans and Patron fonts - referenced via root-relative paths in CSS) + +All files are copied to: `public/documentation/internal/PL20260323299104942/en-US/public/{scss,js,webfonts,fonts}/` ## Technical Details diff --git a/scripts/fix-siemens-paths.sh b/scripts/fix-siemens-paths.sh index 865683466dc..b30c05532f5 100644 --- a/scripts/fix-siemens-paths.sh +++ b/scripts/fix-siemens-paths.sh @@ -1,6 +1,6 @@ #!/bin/bash # Post-processing script to fix doubled paths in Siemens internal deployment -# This script copies CSS and JS files to the location where Hugo's canonifyURLs generates doubled paths +# This script copies CSS, JS, and font files to the location where Hugo's canonifyURLs generates doubled paths set -e @@ -12,6 +12,8 @@ echo "Fixing doubled paths for Siemens internal deployment..." # Create the doubled path directory structure mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/scss" mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/js" +mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/webfonts" +mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/fonts" # Copy CSS files echo "Copying CSS files..." @@ -23,4 +25,9 @@ echo "Copying JS files..." cp "${PUBLIC_DIR}/js/main.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/main.js" cp "${PUBLIC_DIR}/js/click-to-copy.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/click-to-copy.js" +# Copy font files (needed because CSS references ../webfonts/ and /fonts/) +echo "Copying font files..." +cp -r "${PUBLIC_DIR}/webfonts/"* "${PUBLIC_DIR}/${DEEP_PATH}/webfonts/" +cp -r "${PUBLIC_DIR}/fonts/"* "${PUBLIC_DIR}/${DEEP_PATH}/fonts/" + echo "Done! Files copied to handle doubled paths." From 72c67b55dad3d126c655c33aade10261c2583f92 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Fri, 5 Jun 2026 11:12:41 +0200 Subject: [PATCH 07/15] Use relative paths for fonts in CSS Change font references from root-relative paths (/fonts/) to relative paths (../fonts/) so fonts work correctly in all deployment environments without needing to be copied. Changes: - assets/scss/_font-face.scss: Change font URLs from /fonts/ to ../fonts/ - scripts/fix-siemens-paths.sh: Remove font copying (no longer needed) - config/siemens-internal/README.md: Update documentation to reflect relative path approach This fixes font loading for the Siemens internal deployment while also working for production and development environments. Reduces duplicated files from ~3.4MB to ~2.2MB. Co-Authored-By: Claude Sonnet 4.5 --- assets/scss/_font-face.scss | 22 +++++++++++----------- config/siemens-internal/README.md | 12 ++++++------ scripts/fix-siemens-paths.sh | 12 +++--------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/assets/scss/_font-face.scss b/assets/scss/_font-face.scss index db27cd448a2..afe1020d3d4 100644 --- a/assets/scss/_font-face.scss +++ b/assets/scss/_font-face.scss @@ -1,35 +1,35 @@ @font-face { // LZ - Added for MxDock by request 2024-01-30 font-family: "noto-sans"; - src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-400.woff2") format("woff2"); + src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-400.woff2") format("woff2"); font-style: normal; font-weight: 400; font-display: swap; } - + @font-face { font-family: "noto-sans"; - src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-400-italic.woff2") format("woff2"); + src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-400-italic.woff2") format("woff2"); font-style: italic; font-weight: 400; font-display: swap; } - + @font-face { font-family: "noto-sans"; - src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-600.woff2") format("woff2"); + src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-600.woff2") format("woff2"); font-style: normal; font-weight: 600; font-display: swap; } - + @font-face { font-family: "noto-sans"; - src: local("noto-sans"), url("/fonts/noto-sans/noto-sans-600-italic.woff2") format("woff2"); + src: local("noto-sans"), url("../fonts/noto-sans/noto-sans-600-italic.woff2") format("woff2"); font-style: italic; font-weight: 600; font-display: swap; } - + /* Medium */ @font-face { font-family: "Patron"; @@ -37,9 +37,9 @@ font-weight: 500; font-display: swap; src: local("Patron Medium"), local("Patron-Medium"), - url("/fonts/patron/PatronWEB-Medium.woff2") format("woff2"); + url("../fonts/patron/PatronWEB-Medium.woff2") format("woff2"); } - + /* Light */ @font-face { font-family: "Patron"; @@ -47,7 +47,7 @@ font-weight: 300; font-display: swap; src: local("Patron Light"), local("Patron-Light"), - url("/fonts/patron/PatronWEB-Light.woff2") format("woff2"); + url("../fonts/patron/PatronWEB-Light.woff2") format("woff2"); } /* The main font is Noto Sans */ diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index f8bfe98cdbb..b693f3a3094 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -37,8 +37,8 @@ We use a two-step approach: This approach: - ✅ Requires no changes to templates or Markdown content -- ✅ Only duplicates necessary assets (~3.4MB total: CSS, JS, and fonts) -- ✅ Works for all images and page links automatically +- ✅ Only duplicates CSS and JS files (~2.2MB total) +- ✅ Works for all images, fonts, and page links automatically - ✅ Simple to maintain ## How to Build @@ -66,15 +66,15 @@ Sets the baseURL and enables: ### scripts/fix-siemens-paths.sh -Post-processing script that copies assets to the doubled-path location where Hugo's `canonifyURLs` generates references: +Post-processing script that copies CSS and JS files to the doubled-path location where Hugo's `canonifyURLs` generates references: * `scss/main.css` and `scss/main.css.map` * `js/main.js` * `js/click-to-copy.js` -* `webfonts/*` (Font Awesome fonts - referenced via relative paths in CSS) -* `fonts/*` (Noto Sans and Patron fonts - referenced via root-relative paths in CSS) -All files are copied to: `public/documentation/internal/PL20260323299104942/en-US/public/{scss,js,webfonts,fonts}/` +All files are copied to: `public/documentation/internal/PL20260323299104942/en-US/public/{scss,js}/` + +**Note**: Font files (`webfonts/` and `fonts/`) are referenced using relative paths in the CSS (`../fonts/`, `../webfonts/`) and don't need to be copied. This works for all deployment environments. ## Technical Details diff --git a/scripts/fix-siemens-paths.sh b/scripts/fix-siemens-paths.sh index b30c05532f5..df3102ff2b6 100644 --- a/scripts/fix-siemens-paths.sh +++ b/scripts/fix-siemens-paths.sh @@ -1,6 +1,6 @@ #!/bin/bash # Post-processing script to fix doubled paths in Siemens internal deployment -# This script copies CSS, JS, and font files to the location where Hugo's canonifyURLs generates doubled paths +# This script copies CSS and JS files to the location where Hugo's canonifyURLs generates doubled paths set -e @@ -12,8 +12,6 @@ echo "Fixing doubled paths for Siemens internal deployment..." # Create the doubled path directory structure mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/scss" mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/js" -mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/webfonts" -mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/fonts" # Copy CSS files echo "Copying CSS files..." @@ -25,9 +23,5 @@ echo "Copying JS files..." cp "${PUBLIC_DIR}/js/main.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/main.js" cp "${PUBLIC_DIR}/js/click-to-copy.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/click-to-copy.js" -# Copy font files (needed because CSS references ../webfonts/ and /fonts/) -echo "Copying font files..." -cp -r "${PUBLIC_DIR}/webfonts/"* "${PUBLIC_DIR}/${DEEP_PATH}/webfonts/" -cp -r "${PUBLIC_DIR}/fonts/"* "${PUBLIC_DIR}/${DEEP_PATH}/fonts/" - -echo "Done! Files copied to handle doubled paths." +echo "Done! CSS and JS files copied to handle doubled paths." +echo "Note: Font files use relative paths in CSS and don't need to be copied." From 33893ea6f6f07f4684eea4751af007c67124e7b3 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Fri, 5 Jun 2026 11:50:20 +0200 Subject: [PATCH 08/15] Clarify command-line options Update Siemens internal deployment documentation to reflect that Hugo v0.156.0+ fixed the doubled-path bug. Post-processing is no longer needed. Changes: - config/siemens-internal/README.md: Document Hugo v0.156.0+ fix, update build instructions, clarify technical details - scripts/fix-siemens-paths.sh: Simplify to no-op script for backward compatibility The canonifyURLs bug that caused doubled paths for CSS and JS assets has been resolved in Hugo v0.156.0. Sites can now be built with a single hugo command without post-processing. Co-Authored-By: Claude Sonnet 4.5 --- config/siemens-internal/README.md | 98 ++++++++++++++++--------------- scripts/fix-siemens-paths.sh | 34 +++-------- 2 files changed, 58 insertions(+), 74 deletions(-) diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index b693f3a3094..0ea6dfbbb10 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -5,23 +5,27 @@ This directory contains the Hugo environment configuration for deploying the Men ## Deployment URL The site is deployed at: + ``` https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/ ``` ## The Problems -### 1. Deep URL Path +### 1. Deep URL Path (Fixed in Hugo v0.156.0+) + +**Historical Issue**: Earlier versions of Hugo had a bug where `canonifyURLs` generated doubled paths for CSS and JS assets when deploying to a deep URL path (not at the domain root). + +Example of the old bug: -When deploying a Hugo site to a deep URL path (not at the domain root), CSS, JavaScript, and image references need to include the full path. Hugo generates URLs based on the `baseURL` setting, but with deep paths, the `canonifyURLs` feature can cause some assets (specifically CSS and JS) to have doubled paths. +* Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` +* Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` -For example: -- Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` -- Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` +**Status**: ✅ This issue was fixed in Hugo v0.156.0. The `canonifyURLs` setting now correctly handles deep baseURL paths without generating doubled paths. ### 2. Pretty URLs Not Supported -The Siemens internal server does not properly serve Hugo's default "pretty URLs" (e.g., `/page/` resolving to `/page/index.html`). To work around this, we use `uglyURLs = true` which changes how Hugo generates URLs in the HTML: +The Siemens internal server does not serve Hugo's default "pretty URLs" (like `/page/` resolving to `/page/index.html`). To work around this, use `uglyURLs = true`, which changes how Hugo generates URLs in the HTML: * **Without uglyURLs**: Links like `` rely on the server resolving the directory to `index.html` * **With uglyURLs**: Links explicitly include `/index.html` where needed, ensuring compatibility with servers that don't automatically serve directory indexes @@ -30,82 +34,80 @@ Note: The file structure remains the same (directories with `index.html` files i ## The Solution -We use a two-step approach: +Configure Hugo with the appropriate settings for deep URL deployment: -1. **Configure Hugo** with `canonifyURLs = true` and the full baseURL to ensure all images and internal links work correctly -2. **Post-process** by copying the affected CSS and JS files to the doubled-path location where Hugo generates references to them +1. **Set the full baseURL** including the deep path +2. **Enable `canonifyURLs = true`** to convert all root-relative URLs to use the baseURL +3. **Enable `uglyURLs = true`** to ensure proper URL resolution on servers without automatic directory index serving +4. **Use relative font paths** in CSS (`../fonts/` instead of `/fonts/`) to work across all environments This approach: -- ✅ Requires no changes to templates or Markdown content -- ✅ Only duplicates CSS and JS files (~2.2MB total) -- ✅ Works for all images, fonts, and page links automatically -- ✅ Simple to maintain + +* ✅ Requires no changes to templates or Markdown content +* ✅ No post-processing or file duplication needed (as of Hugo v0.156.0+) +* ✅ Works for all images, fonts, and page links automatically +* ✅ Simple to maintain ## How to Build -Run these two commands from the repository root: +Run this command from the repository root: ```bash # Build the site with the siemens-internal environment hugo --environment siemens-internal --cleanDestinationDir - -# Copy CSS and JS files to the doubled-path location -bash scripts/fix-siemens-paths.sh ``` The built site will be in the `public/` directory, ready for deployment to the Siemens internal portal. +**Note**: The `scripts/fix-siemens-paths.sh` script is kept for backward compatibility but is no longer needed with Hugo v0.156.0+. + ## Configuration Files -### hugo.toml +### Hugo.toml Sets the baseURL and enables: -- `canonifyURLs = true` to handle the deep deployment path -- `uglyURLs = true` to ensure proper URL resolution on the Siemens server +* `canonifyURLs = true` to handle the deep deployment path +* `uglyURLs = true` to ensure proper URL resolution on the Siemens server -### scripts/fix-siemens-paths.sh +### Scripts/fix-siemens-paths.sh -Post-processing script that copies CSS and JS files to the doubled-path location where Hugo's `canonifyURLs` generates references: +**Legacy script** - kept for backward compatibility but no longer needed with Hugo v0.156.0+. -* `scss/main.css` and `scss/main.css.map` -* `js/main.js` -* `js/click-to-copy.js` - -All files are copied to: `public/documentation/internal/PL20260323299104942/en-US/public/{scss,js}/` - -**Note**: Font files (`webfonts/` and `fonts/`) are referenced using relative paths in the CSS (`../fonts/`, `../webfonts/`) and don't need to be copied. This works for all deployment environments. +This script was previously used to work around a Hugo bug where `canonifyURLs` generated doubled paths for CSS and JS files. The bug has been fixed, and the script now simply confirms that no post-processing is needed. ## Technical Details -### Why canonifyURLs? +### Why CanonifyURLs? + The `canonifyURLs = true` setting converts all root-relative URLs (like `/images/foo.svg`) to absolute URLs using the baseURL. This is necessary because: -- Images in templates use hardcoded paths like `/images/...` and `/icons/...` -- Internal page links need the full path -- Without it, all these references would be broken -### Why the doubled paths? -Hugo's CSS and JS pipeline generates URLs that already include the baseURL path in some cases, and then `canonifyURLs` prepends the baseURL again, causing the path to appear twice. This is a known Hugo issue with deep basePaths. +* Images in templates use hardcoded paths like `/images/...` and `/icons/...` +* Internal page links need the full path +* Without it, all these references would be broken + +### Why Relative Font Paths? + +Font files are referenced in CSS using relative paths (`../fonts/`, `../webfonts/`) rather than root-relative paths (`/fonts/`). This approach: + +* Works consistently across all deployment environments (production, development, siemens-internal) +* Does not require environment-specific processing +* Avoids issues with deep URL paths -### Why not fix the templates? -Modifying templates to use `absURL` for all images would: -- Require changes to shared Docsy theme files -- Need maintenance across Hugo upgrades -- Affect multiple deployment targets (production, development) +### Hugo Version Requirements -The post-processing approach isolates the Siemens-specific fix. +* **Hugo v0.156.0 or later** is required for correct handling of deep baseURL paths with `canonifyURLs` +* Earlier versions had a bug where `canonifyURLs` would generate doubled paths for CSS and JS assets ## Updating the Deployment Path -If the Siemens deployment URL changes, update: -1. `baseURL` in `config/siemens-internal/hugo.toml` -2. `DEEP_PATH` variable in `scripts/fix-siemens-paths.sh` +If the Siemens deployment URL changes, update the `baseURL` in `config/siemens-internal/hugo.toml`. ## Alternative Approaches Considered -1. **Using relativeURLs**: Would break the landing page images and require template changes -2. **Path-only baseURL**: Would require web server configuration and wouldn't work with direct file access -3. **Template modifications**: Would require maintaining custom versions of Docsy theme files -4. **HTML post-processing**: Would need to parse and modify thousands of HTML files (slower and more complex) +1. **Using relativeURLs**: Breaks the landing page images and requires template changes +2. **Path-only baseURL**: Requires web server configuration and does not work with direct file access +3. **Template modifications**: Requires maintaining custom versions of Docsy theme files +4. **HTML post-processing**: Requires parsing and modifying thousands of HTML files (slower and more complex) The current solution is the simplest and most maintainable approach. diff --git a/scripts/fix-siemens-paths.sh b/scripts/fix-siemens-paths.sh index df3102ff2b6..42673ae6d59 100644 --- a/scripts/fix-siemens-paths.sh +++ b/scripts/fix-siemens-paths.sh @@ -1,27 +1,9 @@ #!/bin/bash -# Post-processing script to fix doubled paths in Siemens internal deployment -# This script copies CSS and JS files to the location where Hugo's canonifyURLs generates doubled paths - -set -e - -DEEP_PATH="documentation/internal/PL20260323299104942/en-US/public" -PUBLIC_DIR="public" - -echo "Fixing doubled paths for Siemens internal deployment..." - -# Create the doubled path directory structure -mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/scss" -mkdir -p "${PUBLIC_DIR}/${DEEP_PATH}/js" - -# Copy CSS files -echo "Copying CSS files..." -cp "${PUBLIC_DIR}/scss/main.css" "${PUBLIC_DIR}/${DEEP_PATH}/scss/main.css" -cp "${PUBLIC_DIR}/scss/main.css.map" "${PUBLIC_DIR}/${DEEP_PATH}/scss/main.css.map" - -# Copy JS files -echo "Copying JS files..." -cp "${PUBLIC_DIR}/js/main.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/main.js" -cp "${PUBLIC_DIR}/js/click-to-copy.js" "${PUBLIC_DIR}/${DEEP_PATH}/js/click-to-copy.js" - -echo "Done! CSS and JS files copied to handle doubled paths." -echo "Note: Font files use relative paths in CSS and don't need to be copied." +# Post-processing script for Siemens internal deployment +# NOTE: As of Hugo v0.156.0, the doubled-path bug has been fixed. +# This script is kept for backwards compatibility but no longer performs any actions. + +echo "Siemens internal deployment post-processing..." +echo "✓ Hugo v0.156.0+ correctly handles deep baseURL paths" +echo "✓ No file copying needed - all asset references are correct" +echo "Done!" From 6cbb836d3b1507223ac81638040a50b4771ef6f2 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Mon, 8 Jun 2026 13:42:52 +0200 Subject: [PATCH 09/15] Add proposal document for index.html issue --- .../siemens-internal/INDEX-HTML-WORKAROUND.md | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 config/siemens-internal/INDEX-HTML-WORKAROUND.md diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md new file mode 100644 index 00000000000..7e7d47272b4 --- /dev/null +++ b/config/siemens-internal/INDEX-HTML-WORKAROUND.md @@ -0,0 +1,156 @@ +# Adding index.html to Directory Links for Siemens Deployment + +## The Problem + +The Siemens internal web server does not automatically serve `index.html` when a directory URL is requested. When a user or browser requests `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/refguide/`, the server does not automatically serve the `refguide/index.html` file. + +Hugo's `uglyURLs = true` setting helps by making URLs explicit where possible, but Hugo still generates many directory-style links (ending with `/`) throughout the site, particularly in: + +* Navigation menus +* Breadcrumbs +* Internal page links +* Table of contents + +## Recommended Solution: Post-Processing + +The cleanest approach is to post-process the HTML files after Hugo builds them, rewriting directory links to explicitly include `/index.html`. + +### How It Works + +1. **Hugo builds the site normally** using the siemens-internal environment +2. **Post-processing script runs** and: + - Scans all HTML files in the `public/` directory + - Identifies internal links that end with `/` (directory links) + - Rewrites them to end with `/index.html` + - Preserves external links, anchor links, and explicit file references unchanged + +3. **Resulting HTML has explicit paths** that the Siemens server can serve correctly + +### Link Transformation Examples + +**Navigation links:** +```html + + + + + +``` + +**Breadcrumb links:** +```html + + + + + +``` + +### What Gets Changed + +✅ **Internal directory links**: `href=".../"` → `href=".../index.html"` + +❌ **External links**: `href="https://example.com/..."` (unchanged) +❌ **Anchor links**: `href="#section"` (unchanged) +❌ **File links**: `href=".../page.html"` (unchanged) +❌ **Protocol links**: `href="mailto:..."`, `href="javascript:..."` (unchanged) +❌ **Print URLs**: `href=".../_print/..."` (unchanged - print output works differently) + +### Implementation Approach + +The post-processing can be implemented using standard text processing tools: + +**Option 1: Using sed (bash)** +* Fast and simple for straightforward pattern matching +* May require careful escaping of special characters +* Best for simple, well-defined patterns + +**Option 2: Using a scripting language (Python/Node.js)** +* More reliable HTML parsing +* Better handling of edge cases +* Can use proper HTML parsers (BeautifulSoup, cheerio, etc.) +* More maintainable for complex transformations + +**Option 3: Using specialized tools (htmlq, pup)** +* Purpose-built for HTML manipulation +* Balance between sed simplicity and full scripting power + +### Integration with Build Process + +Update the build workflow to: + +```bash +# Build the site +hugo --environment siemens-internal --cleanDestinationDir + +# Post-process to add index.html to directory links +bash scripts/add-index-html-links.sh +``` + +The script would be kept in `scripts/` alongside the existing (now no-op) `fix-siemens-paths.sh`. + +### Advantages + +* ✅ **Non-invasive**: Does not require modifying Hugo templates or Docsy theme files +* ✅ **Environment-specific**: Only affects siemens-internal builds +* ✅ **Maintainable**: Clear separation between Hugo build and Siemens-specific processing +* ✅ **Reversible**: Can easily disable by skipping the post-processing step +* ✅ **Hugo-version independent**: Works regardless of Hugo updates +* ✅ **Preserves other outputs**: Standard HTML and print versions remain unchanged + +### Disadvantages + +* ❌ **Build-time overhead**: Adds processing time (likely 5-30 seconds depending on implementation) +* ❌ **Two-step process**: Requires running a script after Hugo build +* ❌ **Pattern matching complexity**: Must carefully identify which links to transform + +## Alternative Solution: Hugo Render Hooks and Custom Layouts + +Instead of post-processing, modify Hugo's rendering behavior at build time. + +### How It Works + +1. **Create custom render hooks** for markdown links in `.layouts/_default/_markup/` +2. **Override navigation partials** from Docsy theme to append `/index.html` +3. **Configure hooks** to only apply for siemens-internal environment + +### Required Changes + +* Copy Docsy navigation partial files to local `layouts/` directory +* Modify link generation logic to append `/index.html` to directory URLs +* Create markdown render hooks for content links +* Add conditional logic to check environment + +### Advantages + +* ✅ **Build-time only**: No post-processing step required +* ✅ **Single build command**: Just run `hugo --environment siemens-internal` + +### Disadvantages + +* ❌ **More invasive**: Requires copying and modifying theme files +* ❌ **Maintenance burden**: Must update custom layouts when Docsy updates +* ❌ **Complexity**: Multiple layout files need modification +* ❌ **Testing required**: Must verify all link types work correctly +* ❌ **Harder to isolate**: Siemens-specific logic mixed with layout code + +## Recommendation + +Use the **post-processing approach** because: + +1. Hugo v0.156.0 already eliminated the need for the previous doubled-path workaround, so we have experience with post-processing scripts +2. The script can be kept simple and focused on one task +3. It does not require maintaining customized Docsy theme files +4. It is easier to test, debug, and modify +5. It keeps the Siemens-specific logic isolated and well-documented + +The slight increase in build time is acceptable for a deployment that happens infrequently, and the maintainability benefits outweigh the minor inconvenience of a two-step build process. + +## Next Steps + +If you decide to implement this solution: + +1. Create `scripts/add-index-html-links.sh` based on the implementation approach +2. Test thoroughly on a local build to verify link transformations +3. Update `config/siemens-internal/README.md` to document the new build step +4. Verify the transformed site works on the Siemens internal server From ee966b33e336b74a858cf07b83b2f8817d16e7cd Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Tue, 16 Jun 2026 16:07:14 +0200 Subject: [PATCH 10/15] Update baseURL for Siemens internal deployment Change the deployment path to match the location where Siemens serves the documentation tiles. Changes: - config/siemens-internal/hugo.toml: Update baseURL to include /Mendix-Docs/ in path - config/siemens-internal/README.md: Update all URL references to new path - config/siemens-internal/INDEX-HTML-WORKAROUND.md: Update example URLs to new path The new deployment URL is: https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ This matches the directory structure on the Siemens internal web server where the documentation tiles are located. Co-Authored-By: Claude Sonnet 4.5 --- config/siemens-internal/INDEX-HTML-WORKAROUND.md | 6 +++--- config/siemens-internal/README.md | 6 +++--- config/siemens-internal/hugo.toml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md index 7e7d47272b4..ef532f48de8 100644 --- a/config/siemens-internal/INDEX-HTML-WORKAROUND.md +++ b/config/siemens-internal/INDEX-HTML-WORKAROUND.md @@ -2,7 +2,7 @@ ## The Problem -The Siemens internal web server does not automatically serve `index.html` when a directory URL is requested. When a user or browser requests `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/refguide/`, the server does not automatically serve the `refguide/index.html` file. +The Siemens internal web server does not automatically serve `index.html` when a directory URL is requested. When a user or browser requests `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/refguide/`, the server does not automatically serve the `refguide/index.html` file. Hugo's `uglyURLs = true` setting helps by making URLs explicit where possible, but Hugo still generates many directory-style links (ending with `/`) throughout the site, particularly in: @@ -31,10 +31,10 @@ The cleanest approach is to post-process the HTML files after Hugo builds them, **Navigation links:** ```html - + - + ``` **Breadcrumb links:** diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 0ea6dfbbb10..560328904a2 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -7,7 +7,7 @@ This directory contains the Hugo environment configuration for deploying the Men The site is deployed at: ``` -https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/ +https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ ``` ## The Problems @@ -18,8 +18,8 @@ https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/ Example of the old bug: -* Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` -* Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` +* Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/scss/main.css` +* Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` **Status**: ✅ This issue was fixed in Hugo v0.156.0. The `canonifyURLs` setting now correctly handles deep baseURL paths without generating doubled paths. diff --git a/config/siemens-internal/hugo.toml b/config/siemens-internal/hugo.toml index 269162e96b9..37370ec4398 100644 --- a/config/siemens-internal/hugo.toml +++ b/config/siemens-internal/hugo.toml @@ -3,7 +3,7 @@ # Need to set _merge = 'deep' to overwrite original value # ============================================================= -baseURL = "https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/public/" +baseURL = "https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/" title = "Mendix Documentation (Internal)" # Convert all absolute paths (starting with /) to use the full baseURL From 07eda93028ca628905288bbee821a3c6cc4769e2 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Tue, 25 Aug 2026 09:59:41 +0200 Subject: [PATCH 11/15] Add index.html post-processing script for Siemens deployment Adds _scripts/add-index-html-links.sh, which rewrites directory-style href links (ending with /) to explicit /index.html links after a Hugo build, so the Siemens server can serve pages without automatic directory index support. Accepts a base URL argument to handle canonifyURLs-expanded internal links generated by the siemens-internal environment. Moves scripts/ to _scripts/ alongside existing repo scripts, and updates README.md and INDEX-HTML-WORKAROUND.md to document the new build step. Co-Authored-By: Claude Sonnet 4.6 --- _scripts/add-index-html-links.sh | 79 +++++++++++++++++++ {scripts => _scripts}/fix-siemens-paths.sh | 0 .../siemens-internal/INDEX-HTML-WORKAROUND.md | 37 ++++----- config/siemens-internal/README.md | 43 +++++----- 4 files changed, 119 insertions(+), 40 deletions(-) create mode 100644 _scripts/add-index-html-links.sh rename {scripts => _scripts}/fix-siemens-paths.sh (100%) diff --git a/_scripts/add-index-html-links.sh b/_scripts/add-index-html-links.sh new file mode 100644 index 00000000000..250216f62fa --- /dev/null +++ b/_scripts/add-index-html-links.sh @@ -0,0 +1,79 @@ +#!/bin/bash +# Post-processing script for Siemens internal deployment. +# Rewrites directory-style href links (ending with /) to explicit /index.html +# links in all HTML files under public/, so the Siemens server can serve them +# without requiring automatic directory index support. +# +# When built with the siemens-internal environment, canonifyURLs=true causes Hugo +# to expand all internal links to full absolute URLs using the baseURL. Pass that +# baseURL as the second argument so those links are rewritten too. +# +# Skips: +# - External links (contain :// but do not start with base-url) +# - Anchor-only links starting with # +# - Links already ending in .html or .htm +# - Print URLs containing /_print/ +# +# Usage: bash _scripts/add-index-html-links.sh [public-dir] [base-url] +# Default public-dir: public +# Default base-url: (empty — only root-relative and relative links are rewritten) +# +# Example (siemens-internal build): +# bash _scripts/add-index-html-links.sh public \ +# https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ + +set -euo pipefail + +PUBLIC_DIR="${1:-public}" +BASE_URL="${2:-}" + +if [ ! -d "$PUBLIC_DIR" ]; then + echo "Error: directory '$PUBLIC_DIR' not found. Run hugo build first." >&2 + exit 1 +fi + +echo "Adding index.html to directory links in $PUBLIC_DIR..." +[ -n "$BASE_URL" ] && echo "Treating '$BASE_URL' as internal base URL." + +python3 - "$PUBLIC_DIR" "$BASE_URL" << 'PYTHON' +import re, sys +from pathlib import Path + +public_dir = sys.argv[1] +base_url = sys.argv[2].rstrip("/") + "/" if sys.argv[2] else "" + +HREF_RE = re.compile(r"""(href=["'])([^"']*)(["'])""") + +def rewrite_href(m): + pre, url, quote = m.group(1), m.group(2), m.group(3) + + # Treat absolute URLs that start with base_url as internal; skip all others + if "://" in url: + if not (base_url and url.startswith(base_url)): + return m.group(0) + + # Skip anchors, already-explicit file links, and print paths + if ( + url.startswith("#") + or url.endswith(".html") + or url.endswith(".htm") + or "/_print/" in url + ): + return m.group(0) + + if url.endswith("/"): + url = url + "index.html" + return f"{pre}{url}{quote}" + +count = 0 +for path in Path(public_dir).rglob("*.html"): + if "/_print/" in str(path): + continue + original = path.read_text(encoding="utf-8", errors="replace") + updated = HREF_RE.sub(rewrite_href, original) + if updated != original: + path.write_text(updated, encoding="utf-8") + count += 1 + +print(f"Updated {count} HTML files.") +PYTHON diff --git a/scripts/fix-siemens-paths.sh b/_scripts/fix-siemens-paths.sh similarity index 100% rename from scripts/fix-siemens-paths.sh rename to _scripts/fix-siemens-paths.sh diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md index ef532f48de8..4e2f9b6a446 100644 --- a/config/siemens-internal/INDEX-HTML-WORKAROUND.md +++ b/config/siemens-internal/INDEX-HTML-WORKAROUND.md @@ -19,16 +19,17 @@ The cleanest approach is to post-process the HTML files after Hugo builds them, 1. **Hugo builds the site normally** using the siemens-internal environment 2. **Post-processing script runs** and: - - Scans all HTML files in the `public/` directory - - Identifies internal links that end with `/` (directory links) - - Rewrites them to end with `/index.html` - - Preserves external links, anchor links, and explicit file references unchanged + * Scans all HTML files in the `public/` directory + * Identifies internal links that end with `/` (directory links) + * Rewrites them to end with `/index.html` + * Preserves external links, anchor links, and explicit file references unchanged 3. **Resulting HTML has explicit paths** that the Siemens server can serve correctly ### Link Transformation Examples **Navigation links:** + ```html @@ -38,6 +39,7 @@ The cleanest approach is to post-process the HTML files after Hugo builds them, ``` **Breadcrumb links:** + ```html @@ -61,17 +63,20 @@ The cleanest approach is to post-process the HTML files after Hugo builds them, The post-processing can be implemented using standard text processing tools: **Option 1: Using sed (bash)** + * Fast and simple for straightforward pattern matching * May require careful escaping of special characters * Best for simple, well-defined patterns **Option 2: Using a scripting language (Python/Node.js)** + * More reliable HTML parsing * Better handling of edge cases * Can use proper HTML parsers (BeautifulSoup, cheerio, etc.) * More maintainable for complex transformations **Option 3: Using specialized tools (htmlq, pup)** + * Purpose-built for HTML manipulation * Balance between sed simplicity and full scripting power @@ -84,17 +89,18 @@ Update the build workflow to: hugo --environment siemens-internal --cleanDestinationDir # Post-process to add index.html to directory links -bash scripts/add-index-html-links.sh +bash _scripts/add-index-html-links.sh public \ + https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ ``` -The script would be kept in `scripts/` alongside the existing (now no-op) `fix-siemens-paths.sh`. +The script is kept in `_scripts/` alongside the existing (now no-op) `fix-siemens-paths.sh`. ### Advantages * ✅ **Non-invasive**: Does not require modifying Hugo templates or Docsy theme files * ✅ **Environment-specific**: Only affects siemens-internal builds * ✅ **Maintainable**: Clear separation between Hugo build and Siemens-specific processing -* ✅ **Reversible**: Can easily disable by skipping the post-processing step +* ✅ **Reversible**: Disable by skipping the post-processing step * ✅ **Hugo-version independent**: Works regardless of Hugo updates * ✅ **Preserves other outputs**: Standard HTML and print versions remain unchanged @@ -102,7 +108,7 @@ The script would be kept in `scripts/` alongside the existing (now no-op) `fix-s * ❌ **Build-time overhead**: Adds processing time (likely 5-30 seconds depending on implementation) * ❌ **Two-step process**: Requires running a script after Hugo build -* ❌ **Pattern matching complexity**: Must carefully identify which links to transform +* ❌ **Pattern matching complexity**: Must identify which links to transform precisely ## Alternative Solution: Hugo Render Hooks and Custom Layouts @@ -110,7 +116,7 @@ Instead of post-processing, modify Hugo's rendering behavior at build time. ### How It Works -1. **Create custom render hooks** for markdown links in `.layouts/_default/_markup/` +1. **Create custom render hooks** for Markdown links in `.layouts/_default/_markup/` 2. **Override navigation partials** from Docsy theme to append `/index.html` 3. **Configure hooks** to only apply for siemens-internal environment @@ -118,7 +124,7 @@ Instead of post-processing, modify Hugo's rendering behavior at build time. * Copy Docsy navigation partial files to local `layouts/` directory * Modify link generation logic to append `/index.html` to directory URLs -* Create markdown render hooks for content links +* Create Markdown render hooks for content links * Add conditional logic to check environment ### Advantages @@ -138,7 +144,7 @@ Instead of post-processing, modify Hugo's rendering behavior at build time. Use the **post-processing approach** because: -1. Hugo v0.156.0 already eliminated the need for the previous doubled-path workaround, so we have experience with post-processing scripts +1. Hugo v0.156.0 already eliminated the need for the previous doubled-path workaround, and the post-processing approach proved straightforward to implement 2. The script can be kept simple and focused on one task 3. It does not require maintaining customized Docsy theme files 4. It is easier to test, debug, and modify @@ -146,11 +152,6 @@ Use the **post-processing approach** because: The slight increase in build time is acceptable for a deployment that happens infrequently, and the maintainability benefits outweigh the minor inconvenience of a two-step build process. -## Next Steps - -If you decide to implement this solution: +## Status -1. Create `scripts/add-index-html-links.sh` based on the implementation approach -2. Test thoroughly on a local build to verify link transformations -3. Update `config/siemens-internal/README.md` to document the new build step -4. Verify the transformed site works on the Siemens internal server +This solution has been implemented. The script is at `_scripts/add-index-html-links.sh` and the build steps are documented in `config/siemens-internal/README.md`. diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 560328904a2..8c117baca50 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -25,42 +25,36 @@ Example of the old bug: ### 2. Pretty URLs Not Supported -The Siemens internal server does not serve Hugo's default "pretty URLs" (like `/page/` resolving to `/page/index.html`). To work around this, use `uglyURLs = true`, which changes how Hugo generates URLs in the HTML: +The Siemens internal server does not serve Hugo's default "pretty URLs" (like `/page/` resolving to `/page/index.html`). `uglyURLs = true` helps, but Hugo still generates many directory-style links (ending with `/`) in navigation menus, breadcrumbs, and table-of-contents entries. -* **Without uglyURLs**: Links like `` rely on the server resolving the directory to `index.html` -* **With uglyURLs**: Links explicitly include `/index.html` where needed, ensuring compatibility with servers that don't automatically serve directory indexes - -Note: The file structure remains the same (directories with `index.html` files inside). The setting only affects how URLs are written in the generated HTML. +A post-processing script rewrites all remaining directory-style `href` links to include `/index.html` explicitly. ## The Solution -Configure Hugo with the appropriate settings for deep URL deployment: +Configure Hugo with the appropriate settings for deep URL deployment, then run the post-processing script: 1. **Set the full baseURL** including the deep path 2. **Enable `canonifyURLs = true`** to convert all root-relative URLs to use the baseURL -3. **Enable `uglyURLs = true`** to ensure proper URL resolution on servers without automatic directory index serving +3. **Enable `uglyURLs = true`** to reduce (but not eliminate) directory-style links 4. **Use relative font paths** in CSS (`../fonts/` instead of `/fonts/`) to work across all environments - -This approach: - -* ✅ Requires no changes to templates or Markdown content -* ✅ No post-processing or file duplication needed (as of Hugo v0.156.0+) -* ✅ Works for all images, fonts, and page links automatically -* ✅ Simple to maintain +5. **Run `add-index-html-links.sh`** to rewrite remaining `href=".../"` links to `href=".../index.html"` ## How to Build -Run this command from the repository root: +Run these commands from the repository root: ```bash # Build the site with the siemens-internal environment hugo --environment siemens-internal --cleanDestinationDir + +# Rewrite directory-style links to include index.html +# Pass the baseURL so that canonifyURLs-expanded internal links are also rewritten +bash _scripts/add-index-html-links.sh public \ + https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ ``` The built site will be in the `public/` directory, ready for deployment to the Siemens internal portal. -**Note**: The `scripts/fix-siemens-paths.sh` script is kept for backward compatibility but is no longer needed with Hugo v0.156.0+. - ## Configuration Files ### Hugo.toml @@ -70,11 +64,17 @@ Sets the baseURL and enables: * `canonifyURLs = true` to handle the deep deployment path * `uglyURLs = true` to ensure proper URL resolution on the Siemens server -### Scripts/fix-siemens-paths.sh +### _scripts/add-index-html-links.sh + +Rewrites all `href=".../"` directory-style links in the built HTML to `href=".../index.html"` so the Siemens server can serve them without automatic directory index support. Run this after every Hugo build. + +Skips external links, anchor links, links that already end in `.html`, and print URLs. + +### _scripts/fix-siemens-paths.sh -**Legacy script** - kept for backward compatibility but no longer needed with Hugo v0.156.0+. +**Legacy script** — kept for backward compatibility but no longer needed with Hugo v0.156.0+. -This script was previously used to work around a Hugo bug where `canonifyURLs` generated doubled paths for CSS and JS files. The bug has been fixed, and the script now simply confirms that no post-processing is needed. +Previously used to work around a Hugo bug where `canonifyURLs` generated doubled paths for CSS and JS files. The bug has been fixed, and the script now only prints a confirmation message. ## Technical Details @@ -108,6 +108,5 @@ If the Siemens deployment URL changes, update the `baseURL` in `config/siemens-i 1. **Using relativeURLs**: Breaks the landing page images and requires template changes 2. **Path-only baseURL**: Requires web server configuration and does not work with direct file access 3. **Template modifications**: Requires maintaining custom versions of Docsy theme files -4. **HTML post-processing**: Requires parsing and modifying thousands of HTML files (slower and more complex) -The current solution is the simplest and most maintainable approach. +The current solution (Hugo configuration plus a focused post-processing script) is the simplest and most maintainable approach. From 5f5ea1da0b888858c75f245ee135a4c317f805b0 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Tue, 25 Aug 2026 10:51:59 +0200 Subject: [PATCH 12/15] Include _print pages in index.html rewriting and clarify base URL requirement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the _print exclusion from add-index-html-links.sh — _print pages have index.html files and need the same rewriting as the rest of the site. Updates README to make clear the base URL argument is required for siemens-internal builds, where canonifyURLs expands all internal links to absolute URLs that the script would otherwise treat as external. Co-Authored-By: Claude Sonnet 4.6 --- _scripts/add-index-html-links.sh | 6 +----- config/siemens-internal/INDEX-HTML-WORKAROUND.md | 1 - config/siemens-internal/README.md | 6 ++++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/_scripts/add-index-html-links.sh b/_scripts/add-index-html-links.sh index 250216f62fa..3d94d4145d6 100644 --- a/_scripts/add-index-html-links.sh +++ b/_scripts/add-index-html-links.sh @@ -12,7 +12,6 @@ # - External links (contain :// but do not start with base-url) # - Anchor-only links starting with # # - Links already ending in .html or .htm -# - Print URLs containing /_print/ # # Usage: bash _scripts/add-index-html-links.sh [public-dir] [base-url] # Default public-dir: public @@ -52,12 +51,11 @@ def rewrite_href(m): if not (base_url and url.startswith(base_url)): return m.group(0) - # Skip anchors, already-explicit file links, and print paths + # Skip anchors and already-explicit file links if ( url.startswith("#") or url.endswith(".html") or url.endswith(".htm") - or "/_print/" in url ): return m.group(0) @@ -67,8 +65,6 @@ def rewrite_href(m): count = 0 for path in Path(public_dir).rglob("*.html"): - if "/_print/" in str(path): - continue original = path.read_text(encoding="utf-8", errors="replace") updated = HREF_RE.sub(rewrite_href, original) if updated != original: diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md index 4e2f9b6a446..61f716bc0f8 100644 --- a/config/siemens-internal/INDEX-HTML-WORKAROUND.md +++ b/config/siemens-internal/INDEX-HTML-WORKAROUND.md @@ -56,7 +56,6 @@ The cleanest approach is to post-process the HTML files after Hugo builds them, ❌ **Anchor links**: `href="#section"` (unchanged) ❌ **File links**: `href=".../page.html"` (unchanged) ❌ **Protocol links**: `href="mailto:..."`, `href="javascript:..."` (unchanged) -❌ **Print URLs**: `href=".../_print/..."` (unchanged - print output works differently) ### Implementation Approach diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 8c117baca50..4a8bb409b64 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -47,8 +47,10 @@ Run these commands from the repository root: # Build the site with the siemens-internal environment hugo --environment siemens-internal --cleanDestinationDir -# Rewrite directory-style links to include index.html -# Pass the baseURL so that canonifyURLs-expanded internal links are also rewritten +# Rewrite directory-style links to include index.html. +# The second argument (the site's baseURL) is required: the siemens-internal build uses +# canonifyURLs=true, which expands all internal links to full absolute URLs. Without the +# baseURL argument, the script cannot tell internal links from external ones and skips them. bash _scripts/add-index-html-links.sh public \ https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ ``` From a4f96faff944f5d615ab005b5aceffdf69d3fae2 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Tue, 25 Aug 2026 13:26:23 +0200 Subject: [PATCH 13/15] Rewrite directory links with anchors to include index.html Updates add-index-html-links.sh to handle href values like /path/#anchor, which previously were not rewritten because the URL doesn't end with /. The script now splits off the fragment before checking and rewriting the path, producing /path/index.html#anchor. Updates INDEX-HTML-WORKAROUND.md to document this case. Co-Authored-By: Claude Sonnet 4.6 --- _scripts/add-index-html-links.sh | 26 +++++++++++++------ .../siemens-internal/INDEX-HTML-WORKAROUND.md | 3 ++- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/_scripts/add-index-html-links.sh b/_scripts/add-index-html-links.sh index 3d94d4145d6..64da55347ff 100644 --- a/_scripts/add-index-html-links.sh +++ b/_scripts/add-index-html-links.sh @@ -8,10 +8,14 @@ # to expand all internal links to full absolute URLs using the baseURL. Pass that # baseURL as the second argument so those links are rewritten too. # +# Rewrites both plain directory links and directory links with anchors: +# href=".../path/" → href=".../path/index.html" +# href=".../path/#anchor" → href=".../path/index.html#anchor" +# # Skips: # - External links (contain :// but do not start with base-url) # - Anchor-only links starting with # -# - Links already ending in .html or .htm +# - Links already containing index.html or ending in .html/.htm # # Usage: bash _scripts/add-index-html-links.sh [public-dir] [base-url] # Default public-dir: public @@ -51,17 +55,23 @@ def rewrite_href(m): if not (base_url and url.startswith(base_url)): return m.group(0) - # Skip anchors and already-explicit file links - if ( - url.startswith("#") - or url.endswith(".html") - or url.endswith(".htm") - ): + # Skip anchor-only links + if url.startswith("#"): return m.group(0) + # Split off any fragment (e.g. /path/#anchor → path=/path/, fragment=#anchor) + fragment = "" + if "#" in url: + url, fragment = url.split("#", 1) + fragment = "#" + fragment + + # Skip already-explicit file links + if url.endswith(".html") or url.endswith(".htm"): + return f"{pre}{url}{fragment}{quote}" + if url.endswith("/"): url = url + "index.html" - return f"{pre}{url}{quote}" + return f"{pre}{url}{fragment}{quote}" count = 0 for path in Path(public_dir).rglob("*.html"): diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md index 61f716bc0f8..42263ef3ac5 100644 --- a/config/siemens-internal/INDEX-HTML-WORKAROUND.md +++ b/config/siemens-internal/INDEX-HTML-WORKAROUND.md @@ -51,9 +51,10 @@ The cleanest approach is to post-process the HTML files after Hugo builds them, ### What Gets Changed ✅ **Internal directory links**: `href=".../"` → `href=".../index.html"` +✅ **Internal directory links with anchors**: `href=".../#section"` → `href=".../index.html#section"` ❌ **External links**: `href="https://example.com/..."` (unchanged) -❌ **Anchor links**: `href="#section"` (unchanged) +❌ **Anchor-only links**: `href="#section"` (unchanged) ❌ **File links**: `href=".../page.html"` (unchanged) ❌ **Protocol links**: `href="mailto:..."`, `href="javascript:..."` (unchanged) From a4b3086a03acfbec4a956ebc1927cd326cb42326 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Fri, 18 Sep 2026 13:06:17 +0200 Subject: [PATCH 14/15] Add Siemens internal build-and-deploy workflow and supporting scripts - Add GitHub Actions workflow for manual build and deploy to Siemens Support Center S3 - Add deploy-to-siemens.sh script with dry-run support via DRY_RUN env var - Add .htmltest-siemens.yml pointing to the siemens-internal publishDir - Add content.xlsx metadata for Siemens Support Center upload structure - Set publishDir to Built/Mendix-Docs/public in hugo.toml to match expected S3 structure - Update README with workflow documentation and remove legacy pre-v0.156.0 content - Delete legacy fix-siemens-paths.sh and INDEX-HTML-WORKAROUND.md Co-Authored-By: Claude Sonnet 4.6 --- .../siemens-internal-build-and-deploy.yml | 116 +++++++++++++ .htmltest-siemens.yml | 50 ++++++ _scripts/deploy-to-siemens.sh | 41 +++++ _scripts/fix-siemens-paths.sh | 9 - .../siemens-internal/INDEX-HTML-WORKAROUND.md | 157 ------------------ config/siemens-internal/README.md | 63 +++---- config/siemens-internal/hugo.toml | 5 +- .../content.xlsx | Bin 0 -> 19907 bytes 8 files changed, 244 insertions(+), 197 deletions(-) create mode 100644 .github/workflows/siemens-internal-build-and-deploy.yml create mode 100644 .htmltest-siemens.yml create mode 100644 _scripts/deploy-to-siemens.sh delete mode 100644 _scripts/fix-siemens-paths.sh delete mode 100644 config/siemens-internal/INDEX-HTML-WORKAROUND.md create mode 100644 static/siemens-support-center-metadata/content.xlsx diff --git a/.github/workflows/siemens-internal-build-and-deploy.yml b/.github/workflows/siemens-internal-build-and-deploy.yml new file mode 100644 index 00000000000..03b6ec48995 --- /dev/null +++ b/.github/workflows/siemens-internal-build-and-deploy.yml @@ -0,0 +1,116 @@ +name: Siemens Internal Build and Deploy + +permissions: + contents: read + +on: + # Allow manual runs from the Actions tab for testing without pushing to production/development + workflow_dispatch: + inputs: + dry_run: + description: 'Perform a dry run - do not upload any data' + required: true + default: true + type: boolean + +jobs: + build: + runs-on: ubuntu-22.04 + if: github.repository_owner == 'mendix' + steps: + - name: Checkout repo + uses: actions/checkout@v6 + with: + # 20000 commits required for Hugo to populate last-modified dates on pages + fetch-depth: 20000 + submodules: false + filter: blob:none + + - name: Set up Node.js + uses: actions/setup-node@v6 + with: + node-version: '24' + cache: 'npm' + cache-dependency-path: package-lock.json + + - name: Install dependencies + run: npm ci + + - name: Report Hugo config + run: ./node_modules/.bin/hugo config --environment siemens-internal + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.11' + + - name: Build with Hugo + run: | + mkdir -p Built/Mendix-Docs/public + set -o pipefail + ./node_modules/.bin/hugo --environment siemens-internal 2>&1 | \ + sed 's/.*│ EN.*/```\n&/; s/.*Cleaned.*/&\n```/' | tee hugo.log + + - name: Add index.html to directory links + run: | + bash _scripts/add-index-html-links.sh Built/Mendix-Docs/public \ + https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ + + - name: Run htmltest + # htmltest errors are treated as warnings — build continues regardless (matches Travis behaviour) + run: | + chmod +x ./htmltest/htmltest + set +o pipefail + ./htmltest/htmltest -conf .htmltest-siemens.yml 2>&1 | \ + sed 's/\o033\[[0-9;]*[A-Za-z]//g; s/^=\+$/\n&/' | tee -a hugo.log + if [ "${PIPESTATUS[0]}" -ne 0 ]; then + # add blank output line first as ::warning:: does not always trigger a warning annotation + echo " " + echo "::warning::htmltest found broken cross-references. See the Run htmltest step for details." + fi + + - name: Print build log to GitHub Summary + if: always() + run: cat hugo.log >> $GITHUB_STEP_SUMMARY + + - name: Upload public site artifact + uses: actions/upload-artifact@v7 + with: + name: public-site + path: Built + if-no-files-found: error + + deploy: + runs-on: ubuntu-22.04 + needs: build + # Only deployment-capable runs attach to a GitHub Environment. + environment: ${{ github.ref_name }} + steps: + - name: Checkout repo + uses: actions/checkout@v6 + with: + fetch-depth: 1 + + - name: Download public site artifact + uses: actions/download-artifact@v8 + with: + name: public-site + path: Built + + - name: Set DRY_RUN + # Set the DRY_RUN environmental variable to indicate if dry_run input is set to true. + run: | + if [ "${{ inputs.dry_run }}" = "false" ]; then + echo "DRY_RUN=" >> "$GITHUB_ENV" + else + echo "DRY_RUN=--dryrun" >> "$GITHUB_ENV" + fi + + - name: Upload to Siemens Support Center S3 + # Use bash script to upload site to Siemens Support Center S3 + # Use SSC secrets for Siemens Support Center - there are separate credentials for docs.mendix.com + run: bash _scripts/deploy-to-siemens.sh + env: + AWS_ACCESS_KEY_ID: ${{ secrets.SSC_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.SSC_AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.SSC_AWS_DEFAULT_REGION }} diff --git a/.htmltest-siemens.yml b/.htmltest-siemens.yml new file mode 100644 index 00000000000..3f8cd937f90 --- /dev/null +++ b/.htmltest-siemens.yml @@ -0,0 +1,50 @@ +# ========================== +# Configuration for HTMLTEST +# ========================== +# See documentation in repo: https://github.com/wjdp/htmltest +# Siemens-internal variant — points to the siemens-internal publishDir + +DirectoryPath: "./Built/Mendix-Docs/public" +DirectoryIndex: "index.html" +FileExtension: .html +# Do not check external files - will want to do this monthly or so - implement later +CheckExternal: false +CheckMailto: false +# Not checking scripts for speed - should be OK as generated through HUGO +CheckScripts: false +CheckTel: false +IgnoreAltMissing: true +IgnoreDirectoryMissingTrailingSlash: false +IgnoreDirs: +- "_includes" +- "_print" +- "attachments" +- "css" +- "favicons" +- "icons" +- "js" +- "scss" +- "webfonts" +IgnoreEmptyHref: true +IgnoreInternalEmptyHash: true +IgnoreInternalURLs: +- "/misc/js/script.js" +- "/js/" +# HUGO generates a lot of tags which don't need to be tested +IgnoreTagAttribute: "data-proofer-ignore" +# Ignore URLs which return a 401/403 authentication error - might want to check these ignored URLs occasionally to ensure they are still valid. +# NOTE DOUBLE \\ needed to escape special characters in the string +IgnoreURLs: +- "example.com" +- "support.mendix.com.*" +- "sapes5.sapdevcenter.com/sap/opu/odata/iwbep/GWSAMPLE_BASIC.*" +- "www.microsoft.com/en-us/download/details.aspx\\?id=11774" + +# ========================================================== +# Speed up using concurrent testing by changing flag to true +# Using 4 concurrent documents halves the processing time +# EXPERIMENTAL - REMOVE IF THERE ARE PROBLEMS +#=========================================================== + +TestFilesConcurrently: false +DocumentConcurrencylimit: 4 diff --git a/_scripts/deploy-to-siemens.sh b/_scripts/deploy-to-siemens.sh new file mode 100644 index 00000000000..f7de83533c3 --- /dev/null +++ b/_scripts/deploy-to-siemens.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +set -ev + +BUCKET=scp-prod-source +SIEMENS_EMAIL=mark.van.ments@siemens.com +RELEASE_ID=PL20260323299104942 +LANG_CODE=en-US +TARGETAWSBUCKET=$BUCKET/$SIEMENS_EMAIL/$RELEASE_ID/$LANG_CODE/ + +echo "Deploying to Siemens AWS bucket $TARGETAWSBUCKET" + + + +mkdir -p Built/Mendix-Docs/.meta +cp static/siemens-support-center-metadata/content.xlsx Built/Mendix-Docs/.meta/ + +cd Built +pwd +ls +# the AWS CLI is part of the standard GitHub runner +aws --version + +# Requires the following environment variables (set as GitHub Actions secrets): +# AWS_ACCESS_KEY_ID +# AWS_SECRET_ACCESS_KEY +# AWS_DEFAULT_REGION +# +# HUGO creates new files with a newer timestamp except those in the /static folder +# so this will always push all the html, but only changed /static files. +# +# Need to use old method - or a new method to reduce number of docs transferred. +# see https://stackoverflow.com/questions/1964470/whats-the-equivalent-of-subversions-use-commit-times-for-git/13284229#13284229 for a possibility +# +start=$SECONDS +echo "Starting sync to AWS" +aws s3 sync . s3://$TARGETAWSBUCKET --delete --only-show-errors --exclude "*.png" $DRY_RUN # sync all files except png files +aws s3 sync . s3://$TARGETAWSBUCKET --delete --only-show-errors --size-only --exclude "*" --include "*.png" $DRY_RUN # sync all png files +echo "Upload to AWS took $((SECONDS - start)) seconds" + +exit 0 \ No newline at end of file diff --git a/_scripts/fix-siemens-paths.sh b/_scripts/fix-siemens-paths.sh deleted file mode 100644 index 42673ae6d59..00000000000 --- a/_scripts/fix-siemens-paths.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -# Post-processing script for Siemens internal deployment -# NOTE: As of Hugo v0.156.0, the doubled-path bug has been fixed. -# This script is kept for backwards compatibility but no longer performs any actions. - -echo "Siemens internal deployment post-processing..." -echo "✓ Hugo v0.156.0+ correctly handles deep baseURL paths" -echo "✓ No file copying needed - all asset references are correct" -echo "Done!" diff --git a/config/siemens-internal/INDEX-HTML-WORKAROUND.md b/config/siemens-internal/INDEX-HTML-WORKAROUND.md deleted file mode 100644 index 42263ef3ac5..00000000000 --- a/config/siemens-internal/INDEX-HTML-WORKAROUND.md +++ /dev/null @@ -1,157 +0,0 @@ -# Adding index.html to Directory Links for Siemens Deployment - -## The Problem - -The Siemens internal web server does not automatically serve `index.html` when a directory URL is requested. When a user or browser requests `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/refguide/`, the server does not automatically serve the `refguide/index.html` file. - -Hugo's `uglyURLs = true` setting helps by making URLs explicit where possible, but Hugo still generates many directory-style links (ending with `/`) throughout the site, particularly in: - -* Navigation menus -* Breadcrumbs -* Internal page links -* Table of contents - -## Recommended Solution: Post-Processing - -The cleanest approach is to post-process the HTML files after Hugo builds them, rewriting directory links to explicitly include `/index.html`. - -### How It Works - -1. **Hugo builds the site normally** using the siemens-internal environment -2. **Post-processing script runs** and: - * Scans all HTML files in the `public/` directory - * Identifies internal links that end with `/` (directory links) - * Rewrites them to end with `/index.html` - * Preserves external links, anchor links, and explicit file references unchanged - -3. **Resulting HTML has explicit paths** that the Siemens server can serve correctly - -### Link Transformation Examples - -**Navigation links:** - -```html - - - - - -``` - -**Breadcrumb links:** - -```html - - - - - -``` - -### What Gets Changed - -✅ **Internal directory links**: `href=".../"` → `href=".../index.html"` -✅ **Internal directory links with anchors**: `href=".../#section"` → `href=".../index.html#section"` - -❌ **External links**: `href="https://example.com/..."` (unchanged) -❌ **Anchor-only links**: `href="#section"` (unchanged) -❌ **File links**: `href=".../page.html"` (unchanged) -❌ **Protocol links**: `href="mailto:..."`, `href="javascript:..."` (unchanged) - -### Implementation Approach - -The post-processing can be implemented using standard text processing tools: - -**Option 1: Using sed (bash)** - -* Fast and simple for straightforward pattern matching -* May require careful escaping of special characters -* Best for simple, well-defined patterns - -**Option 2: Using a scripting language (Python/Node.js)** - -* More reliable HTML parsing -* Better handling of edge cases -* Can use proper HTML parsers (BeautifulSoup, cheerio, etc.) -* More maintainable for complex transformations - -**Option 3: Using specialized tools (htmlq, pup)** - -* Purpose-built for HTML manipulation -* Balance between sed simplicity and full scripting power - -### Integration with Build Process - -Update the build workflow to: - -```bash -# Build the site -hugo --environment siemens-internal --cleanDestinationDir - -# Post-process to add index.html to directory links -bash _scripts/add-index-html-links.sh public \ - https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ -``` - -The script is kept in `_scripts/` alongside the existing (now no-op) `fix-siemens-paths.sh`. - -### Advantages - -* ✅ **Non-invasive**: Does not require modifying Hugo templates or Docsy theme files -* ✅ **Environment-specific**: Only affects siemens-internal builds -* ✅ **Maintainable**: Clear separation between Hugo build and Siemens-specific processing -* ✅ **Reversible**: Disable by skipping the post-processing step -* ✅ **Hugo-version independent**: Works regardless of Hugo updates -* ✅ **Preserves other outputs**: Standard HTML and print versions remain unchanged - -### Disadvantages - -* ❌ **Build-time overhead**: Adds processing time (likely 5-30 seconds depending on implementation) -* ❌ **Two-step process**: Requires running a script after Hugo build -* ❌ **Pattern matching complexity**: Must identify which links to transform precisely - -## Alternative Solution: Hugo Render Hooks and Custom Layouts - -Instead of post-processing, modify Hugo's rendering behavior at build time. - -### How It Works - -1. **Create custom render hooks** for Markdown links in `.layouts/_default/_markup/` -2. **Override navigation partials** from Docsy theme to append `/index.html` -3. **Configure hooks** to only apply for siemens-internal environment - -### Required Changes - -* Copy Docsy navigation partial files to local `layouts/` directory -* Modify link generation logic to append `/index.html` to directory URLs -* Create Markdown render hooks for content links -* Add conditional logic to check environment - -### Advantages - -* ✅ **Build-time only**: No post-processing step required -* ✅ **Single build command**: Just run `hugo --environment siemens-internal` - -### Disadvantages - -* ❌ **More invasive**: Requires copying and modifying theme files -* ❌ **Maintenance burden**: Must update custom layouts when Docsy updates -* ❌ **Complexity**: Multiple layout files need modification -* ❌ **Testing required**: Must verify all link types work correctly -* ❌ **Harder to isolate**: Siemens-specific logic mixed with layout code - -## Recommendation - -Use the **post-processing approach** because: - -1. Hugo v0.156.0 already eliminated the need for the previous doubled-path workaround, and the post-processing approach proved straightforward to implement -2. The script can be kept simple and focused on one task -3. It does not require maintaining customized Docsy theme files -4. It is easier to test, debug, and modify -5. It keeps the Siemens-specific logic isolated and well-documented - -The slight increase in build time is acceptable for a deployment that happens infrequently, and the maintainability benefits outweigh the minor inconvenience of a two-step build process. - -## Status - -This solution has been implemented. The script is at `_scripts/add-index-html-links.sh` and the build steps are documented in `config/siemens-internal/README.md`. diff --git a/config/siemens-internal/README.md b/config/siemens-internal/README.md index 4a8bb409b64..765322588d0 100644 --- a/config/siemens-internal/README.md +++ b/config/siemens-internal/README.md @@ -10,20 +10,7 @@ The site is deployed at: https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ ``` -## The Problems - -### 1. Deep URL Path (Fixed in Hugo v0.156.0+) - -**Historical Issue**: Earlier versions of Hugo had a bug where `canonifyURLs` generated doubled paths for CSS and JS assets when deploying to a deep URL path (not at the domain root). - -Example of the old bug: - -* Expected: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/scss/main.css` -* Generated: `https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/documentation/internal/PL20260323299104942/en-US/public/scss/main.css` - -**Status**: ✅ This issue was fixed in Hugo v0.156.0. The `canonifyURLs` setting now correctly handles deep baseURL paths without generating doubled paths. - -### 2. Pretty URLs Not Supported +## The Problem: Pretty URLs Not Supported The Siemens internal server does not serve Hugo's default "pretty URLs" (like `/page/` resolving to `/page/index.html`). `uglyURLs = true` helps, but Hugo still generates many directory-style links (ending with `/`) in navigation menus, breadcrumbs, and table-of-contents entries. @@ -45,24 +32,51 @@ Run these commands from the repository root: ```bash # Build the site with the siemens-internal environment -hugo --environment siemens-internal --cleanDestinationDir +Hugo --environment siemens-internal --cleanDestinationDir # Rewrite directory-style links to include index.html. # The second argument (the site's baseURL) is required: the siemens-internal build uses # canonifyURLs=true, which expands all internal links to full absolute URLs. Without the # baseURL argument, the script cannot tell internal links from external ones and skips them. -bash _scripts/add-index-html-links.sh public \ +bash _scripts/add-index-html-links.sh Built/Mendix-Docs/public \ https://internal.docs.sw.siemens.com/documentation/internal/PL20260323299104942/en-US/Mendix-Docs/public/ ``` -The built site will be in the `public/` directory, ready for deployment to the Siemens internal portal. +The built site will be in `Built/Mendix-Docs/public/`, ready for deployment to the Siemens internal portal. + +## GitHub Actions Workflow + +The `siemens-internal-build-and-deploy` workflow (`.github/workflows/siemens-internal-build-and-deploy.yml`) automates the build and deployment to the Siemens Support Center S3 bucket. It is triggered manually from the Actions tab and has a single input: + +* **`dry_run`** (Boolean, default `true`): when `true`, the S3 sync runs with `--dryrun` and no files are uploaded. Set to `false` to perform a real deployment. + +The workflow runs in two jobs: + +### Build Job + +1. Checks out the repository (with 20,000 commits to populate last-modified dates). +2. Installs Node.js dependencies and Python. +3. Builds the site with Hugo using the `siemens-internal` environment, outputting to `Built/Mendix-Docs/public/`. +4. Runs `add-index-html-links.sh` to rewrite directory-style links. +5. Runs htmltest (using `.htmltest-siemens.yml`) to check for broken cross-references; failures are treated as warnings. +6. Uploads the entire `Built/` directory as a build artifact. + +### Deploy Job + +1. Checks out the repository (for access to scripts and metadata files). +2. Downloads the `Built/` artifact from the build job. +3. Sets the `DRY_RUN` environment variable to `--dryrun` (default) or an empty string based on the `dry_run` input. +4. Runs `_scripts/deploy-to-siemens.sh`, which copies `content.xlsx` into `Built/Mendix-Docs/.meta/` and syncs the `Built/` directory to the Siemens Support Center S3 bucket using the `SSC_AWS_*` secrets. + +The workflow is guarded by `if: github.repository_owner == 'mendix'` on the build job, so it will not run in forks. ## Configuration Files -### Hugo.toml +### hugo.toml -Sets the baseURL and enables: +Sets the baseURL, the publish directory, and enables: +* `publishDir = "Built/Mendix-Docs/public"` to match the structure expected by the Siemens Support Center * `canonifyURLs = true` to handle the deep deployment path * `uglyURLs = true` to ensure proper URL resolution on the Siemens server @@ -72,12 +86,6 @@ Rewrites all `href=".../"` directory-style links in the built HTML to `href="... Skips external links, anchor links, links that already end in `.html`, and print URLs. -### _scripts/fix-siemens-paths.sh - -**Legacy script** — kept for backward compatibility but no longer needed with Hugo v0.156.0+. - -Previously used to work around a Hugo bug where `canonifyURLs` generated doubled paths for CSS and JS files. The bug has been fixed, and the script now only prints a confirmation message. - ## Technical Details ### Why CanonifyURLs? @@ -96,11 +104,6 @@ Font files are referenced in CSS using relative paths (`../fonts/`, `../webfonts * Does not require environment-specific processing * Avoids issues with deep URL paths -### Hugo Version Requirements - -* **Hugo v0.156.0 or later** is required for correct handling of deep baseURL paths with `canonifyURLs` -* Earlier versions had a bug where `canonifyURLs` would generate doubled paths for CSS and JS assets - ## Updating the Deployment Path If the Siemens deployment URL changes, update the `baseURL` in `config/siemens-internal/hugo.toml`. diff --git a/config/siemens-internal/hugo.toml b/config/siemens-internal/hugo.toml index 37370ec4398..ab1d945fa4b 100644 --- a/config/siemens-internal/hugo.toml +++ b/config/siemens-internal/hugo.toml @@ -14,4 +14,7 @@ canonifyURLs = true enableRobotsTXT = false # Enable ugly URLs to help links work on the Siemens site -uglyURLs = true \ No newline at end of file +uglyURLs = true + +# Publish siemens-internal to "Built/Mendix-Docs/public" so we can add meta data and upload Mendix-Docs to match expected structure of Siemens Support Center +publishDir = "Built/Mendix-Docs/public" \ No newline at end of file diff --git a/static/siemens-support-center-metadata/content.xlsx b/static/siemens-support-center-metadata/content.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..7d8c0c183b66d4ef05a86932317aee3f1f02d1c0 GIT binary patch literal 19907 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 NpZ)tM4w0YV{ttpSKIQ-b literal 0 HcmV?d00001 From f69cf5951a48f15bc87f0e2e02eb8219402811e8 Mon Sep 17 00:00:00 2001 From: MarkvanMents Date: Fri, 18 Sep 2026 16:06:40 +0200 Subject: [PATCH 15/15] Fix deploy job environment and shell script debug output - Remove GitHub Environment from deploy job so repository-level secrets are used - Switch deploy script from set -ev to set -ex for expanded variable output Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/siemens-internal-build-and-deploy.yml | 5 ++--- _scripts/deploy-to-siemens.sh | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/siemens-internal-build-and-deploy.yml b/.github/workflows/siemens-internal-build-and-deploy.yml index 03b6ec48995..d98b7edb25f 100644 --- a/.github/workflows/siemens-internal-build-and-deploy.yml +++ b/.github/workflows/siemens-internal-build-and-deploy.yml @@ -61,7 +61,7 @@ jobs: run: | chmod +x ./htmltest/htmltest set +o pipefail - ./htmltest/htmltest -conf .htmltest-siemens.yml 2>&1 | \ + ./htmltest/htmltest --conf .htmltest-siemens.yml 2>&1 | \ sed 's/\o033\[[0-9;]*[A-Za-z]//g; s/^=\+$/\n&/' | tee -a hugo.log if [ "${PIPESTATUS[0]}" -ne 0 ]; then # add blank output line first as ::warning:: does not always trigger a warning annotation @@ -83,8 +83,6 @@ jobs: deploy: runs-on: ubuntu-22.04 needs: build - # Only deployment-capable runs attach to a GitHub Environment. - environment: ${{ github.ref_name }} steps: - name: Checkout repo uses: actions/checkout@v6 @@ -109,6 +107,7 @@ jobs: - name: Upload to Siemens Support Center S3 # Use bash script to upload site to Siemens Support Center S3 # Use SSC secrets for Siemens Support Center - there are separate credentials for docs.mendix.com + # Secrets are restored at the Repository level. run: bash _scripts/deploy-to-siemens.sh env: AWS_ACCESS_KEY_ID: ${{ secrets.SSC_AWS_ACCESS_KEY_ID }} diff --git a/_scripts/deploy-to-siemens.sh b/_scripts/deploy-to-siemens.sh index f7de83533c3..1f279266905 100644 --- a/_scripts/deploy-to-siemens.sh +++ b/_scripts/deploy-to-siemens.sh @@ -1,6 +1,6 @@ #!/bin/bash -set -ev +set -ex BUCKET=scp-prod-source SIEMENS_EMAIL=mark.van.ments@siemens.com