diff --git a/docs/css/custom.css b/docs/css/custom.css index fe9b85528a..eae77fe84e 100644 --- a/docs/css/custom.css +++ b/docs/css/custom.css @@ -158,7 +158,7 @@ body { } .md-typeset h1 { - margin: 0 0 1rem; + margin: 0 0 0.5rem; font-size: 24px; line-height: 34px; } diff --git a/llmstxt_preprocess.py b/llmstxt_preprocess.py new file mode 100644 index 0000000000..13b6a3a810 --- /dev/null +++ b/llmstxt_preprocess.py @@ -0,0 +1,68 @@ +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from bs4 import BeautifulSoup + + +def preprocess(soup: "BeautifulSoup", output: str) -> None: + """ + Preprocess HTML to improve markdown conversion. + + Converts card macro HTML structure into markdown lists with links + so they are preserved in the llms.txt output. + + Filters out release notes filter UI elements. + """ + # Remove release notes filter UI (checkboxes and labels) + # These are interactive filters, not content + filter_containers = soup.find_all("div", class_="release-notes-filters") + for container in filter_containers: + container.decompose() + + # Find all cards wrapper divs (these contain groups of cards) + cards_divs = soup.find_all("div", class_=lambda c: c and c.startswith("cards ")) + + for cards_div in cards_divs: + # Find all card-wrapper divs within this cards group + card_wrappers = cards_div.find_all("div", class_="card-wrapper") + + if not card_wrappers: + continue + + # Create a list to hold all the cards in this group + ul = soup.new_tag("ul") + + for card_wrapper in card_wrappers: + # Extract the link, title, and description from the card structure + link = card_wrapper.find("a", class_="card") + if not link: + continue + + href = link.get("href", "") + # Fix protocol-relative URLs + if href.startswith("//"): + href = "https:" + href + + title_elem = link.find("p", class_="title") + description_elem = link.find("p", class_="description") + + if not title_elem: + continue + + title = title_elem.get_text(strip=True) + description = description_elem.get_text(strip=True) if description_elem else "" + + # Create a list item with a link and description + li = soup.new_tag("li") + link_tag = soup.new_tag("a", href=href) + link_tag.string = title + li.append(link_tag) + + if description: + li.append(soup.new_string(" - ")) + li.append(soup.new_string(description)) + + ul.append(li) + + # Replace the entire cards div with the unordered list + cards_div.replace_with(ul) diff --git a/mkdocs.yml b/mkdocs.yml index a2082cc594..2f30560198 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,6 +2,7 @@ INHERIT: plugins.yml site_name: Developer Documentation repo_url: https://github.com/ibexa/documentation-developer +edit_uri: edit/5.0/docs/ site_url: https://doc.ibexa.co/en/latest/ copyright: "Copyright 1999-2026 Ibexa AS and others" validation: diff --git a/plugins.yml b/plugins.yml index 77c3fd4879..bcc5d4d049 100644 --- a/plugins.yml +++ b/plugins.yml @@ -586,3 +586,158 @@ plugins: 'ai_actions/install_ai_actions.md': 'ai_actions/configure_ai_actions.md' 'discounts/install_discounts.md': 'discounts/configure_discounts.md' 'content_management/collaborative_editing/install_collaborative_editing.md': 'content_management/collaborative_editing/configure_collaborative_editing.md' + - llmstxt: + preprocess: llmstxt_preprocess.py + markdown_description: | + > Ibexa DXP developer documentation - comprehensive technical guide for building digital experiences with Ibexa, a modern PHP-based Digital Experience Platform built on Symfony Full Stack Framework. + Ibexa is an enterprise-grade content management and digital commerce platform that comes in three editions: Headless (API-first content management), Experience (full DXP with Page Builder and forms), and Commerce (complete e-commerce solution). + Key technical capabilities include: flexible content modeling with custom field types, powerful REST and GraphQL APIs, headless and traditional architecture support, Product Information Management (PIM), integrated commerce features (cart, checkout, payment, shipping), multi-site and multi-language support, advanced search with Elasticsearch/Solr, customizable Twig templating, Symfony-based extensibility, workflow management, AI Actions for content generation, Form Builder, and comprehensive user/permission management. + The platform is designed for developers to build scalable content-driven applications, e-commerce sites, and headless solutions with enterprise features like Customer Data Platform (CDP), personalization, editorial workflows, and extensive APIs. Built with modern PHP practices on Symfony 7.x, supporting MySQL/MariaDB and PostgreSQL databases. + full_output: llms-full.txt + sections: + Ibexa Developer Documentation: + - index.md + Ibexa DXP editions: + - ibexa_products/*.md + Getting started: + - getting_started/*.md + Tutorials: + - tutorials/tutorials.md + - tutorials/beginner_tutorial/*.md + - tutorials/generic_field_type/*.md + - tutorials/page_and_form_tutorial/*.md + API: + - api/api.md + - api/event_reference/*.md + - api/graphql/*.md + - api/php_api/php_api.md + - api/rest_api/rest_api_authentication.md + - api/rest_api/extending_rest_api/*.md + - api/rest_api/rest_api_usage/*.md + Administration: + - administration/administration.md + - administration/admin_panel/*.md + - administration/back_office/*.md + - administration/back_office/back_office_elements/*.md + - administration/back_office/back_office_menus/*.md + - administration/back_office/back_office_tabs/*.md + - administration/back_office/browser/*.md + - administration/configuration/*.md + - administration/content_organization/*.md + - administration/dashboard/*.md + - administration/project_organization/*.md + - administration/recent_activity/recent_activity.md + Content management: + - content_management/*.md + - content_management/collaborative_editing/*.md + - content_management/content_api/*.md + - content_management/content_management_api/*.md + - content_management/data_migration/*.md + - content_management/field_types/*.md + - content_management/field_types/field_type_reference/*.md + - content_management/file_management/*.md + - content_management/forms/*.md + - content_management/images/*.md + - content_management/pages/*.md + - content_management/rich_text/*.md + - content_management/taxonomy/*.md + - content_management/url_management/*.md + - content_management/workflow/*.md + Templating: + - templating/*.md + - templating/design_engine/*.md + - templating/embed_and_list_content/*.md + - templating/layout/*.md + - templating/queries_and_controllers/*.md + - templating/render_content/*.md + - templating/templates/*.md + - templating/twig_function_reference/*.md + - templating/urls_and_routes/*.md + AI Actions: + - ai_actions/*.md + PIM (Product management): + - pim/*.md + - pim/attributes/*.md + Commerce: + - commerce/commerce.md + - commerce/cart/*.md + - commerce/checkout/*.md + - commerce/order_management/*.md + - commerce/payment/*.md + - commerce/shipping_management/*.md + - commerce/storefront/*.md + - commerce/transactional_emails/*.md + Discounts: + - discounts/*.md + Customer management: + - customer_management/*.md + Ibexa Engage: + - ibexa_engage/*.md + Multisite: + - multisite/*.md + - multisite/languages/*.md + - multisite/site_factory/*.md + - multisite/siteaccess/*.md + Permissions: + - permissions/*.md + Users: + - users/*.md + CDP (Customer Data Platform): + - cdp/*.md + - cdp/cdp_activation/*.md + Search: + - search/*.md + - search/activity_log_search_reference/*.md + - search/aggregation_reference/*.md + - search/ai_actions_search_reference/*.md + - search/collaboration_search_reference/*.md + - search/content_type_search_reference/*.md + - search/criteria_reference/*.md + - search/discounts_search_reference/*.md + - search/extensibility/*.md + - search/search_engines/search_engines.md + - search/search_engines/elasticsearch/*.md + - search/search_engines/legacy_search_engine/*.md + - search/search_engines/solr_search_engine/*.md + - search/sort_clause_reference/*.md + - search/url_search_reference/*.md + Ibexa Cloud: + - ibexa_cloud/*.md + Infrastructure and maintenance: + - infrastructure_and_maintenance/*.md + - infrastructure_and_maintenance/cache/*.md + - infrastructure_and_maintenance/cache/http_cache/*.md + - infrastructure_and_maintenance/clustering/*.md + - infrastructure_and_maintenance/security/*.md + Update and migration: + - update_and_migration/update_ibexa_dxp.md + - update_and_migration/from_4.0/to_4.1.md + - update_and_migration/from_4.1/update_from_4.1.md + - update_and_migration/from_4.2/update_from_4.2.md + - update_and_migration/from_4.3/*.md + - update_and_migration/from_4.4/update_from_4.4.md + - update_and_migration/from_4.5/update_from_4.5.md + - update_and_migration/from_4.6/*.md + - update_and_migration/from_5.0/update_from_5.0.md + - update_and_migration/migrate_to_ibexa_dxp/*.md + Resources: + - resources/*.md + - resources/contributing/*.md + Product guides: + - product_guides/product_guides.md + Release notes: + - release_notes/release_notes.md + - release_notes/ibexa_dxp_v5.0.md + - release_notes/ibexa_dxp_v5.0_deprecations.md + - release_notes/ibexa_dxp_v4.6.md + - release_notes/ibexa_dxp_v4.5.md + - release_notes/ibexa_dxp_v4.4.md + - release_notes/ibexa_dxp_v4.3.md + - release_notes/ibexa_dxp_v4.2.md + - release_notes/ibexa_dxp_v4.1.md + - release_notes/ibexa_dxp_v4.0.md + PHP API Reference - Signatures: + - api/php_api/php_api_reference.md + - api/php_api/php_api_signatures.md + REST API Reference: + - api/rest_api/rest_api_reference_overview.md diff --git a/requirements.txt b/requirements.txt index c03e3d1a35..688d9446a1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ mkdocs-macros-plugin==1.3.7 mkdocs-redirects==1.2.2 mkdocs-autolinks-plugin==0.7.1 Jinja2==3.1.6 +mkdocs-llmstxt diff --git a/theme/assets/page-actions.js b/theme/assets/page-actions.js new file mode 100644 index 0000000000..6323042755 --- /dev/null +++ b/theme/assets/page-actions.js @@ -0,0 +1,103 @@ +/** + * Page Actions JavaScript + * Handles functionality for page action buttons (Copy for LLM, View as Markdown, Edit on GitHub) + */ + +async function copyPageForLLM() { + try { + const mdPath = document.querySelector('meta[name="markdown-path"]').content; + console.log('Fetching from path:', mdPath); + + let markdownContent; + + try { + const response = await fetch(mdPath); + if (response.ok) { + markdownContent = await response.text(); + } else { + throw new Error(`HTTP error! status: ${response.status}`); + } + } catch (fetchError) { + console.log('Direct fetch failed, trying GitHub fallback...'); + const editUrl = document.querySelector('meta[name="edit-url"]').content; + const rawUrl = editUrl.replace('/edit/', '/raw/'); + + try { + const response = await fetch(rawUrl); + if (response.ok) { + markdownContent = await response.text(); + } else { + const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(rawUrl)}`; + const proxyResponse = await fetch(proxyUrl); + if (proxyResponse.ok) { + const proxyData = await proxyResponse.json(); + markdownContent = proxyData.contents; + } else { + throw new Error('All fetch methods failed'); + } + } + } catch (githubError) { + throw new Error('GitHub fallback failed'); + } + } + + if (!markdownContent) { + throw new Error('No content received'); + } + + await navigator.clipboard.writeText(markdownContent); + showButtonFeedback('success', 'Copied!', '📋'); + + } catch (error) { + console.error('Failed to copy content:', error); + + try { + const mdPath = document.querySelector('meta[name="markdown-path"]').content; + window.open(mdPath, '_blank'); + showButtonFeedback('info', 'Opened in tab', '🔗'); + } catch (fallbackError) { + showButtonFeedback('error', 'Failed', '❌'); + } + } +} + +function showButtonFeedback(type, message, icon) { + const button = document.querySelector('button[onclick="copyPageForLLM()"]'); + if (!button) return; + + const originalHTML = button.innerHTML; + button.innerHTML = `${icon} ${message}`; + + if (type === 'success') { + button.style.background = '#d4edda'; + button.style.borderColor = '#c3e6cb'; + button.style.color = '#155724'; + } else if (type === 'error') { + button.style.background = '#f8d7da'; + button.style.borderColor = '#f5c6cb'; + button.style.color = '#721c24'; + } else if (type === 'info') { + button.style.background = '#d1ecf1'; + button.style.borderColor = '#bee5eb'; + button.style.color = '#0c5460'; + } + + setTimeout(() => { + button.innerHTML = originalHTML; + button.style.background = ''; + button.style.borderColor = ''; + button.style.color = ''; + }, 2000); +} + +document.addEventListener('DOMContentLoaded', function() { + console.log('Page actions initialized'); + + const pageActions = document.getElementById('page-actions'); + const firstH1 = document.querySelector('.bootstrap-iso h1, h1'); + + if (pageActions && firstH1) { + firstH1.insertAdjacentElement('afterend', pageActions); + pageActions.style.display = 'flex'; + } +}); diff --git a/theme/main.html b/theme/main.html index 66ce7dc87d..110fbcaf1a 100644 --- a/theme/main.html +++ b/theme/main.html @@ -13,6 +13,93 @@ + + + + + + {% if config.repo_url and page.edit_url %} + + + {% endif %} + + + {% endblock %} {% block site_nav %} {% if nav %} @@ -75,7 +162,36 @@ {% endif %} {% include "partials/eol_warning.html" %} - {{ page.content }} + +