Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 71 additions & 1 deletion docs/css/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ body {
}

.md-typeset h1 {
margin: 0 0 1rem;
margin: 0 0 0.5rem;
font-size: 24px;
line-height: 34px;
}
Expand Down Expand Up @@ -649,3 +649,73 @@ div.path {
[hidden] {
display: none !important;
}

.page-actions {
display: none;
gap: 0;
margin: 12px 0 0 0;
padding-bottom: 6px;
border-bottom: 1px solid var(--ibexa-snow);
}

.md-typeset .page-action-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 12px;
background: transparent;
border: none;
text-decoration: none;
color: var(--ibexa-dusk-black);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: color 0.15s ease;
white-space: nowrap;
position: relative;
}

.page-action-btn+.page-action-btn::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
height: 16px;
width: 1px;
background: var(--ibexa-snow);
}

.page-action-btn svg {
width: 14px;
height: 14px;
fill: currentColor;
flex-shrink: 0;
}

.page-action-btn.external::after,
.page-action-btn[rel="nofollow"]::after {
display: none;
}

@media (max-width: 768px) {
.page-actions {
gap: 0;
}
}

.page-actions--visible {
display: flex;
}

.page-action-btn.page-action-btn--success {
background: #d4edda;
border-color: #c3e6cb;
color: #155724;
}

.page-action-btn.page-action-btn--info {
background: color-mix(in srgb, var(--turquoise-pearl) 25%, white);
border-color: color-mix(in srgb, var(--turquoise-pearl) 40%, white);
color: var(--sherpa-blue);
}
1 change: 0 additions & 1 deletion docs/css/release-notes.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/personalization/api_reference/api_reference.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Explore Personalization API sets that let you manage item data, track events, combine tracking data with users and render recommendations.
page_type: landing_page
exclude_from_llmstxt: true
---

# Personalization API
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/api_reference/content_api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Personalization server can use external information about the items. Use HTTP methods to create, update or get items from the data store.
exclude_from_llmstxt: true
---

# Content API
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/api_reference/recommendation_api.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Use HTTP GET request method to render recommendations.
month_change: false
exclude_from_llmstxt: true
---

# Recommendation API
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/api_reference/tracking_api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Allows to track items based on an ID. It covers many content types with the same ID configured for tracking.
exclude_from_llmstxt: true
---

# Tracking API
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/api_reference/user_api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Use HTTP methods to correlate metadata with user data and combine users into clusters of certain type.
exclude_from_llmstxt: true
---

# User API
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/attribute_search_in_elasticsearch.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Attribute search uses Elasticsearch database to display dynamically taken values in scenario and model previews.
exclude_from_llmstxt: true
---

# Attribute search in Elasticsearch database
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/enable_personalization.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Configure your project files to enable Personalization and set up items you want to track.
month_change: false
exclude_from_llmstxt: true
---

# Enable Personalization
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/how_it_works.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Integrate recommendation service into your website.
exclude_from_llmstxt: true
---

# How Personalization works
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Use historical user tracking data to build user profiles and generate better recommendations.
exclude_from_llmstxt: true
---

# Importing historical user tracking data
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/integrate_recommendation_service.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Integrate recommendation service into your website.
month_change: false
exclude_from_llmstxt: true
---

# Integrate recommendation service
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/legacy_recommendation_api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: An old method of fetching recommendations from the system using recommendation requests.
exclude_from_llmstxt: true
---

# Legacy Recommendation API
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/personalization.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Personalization tracks consumed content and suggests targeted content to your website visitors.
page_type: landing_page
exclude_from_llmstxt: true
---

# Personalization
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/personalization_guide.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Discover Personalization - a cloud-based service that tracks and analyzes customer behaviors.
exclude_from_llmstxt: true
---

# Personalization product guide
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/recommendation_integration.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
description: Methods for REST call with Personalization server.
exclude_from_llmstxt: true
---

# Recommendation integration
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/tracking_integration.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: See the methods of event tracking integration using tracking from server or from client-side.
month_change: false
exclude_from_llmstxt: true
---

# Tracking integration
Expand Down
1 change: 1 addition & 0 deletions docs/personalization/tracking_with_ibexa-tracker.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
description: Integrate tracking with a Google-style JavaScript.
month_change: false
exclude_from_llmstxt: true
---

# Track events with ibexa-tracker.js
Expand Down
144 changes: 144 additions & 0 deletions hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
"""
MkDocs hooks for Ibexa developer documentation.

Automatically keeps the llmstxt plugin's ``sections`` config in sync with the ``nav`` defined in ``mkdocs.yml``
"""

