Skip to content

Conversation

@spliffone
Copy link
Member

@spliffone spliffone commented Oct 31, 2025

Describe in detail what your merge request does and why. Add relevant
screenshots and reference related issues via Closes #XY or Related to #XY.


Summary by CodeRabbit

  • New Features

    • Improved markdown inclusion: add a new configuration option to enable relative-path resolution for included markdown files so references resolve correctly from the current page location.
    • Page-aware resolution: included file paths are now resolved relative to the active page, allowing more flexible organization of documentation content.
  • Documentation

    • Updated config to expose the new option for markdown includes.

✏️ Tip: You can customize this high-level summary in your review settings.

@spliffone spliffone requested a review from a team as a code owner October 31, 2025 12:58
@github-actions
Copy link

@spliffone spliffone force-pushed the docs/build-relative-examples-path branch 2 times, most recently from 4a92e78 to 6d544ec Compare October 31, 2025 13:28
@spike-rabbit spike-rabbit self-assigned this Nov 3, 2025
Copy link
Member

@spike-rabbit spike-rabbit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to work, but please remove EXAMPLES_BASE env var from the build-and-test.yaml

@spliffone spliffone force-pushed the docs/build-relative-examples-path branch from 6d544ec to b8495d6 Compare November 25, 2025 09:44
@coderabbitai
Copy link

coderabbitai bot commented Nov 25, 2025

Walkthrough

Adds page-aware relative path resolution to the element-docs markdown extension: a new md_file config key is added to mkdocs.yml, and the extension now passes the current page context into the example preprocessor to resolve relative examples_base paths.

Changes

Cohort / File(s) Summary
Configuration
mkdocs.yml
Adds md_file: !relative under markdown_extensions -> element-docs to provide the current page context to the extension.
Extension logic
projects/element-docs-builder/md_extension_element_docs/extension.py
Adds Path and urlparse imports; extends ElementDocsExtension config with 'md_file'; extendMarkdown extracts page URL and passes it to ElementExamplePreProcessor; updates ElementExamplePreProcessor.__init__() signature to accept page and resolves relative examples_base using page depth.

Sequence Diagram

sequenceDiagram
    participant MkDocs as mkdocs.yml (config)
    participant Ext as ElementDocsExtension
    participant Prep as ElementExamplePreProcessor
    participant FS as Filesystem/Path

    MkDocs->>Ext: load `markdown_extensions.element-docs.md_file`
    Ext->>Ext: extract page URL from `md_file`
    Ext->>Prep: initialize preprocessor with `examples_base` + page
    Prep->>FS: compute relative path (use page depth if no URL scheme)
    FS-->>Prep: resolved examples_base path
    Prep->>Ext: process markdown includes with resolved paths
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Check ElementExamplePreProcessor.__init__ signature change is propagated to all initializers.
  • Verify md_file extraction (format, edge cases) and urlparse handling for URL vs relative path.
  • Validate path-depth computation logic (../ prefixing) for various page paths and nested directories.

Poem

🐰 I sniff the page where I belong,
I hop through folders, singing a song,
Relative trails now find their way,
Markdown blossoms from night to day,
Hooray — the docs and rabbit play! 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding relative path resolution for preview examples in the documentation build system.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/build-relative-examples-path

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a031159 and b8495d6.

