diff options
| author | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-07 09:51:18 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-05-07 09:51:18 +0300 |
| commit | a7bb8246e42719a809421d016f8f5d52f43d7db1 (patch) | |
| tree | 66f069575bdaf0ad02b3dfaed5a53965e09021aa /docs/conf.py | |
| parent | 7cf51e1c2901f6d1b01e9bff194f7188bc29e417 (diff) | |
| parent | 04541bda8a3d04ecb9824f92d344ec8bd7aa2523 (diff) | |
| download | vyos-documentation-a7bb8246e42719a809421d016f8f5d52f43d7db1.tar.gz vyos-documentation-a7bb8246e42719a809421d016f8f5d52f43d7db1.zip | |
Merge pull request #1874 from vyos/feat/docs-llms-txt-current
docs: render llms.txt at build time (current)
Diffstat (limited to 'docs/conf.py')
| -rw-r--r-- | docs/conf.py | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/docs/conf.py b/docs/conf.py index 76a00577..da462b0e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,11 +26,16 @@ project = u'VyOS' copyright = u'2026, VyOS maintainers and contributors' author = u'VyOS maintainers and contributors' -# The short X.Y version -version = u'1.5' +# The short X.Y version (rolling — next major; bumped at branch cut) +version = u'rolling' -# The full version, including alpha/beta/rc tags -release = u'1.5.x (circinus)' +# The full version, including alpha/beta/rc tags. The `current` branch +# is the rolling tip and serves at /en/rolling/ on RTD; the literal +# below is exposed in the page footer ("v: rolling (current)") and is +# interpolated into _templates/llms.txt.j2 ("This documentation covers +# {{ release }}."). Pin this to a value that names what the rolling +# docs actually serve, not a stale LTS codename. +release = u'rolling (current)' # -- General configuration --------------------------------------------------- @@ -127,7 +132,7 @@ html_static_path = ['_static'] html_extra_path = ['_html_extra'] -html_baseurl = 'https://docs.vyos.io/en/latest/' +html_baseurl = 'https://docs.vyos.io/en/rolling/' _rtd_version_type = os.environ.get('READTHEDOCS_VERSION_TYPE', '') _github_version = ( @@ -144,11 +149,13 @@ html_context = { 'conf_py_path': '/docs/', } -# sphinx-sitemap: baseurl already includes /en/latest/, so skip lang+version +# sphinx-sitemap: baseurl already includes /en/rolling/, so skip lang+version sitemap_url_scheme = '{link}' -# sphinx-llms-txt: disable auto-generated llms.txt, keep curated one from -# _html_extra; llms-full.txt is still auto-generated +# sphinx-llms-txt: disable the package's auto-generated index llms.txt. +# The curated llms.txt is rendered at build time from +# _templates/llms.txt.j2 by the _write_llms_txt() build-finished hook +# below; llms-full.txt is still auto-generated by sphinx-llms-txt. llms_txt_file = False # Custom sidebar templates, must be a dictionary that maps document names @@ -246,6 +253,51 @@ def _prefer_webp(app): app.builder.supported_image_types = ['image/webp'] + types +def _write_llms_txt(app, exception): + # Skip dirhtml: production publishes via the `html` / `readthedocs` + # builders only. The `.md` links in the curated template do + # actually resolve under `dirhtml` (`_copy_md_sources` puts `.md` + # files at their source-relative paths regardless of builder), but + # we still don't render llms.txt for builds we don't ship — local + # `make dirhtml` is a developer convenience, not a publish target. + if exception is not None or app.builder.name not in ( + 'html', 'readthedocs'): + return + if not app.config.html_baseurl: + # Fail loudly rather than rendering /quick-start.md etc. as a + # silently-broken root-relative URL — every supported branch + # sets html_baseurl, so a missing value is a regression. + raise RuntimeError( + 'html_baseurl must be set to render llms.txt') + from pathlib import Path + from jinja2 import Environment, FileSystemLoader, StrictUndefined + tpl_dir = Path(app.srcdir) / '_templates' + out_path = Path(app.outdir) / 'llms.txt' + baseurl = app.config.html_baseurl.rstrip('/') + '/' + # FileSystemLoader + get_template (rather than from_string) makes + # Jinja tracebacks reference the real template filename and line + # number — useful when StrictUndefined trips on a typo in + # llms.txt.j2. StrictUndefined: missing template variables raise + # rather than silently render as empty strings, so a typo in + # llms.txt.j2 fails the build instead of shipping a half-blank + # llms.txt. + env = Environment( + loader=FileSystemLoader(str(tpl_dir)), + undefined=StrictUndefined, + keep_trailing_newline=True, + # Plain-text template (not HTML), so HTML autoescape is not + # appropriate. Setting autoescape=False explicitly to silence + # bandit/ruff S701 and document the intent. + autoescape=False, + ) + template = env.get_template('llms.txt.j2') + rendered = template.render( + baseurl=baseurl, + release=app.config.release, + ) + out_path.write_text(rendered, encoding='utf-8') + + def _copy_md_sources(app, exception): """Copy .md source files verbatim into the HTML output tree.""" if exception is not None: @@ -261,3 +313,4 @@ def _copy_md_sources(app, exception): def setup(app): app.connect('builder-inited', _prefer_webp) app.connect('build-finished', _copy_md_sources) + app.connect('build-finished', _write_llms_txt) |