from __future__ import annotations

import re
from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from mkdocs.config.defaults import MkDocsConfig

FRONTMATTER_EDITION_DISPLAY = {
"lts-update": "LTS Update",
"experience": "Experience",
"commerce": "Commerce",
"headless": "Headless",
}


def on_config(config: "MkDocsConfig") -> None:
"""Populate llmstxt sections from nav before the build starts.

The llmstxt plugin reads ``config.sections`` in its ``on_files`` event,
which fires after ``on_config``, so injecting here is the right place.
"""
nav = config.get("nav")
if not nav:
return

llmstxt = config["plugins"].get("llmstxt")
if llmstxt is None:
return

import sys
_here = Path(__file__).parent
if str(_here) not in sys.path:
sys.path.insert(0, str(_here))
from update_llmstxt_config import convert_nav_to_llmstxt_sections

docs_dir = Path(config["docs_dir"])
llmstxt.config.sections = convert_nav_to_llmstxt_sections(nav, docs_dir)


def on_page_content(html: str, *, page: "Page", config: "MkDocsConfig", **kwargs) -> None:

Check warning on line 48 in hooks.py

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused function parameter "html".

See more on https://sonarcloud.io/project/issues?id=ezsystems_developer-documentation&issues=AZ43ep1yBrFcw9uEOOza&open=AZ43ep1yBrFcw9uEOOza&pullRequest=3161
"""Reformat the Markdown content generated by the llmstxt plugin for this page.

Hooks run after plugins for every event, so at this point the llmstxt
plugin has already generated Markdown and stored it in ``_md_pages``.
We reformat here so the plugin writes the corrected content in its own
``on_post_build`` (which also runs before ours, for the same reason).
"""
llmstxt = config["plugins"].get("llmstxt")
if llmstxt is None:
return

src_uri = page.file.src_uri
page_info = llmstxt._md_pages.get(src_uri)
if page_info is None:
return

content = page_info.content
content = _inject_edition_badges(content, page, config)
reformatted = _renumber_ordered_lists(content)
if reformatted != content:
llmstxt._md_pages[src_uri] = page_info._replace(content=reformatted)
elif content != page_info.content:
llmstxt._md_pages[src_uri] = page_info._replace(content=content)


def on_post_build(*, config: "MkDocsConfig", **kwargs) -> None:
"""No-op — reformatting is done per-page in on_page_content."""


def _inject_edition_badges(content: str, page: "Page", config: "MkDocsConfig") -> str:
"""Insert 'Editions: X, Y' line after the first h1 heading, from frontmatter."""
src_path = Path(config["docs_dir"]) / page.file.src_path
try:
from mkdocs.utils import meta as mkdocs_meta
with open(src_path, encoding="utf-8") as f:
raw = f.read()
_, frontmatter = mkdocs_meta.get_data(raw)
except Exception:
return content

def _to_list(value):
if isinstance(value, list):
return value
if isinstance(value, str):
return value.split()
return []

edition = frontmatter.get("edition")
editions = frontmatter.get("editions") or []
all_editions = _to_list(edition) + _to_list(editions)
display = [FRONTMATTER_EDITION_DISPLAY.get(e, e) for e in all_editions if e]
if not display:
return content

badge_line = "Editions: " + ", ".join(display)

# Insert after the first h1 (# ...) line
lines = content.split("\n")
for i, line in enumerate(lines):
if line.startswith("# "):
lines.insert(i + 1, "")
lines.insert(i + 2, badge_line)
return "\n".join(lines)

return badge_line + "\n\n" + content


def _renumber_ordered_lists(content: str) -> str:
"""Replace repeated '1.' list markers with sequential numbers (1. 2. 3. ...)."""
lines = content.split("\n")
result = []
counters: list[int] = [] # stack of counters per indent level

for line in lines:
m = re.match(r'^(\s*)1\. (.*)$', line)
if m:
indent = len(m.group(1))
level = indent // 2 # assume 2-space indent per level

# Trim deeper levels from the stack
while len(counters) > level + 1:
counters.pop()
# Extend stack if we went deeper
while len(counters) <= level:
counters.append(0)

counters[level] += 1
result.append(f"{m.group(1)}{counters[level]}. {m.group(2)}")
else:
# Both blank lines and non-list lines reset the counter stack,
# since a blank line always separates distinct markdown lists.
counters.clear()
result.append(line)

return "\n".join(result)

Loading
Loading