📒 Files selected for processing (2)
  • mkdocs.yml (1 hunks)
  • projects/element-docs-builder/md_extension_element_docs/extension.py (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
projects/element-docs-builder/md_extension_element_docs/extension.py (1)
projects/element-docs-builder/md_extension_element_docs_composer/extension.py (1)
  • extendMarkdown (20-25)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
mkdocs.yml (1)

236-239: Using !relative here is fine, but it ties you to MkDocs ≥ 1.5

md_file: !relative in markdown_extensions is a valid use of MkDocs’ !relative tag and gives the extension access to page-local context.(mkdocs.org)
However, it implicitly requires MkDocs 1.5+ and that element-docs is only used in that environment. If older MkDocs versions must remain supported, this will fail at config load time; otherwise, consider documenting the minimum MkDocs version in CONTRIBUTING/README so users understand the new requirement.

To double‑check compatibility across MkDocs versions you support, please confirm against the version matrix you target (e.g., CI jobs) and adjust docs or pin MkDocs accordingly.

@spliffone spliffone force-pushed the docs/build-relative-examples-path branch from b8495d6 to cae9512 Compare November 27, 2025 21:52
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
projects/element-docs-builder/md_extension_element_docs/extension.py (1)

4-4: Remove unused Path import.

The Path class is imported but never used in the code. The relative path logic correctly uses string manipulation instead.

Apply this diff to remove the unused import:

-from pathlib import Path
 from typing import cast
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8495d6 and cae9512.

📒 Files selected for processing (2)
  • mkdocs.yml (1 hunks)
  • projects/element-docs-builder/md_extension_element_docs/extension.py (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • mkdocs.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (1)
projects/element-docs-builder/md_extension_element_docs/extension.py (1)

144-147: Config updates look good.

The md_file config description accurately reflects its purpose as a !relative helper for accessing the MkDocs config.

Comment on lines +104 to +110
url = urlparse(self.examples_base)
# If no scheme, we assume we need to build a relative path to the examples
if url.scheme == '':
# Number of non-empty segments in /foo/bar/ → 2, used as "../" depth
depth = len([s for s in self.page.strip('/').split('/') if s])
rel_prefix = '../' * depth
self.examples_base = f'{rel_prefix}{self.examples_base.lstrip("/")}'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for examples_base configuration in YAML files and check for relative paths

# Find all YAML files and search for examples_base
rg -n "examples_base" --type yaml -A 2 -B 2

# Also search in any Python config files
rg -n "examples_base" --type py -A 2 -B 2 | head -50

Repository: siemens/element

Length of output: 4506


Based on my verification, I can now provide the rewritten review comment. The original concern is valid and confirmed. The code comments at lines 130-131 explicitly mention the case where examples_base could be ../../../demo/index.html on a server, but the code doesn't normalize this input before prepending additional ../ segments based on page depth.

Relative path double-prepending is possible with the current logic.

The code at lines 104–110 will prepend additional ../ segments to any examples_base without a URL scheme. However, if examples_base is already a relative path (e.g., ../../../demo/index.html, as mentioned in the comments at lines 130–131), this results in double-prepending. For example, a page at /docs/reference/foo/ (depth 3) would transform ../../../demo/index.html into ../../../../../../../../../demo/index.html, potentially overshooting the target.

To fix this, either:

  • Normalize examples_base by removing leading ../ before applying the page-relative prefix, or
  • Document that examples_base must be an absolute path (e.g., /demo/index.html) or a bare relative path without ../ (e.g., demo/index.html), or
  • Use a proper path normalization library to resolve the final path correctly.
🤖 Prompt for AI Agents
In projects/element-docs-builder/md_extension_element_docs/extension.py around
lines 104-110, the code prepends a page-relative "../" prefix to examples_base
without handling cases where examples_base already starts with "../", causing
double-prepending; fix it by normalizing examples_base before prefixing—either
strip any leading "../" segments from self.examples_base (or convert leading
"./" to none) then prepend rel_prefix, or resolve the final path using a POSIX
path normalization/join (e.g., posixpath.join + posixpath.normpath) so multiple
"../" segments collapse correctly and the resulting relative path is normalized.

Comment on lines +152 to +159
# Extract current page path
md_file_cfg = self.config.get('md_file')[0]
mkdocs_config = getattr(md_file_cfg, 'config', None)
current_page = getattr(mkdocs_config, '_current_page', None)
page = getattr(current_page, 'abs_url', '') or ''
if hasattr(current_page, 'abs_url'):
page = current_page.abs_url
md.preprocessors.register(ElementExamplePreProcessor(self.config.get('examples_base')[0], page, md), 'element_example', 10)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix potential IndexError and remove redundant logic.

Two issues in the page extraction logic:

  1. Line 153 could raise IndexError if md_file is configured as an empty list. While unlikely in normal usage, defensive programming would check the list length first.

  2. Lines 156-158 contain redundant logic. Line 156 already extracts abs_url with a fallback to empty string using getattr. Lines 157-158 then repeat the same extraction with hasattr, overwriting the result. The second check is unnecessary.

Apply this diff to fix both issues:

 # Extract current page path
-md_file_cfg = self.config.get('md_file')[0]
+md_file_list = self.config.get('md_file', [''])
+md_file_cfg = md_file_list[0] if md_file_list else ''
 mkdocs_config = getattr(md_file_cfg, 'config', None)
 current_page = getattr(mkdocs_config, '_current_page', None)
 page = getattr(current_page, 'abs_url', '') or ''
-if hasattr(current_page, 'abs_url'):
-  page = current_page.abs_url
 md.preprocessors.register(ElementExamplePreProcessor(self.config.get('examples_base')[0], page, md), 'element_example', 10)
🤖 Prompt for AI Agents
In projects/element-docs-builder/md_extension_element_docs/extension.py around
lines 152 to 159, the code currently indexes self.config.get('md_file')[0]
without checking the list length and redundantly re-reads abs_url; change it to
first safely retrieve the md_file list, verify it contains at least one element
and bail or use a safe default if empty, then use mkdocs_config =
getattr(md_file_cfg, 'config', None) and current_page = getattr(mkdocs_config,
'_current_page', None) and set page = getattr(current_page, 'abs_url', '')
(remove the subsequent hasattr block), and finally register the preprocessor
using the safe page variable; ensure you do not assume md_file is non-empty to
avoid IndexError.

@github-actions
Copy link

Code Coverage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants