From 82a67a1fabe747c63d9228e9c1b488cd46b353f1 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 15:11:17 +0000 Subject: [PATCH 01/10] Store each endpoint's metadata in a slice on Page Such that we can later construct the table of contents with the data. --- layouts/_partials/openapi/render-api.html | 9 +++++---- layouts/_partials/openapi/render-operation.html | 11 +++++++++++ layouts/_shortcodes/http-api.html | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/layouts/_partials/openapi/render-api.html b/layouts/_partials/openapi/render-api.html index 608cfa33..a40fb04a 100644 --- a/layouts/_partials/openapi/render-api.html +++ b/layouts/_partials/openapi/render-api.html @@ -15,6 +15,7 @@ {{ $api_data := index .api_data }} {{ $base_url := .base_url }} {{ $anchor_base := .anchor_base }} +{{ $page := .page }} {{ range $path_name, $path_data := $api_data.paths }} @@ -26,28 +27,28 @@ {{ with $path_data.get }} - {{ $operation_params := merge $params (dict "method" "GET" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "GET" "operation_data" . "anchor_base" $anchor_base "page" $page) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.post }} - {{ $operation_params := merge $params (dict "method" "POST" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "POST" "operation_data" . "anchor_base" $anchor_base "page" $page) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.put }} - {{ $operation_params := merge $params (dict "method" "PUT" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "PUT" "operation_data" . "anchor_base" $anchor_base "page" $page) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.delete }} - {{ $operation_params := merge $params (dict "method" "DELETE" "operation_data" . "anchor_base" $anchor_base) }} + {{ $operation_params := merge $params (dict "method" "DELETE" "operation_data" . "anchor_base" $anchor_base "page" $page) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} diff --git a/layouts/_partials/openapi/render-operation.html b/layouts/_partials/openapi/render-operation.html index c1e34ddf..d59ea16d 100644 --- a/layouts/_partials/openapi/render-operation.html +++ b/layouts/_partials/openapi/render-operation.html @@ -22,6 +22,7 @@ {{ $method := .method }} {{ $endpoint := .endpoint }} {{ $operation_data := .operation_data }} +{{ $page := .page }} {{ $anchor := "" }} {{ if .anchor_base }} @@ -29,6 +30,16 @@ {{ end }} {{ $anchor = printf "%s%s%s" $anchor (lower $method) (anchorize $endpoint) }} +{{/* Collect endpoints for the on-page endpoints TOC */}} +{{ if $page }} + {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary }} + {{/* Store each endpoint's metadata in a scratch variable */}} + {{ if not (reflect.IsSlice ($page.Scratch.Get "api_endpoints")) }} + {{ $page.Scratch.Set "api_endpoints" (slice) }} + {{ end }} + {{ $page.Scratch.Add "api_endpoints" (slice $entry) }} +{{ end }} +
diff --git a/layouts/_shortcodes/http-api.html b/layouts/_shortcodes/http-api.html index b5201c49..dc2b7d02 100644 --- a/layouts/_shortcodes/http-api.html +++ b/layouts/_shortcodes/http-api.html @@ -30,4 +30,4 @@ {{ $api_data = partial "json-schema/resolve-refs" (dict "schema" $api_data "path" $path) }} {{ $api_data = partial "json-schema/resolve-allof" $api_data }} -{{ partial "openapi/render-api" (dict "api_data" $api_data "base_url" $base_url "anchor_base" $anchor_base) }} +{{ partial "openapi/render-api" (dict "api_data" $api_data "base_url" $base_url "anchor_base" $anchor_base "page" .Page) }} From 56d48eb3a8e6ca57e84f3688de1b811362c62efc Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 15:12:15 +0000 Subject: [PATCH 02/10] Add an endpoints table of contents A simple list of endpoints that one can ctrl-f through. --- assets/scss/_styles_project.scss | 41 +++++++++++++++++++++++++++- layouts/_partials/endpoints-toc.html | 28 +++++++++++++++++++ layouts/docs/list.html | 3 +- 3 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 layouts/_partials/endpoints-toc.html diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index ce0ce0ee..71686e54 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -257,6 +257,45 @@ Custom SCSS for the Matrix spec } +.endpoints-toc { + summary { + cursor: pointer; + font-weight: $font-weight-bold; + font-size: 1.05rem; + margin-bottom: 0.5rem; + } + + .endpoint-list { + list-style: none; + padding-left: 0; + margin: 0; + } + + .endpoint-list li { + margin: 0.2rem 0; + } + + .endpoint-list a { + text-decoration: none; + color: inherit; + } + + .endpoint-list .http-api-method { + font-weight: $font-weight-bold; + margin-right: 0.35rem; + } + + .endpoint-path { + font-family: $font-family-monospace; + color: $secondary; + } +} + +.page-description { + margin-bottom: 1rem; + color: inherit; +} + /* Styles for alert boxes */ .alert { &.note { @@ -581,4 +620,4 @@ dd { .breadcrumb { margin: 0; } -} \ No newline at end of file +} diff --git a/layouts/_partials/endpoints-toc.html b/layouts/_partials/endpoints-toc.html new file mode 100644 index 00000000..238dee05 --- /dev/null +++ b/layouts/_partials/endpoints-toc.html @@ -0,0 +1,28 @@ +{{/* Minimal list of API endpoints for the current page. */}} +{{ $raw := .Scratch.Get "api_endpoints" }} +{{/* Normalize to a slice */}} +{{ $endpoints := slice }} +{{ if reflect.IsSlice $raw }} + {{ $endpoints = $raw }} +{{ else if reflect.IsMap $raw }} + {{ range $raw }} + {{ $endpoints = append $endpoints . }} + {{ end }} +{{ end }} +{{ if gt (len $endpoints) 0 }} +
+
+ List of Endpoints + +
+
+{{ end }} diff --git a/layouts/docs/list.html b/layouts/docs/list.html index 01145138..25449816 100644 --- a/layouts/docs/list.html +++ b/layouts/docs/list.html @@ -7,7 +7,8 @@ {{ define "main" }}

{{ .Title }}

- {{ with .Params.description }}
{{ . | markdownify }}
{{ end }} + {{ with .Params.description }}

{{ . | markdownify }}

{{ end }} + {{ partial "endpoints-toc.html" . }} {{ .Content }}
{{ end }} From f03730455dccd890bd1cb5003f3ed2a53d0cccfc Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 15:46:03 +0000 Subject: [PATCH 03/10] Place the endpoints list just under the description of each API We needed to override Docsy's default page renderers to show it. Because the Client-Server API uses a different render chain than the other endpoint pages, we have to override two of Docsy's pages (`content.html` and `single.html`). In order to reduce duplication, we then put the shared content into a `spec-content.html` partial. --- layouts/_partials/spec-content.html | 9 +++++++++ layouts/content.html | 7 +++---- layouts/docs/single.html | 3 +++ 3 files changed, 15 insertions(+), 4 deletions(-) create mode 100644 layouts/_partials/spec-content.html create mode 100644 layouts/docs/single.html diff --git a/layouts/_partials/spec-content.html b/layouts/_partials/spec-content.html new file mode 100644 index 00000000..21596dc5 --- /dev/null +++ b/layouts/_partials/spec-content.html @@ -0,0 +1,9 @@ +{{- /* Shared render for spec pages: title, optional description, endpoints list, body, and last-mod info. */ -}} +
+

{{ .Title }}

+ {{ partial "endpoints-toc.html" . }} + + {{ .Content }} + + {{ partial "page-meta-lastmod.html" . }} +
diff --git a/layouts/content.html b/layouts/content.html index e58073f3..1fde0699 100644 --- a/layouts/content.html +++ b/layouts/content.html @@ -1,4 +1,3 @@ -
-

{{ .Title }}

- {{ .Content }} -
+{{ define "main" }} + {{ partial "spec-content.html" . }} +{{ end }} diff --git a/layouts/docs/single.html b/layouts/docs/single.html new file mode 100644 index 00000000..1fde0699 --- /dev/null +++ b/layouts/docs/single.html @@ -0,0 +1,3 @@ +{{ define "main" }} + {{ partial "spec-content.html" . }} +{{ end }} From 1213f81676321a39641814369cf5faead3ea9e79 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 15:47:08 +0000 Subject: [PATCH 04/10] Move each spec's intro above the endpoints list This just looks visually nicer. You have an introduction paragraph, then the list of endpoints, then the spec. --- content/application-service-api.md | 14 +++-- content/client-server-api/_index.md | 12 ++--- content/identity-service-api.md | 16 +++--- content/push-gateway-api.md | 7 ++- content/server-server-api.md | 79 ++++++++++++++--------------- layouts/_partials/spec-content.html | 2 + 6 files changed, 62 insertions(+), 68 deletions(-) diff --git a/content/application-service-api.md b/content/application-service-api.md index cc2c25ca..83217383 100644 --- a/content/application-service-api.md +++ b/content/application-service-api.md @@ -2,16 +2,14 @@ title: "Application Service API" weight: 30 type: docs +description: | + The Matrix client-server API and server-server APIs provide a consistent, + self-contained federated messaging fabric but leave little room for custom + server-side behaviour such as gateways, filters, or extensible hooks. The + Application Service API defines a standard way to add this extensible + functionality, independent of the underlying homeserver implementation. --- -The Matrix client-server API and server-server APIs provide the means to -implement a consistent self-contained federated messaging fabric. -However, they provide limited means of implementing custom server-side -behaviour in Matrix (e.g. gateways, filters, extensible hooks etc). The -Application Service API (AS API) defines a standard API to allow such -extensible functionality to be implemented irrespective of the -underlying homeserver implementation. - ## Application Services Application services are passive and can only observe events from the diff --git a/content/client-server-api/_index.md b/content/client-server-api/_index.md index 2460776f..82d05b4f 100644 --- a/content/client-server-api/_index.md +++ b/content/client-server-api/_index.md @@ -2,14 +2,14 @@ title: "Client-Server API" weight: 10 type: docs +description: | + The client-server API allows clients to send messages, control rooms and + synchronise conversation history. It is designed to support both lightweight + clients which store no state and lazy-load data from the server as required, + as well as heavyweight clients which maintain a full local persistent copy of + server state. --- -The client-server API allows clients to -send messages, control rooms and synchronise conversation history. It is -designed to support both lightweight clients which store no state and -lazy-load data from the server as required - as well as heavyweight -clients which maintain a full local persistent copy of server state. - ## API Standards {{% boxes/note %}} diff --git a/content/identity-service-api.md b/content/identity-service-api.md index 3c20a12a..8946ad34 100644 --- a/content/identity-service-api.md +++ b/content/identity-service-api.md @@ -2,17 +2,15 @@ title: "Identity Service API" weight: 40 type: docs +description: | + The Matrix client-server and server-server APIs are largely expressed in + Matrix user identifiers. Sometimes it is useful to refer to users by other + (“third-party”) identifiers such as email addresses or phone numbers. The + Identity Service API describes how mappings between 3PIDs and Matrix user + IDs can be established, validated, and used; in practice this has been + applied to email addresses and phone numbers. --- -The Matrix client-server and server-server APIs are largely expressed in -Matrix user identifiers. From time to time, it is useful to refer to -users by other ("third-party") identifiers, or "3PID"s, e.g. their email -address or phone number. This Identity Service Specification describes -how mappings between third-party identifiers and Matrix user identifiers -can be established, validated, and used. This description technically -may apply to any 3PID, but in practice has only been applied -specifically to email addresses and phone numbers. - ## General principles The purpose of an identity server is to validate, store, and answer diff --git a/content/push-gateway-api.md b/content/push-gateway-api.md index 161cf24f..f74decd9 100644 --- a/content/push-gateway-api.md +++ b/content/push-gateway-api.md @@ -2,12 +2,11 @@ title: "Push Gateway API" weight: 50 type: docs +description: | + Clients may want to receive push notifications when events are received at the + homeserver. This is managed by a distinct entity called the Push Gateway. --- -Clients may want to receive push notifications when events are received -at the homeserver. This is managed by a distinct entity called the Push -Gateway. - ## Overview A client's homeserver forwards information about received events to the diff --git a/content/server-server-api.md b/content/server-server-api.md index ca1cdd2e..1ab7e3ba 100644 --- a/content/server-server-api.md +++ b/content/server-server-api.md @@ -2,49 +2,46 @@ title: "Server-Server API" weight: 20 type: docs +description: | + Matrix homeservers use the Federation APIs (also known as server-server APIs) + to communicate with each other. Homeservers use these APIs to push messages in + real-time, retrieve historic messages, and query profile or presence + information about users on other servers. The APIs are implemented over HTTPS, + with authentication provided by public key signatures both at the TLS + transport layer and in HTTP Authorization headers. + + There are three main kinds of communication that occur between + homeservers: + + Persistent Data Units (PDUs): + These events are broadcast from one homeserver to any others that have + joined the same room (identified by Room ID). They are persisted in + long-term storage and record the history of messages and state for a + room. + + Like email, it is the responsibility of the originating server of a PDU + to deliver that event to its recipient servers. However PDUs are signed + using the originating server's private key so that it is possible to + deliver them through third-party servers. + + Ephemeral Data Units (EDUs): + These events are pushed between pairs of homeservers. They are not + persisted and are not part of the history of a room, nor does the + receiving homeserver have to reply to them. + + Queries: + These are single request/response interactions between a given pair of + servers, initiated by one side sending an HTTPS GET request to obtain + some information, and responded by the other. They are not persisted and + contain no long-term significant history. They simply request a snapshot + state at the instant the query is made. + + EDUs and PDUs are further wrapped in an envelope called a Transaction, + which is transferred from the origin to the destination homeserver using + an HTTPS PUT request. + --- -Matrix homeservers use the Federation APIs (also known as server-server -APIs) to communicate with each other. Homeservers use these APIs to push -messages to each other in real-time, to retrieve historic messages from -each other, and to query profile and presence information about users on -each other's servers. - -The APIs are implemented using HTTPS requests between each of the -servers. These HTTPS requests are strongly authenticated using public -key signatures at the TLS transport layer and using public key -signatures in HTTP Authorization headers at the HTTP layer. - -There are three main kinds of communication that occur between -homeservers: - -Persistent Data Units (PDUs): -These events are broadcast from one homeserver to any others that have -joined the same room (identified by Room ID). They are persisted in -long-term storage and record the history of messages and state for a -room. - -Like email, it is the responsibility of the originating server of a PDU -to deliver that event to its recipient servers. However PDUs are signed -using the originating server's private key so that it is possible to -deliver them through third-party servers. - -Ephemeral Data Units (EDUs): -These events are pushed between pairs of homeservers. They are not -persisted and are not part of the history of a room, nor does the -receiving homeserver have to reply to them. - -Queries: -These are single request/response interactions between a given pair of -servers, initiated by one side sending an HTTPS GET request to obtain -some information, and responded by the other. They are not persisted and -contain no long-term significant history. They simply request a snapshot -state at the instant the query is made. - -EDUs and PDUs are further wrapped in an envelope called a Transaction, -which is transferred from the origin to the destination homeserver using -an HTTPS PUT request. - ## API standards The mandatory baseline for server-server communication in Matrix is diff --git a/layouts/_partials/spec-content.html b/layouts/_partials/spec-content.html index 21596dc5..7f18c60a 100644 --- a/layouts/_partials/spec-content.html +++ b/layouts/_partials/spec-content.html @@ -1,6 +1,8 @@ {{- /* Shared render for spec pages: title, optional description, endpoints list, body, and last-mod info. */ -}}

{{ .Title }}

+ {{ with .Params.description }}

{{ . | markdownify }}

{{ end }} + {{ partial "endpoints-toc.html" . }} {{ .Content }} From 17acd978a40d1f26729782a61c810dbbef672663 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 14:53:10 +0000 Subject: [PATCH 05/10] Display "(deprecated)" next to deprecated endpoints --- assets/scss/_styles_project.scss | 6 ++++++ layouts/_partials/endpoints-toc.html | 1 + layouts/_partials/openapi/render-operation.html | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 71686e54..2e1d2da9 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -289,6 +289,12 @@ Custom SCSS for the Matrix spec font-family: $font-family-monospace; color: $secondary; } + + .endpoint-deprecated { + color: $danger; + font-weight: $font-weight-bold; + margin-left: 0.35rem; + } } .page-description { diff --git a/layouts/_partials/endpoints-toc.html b/layouts/_partials/endpoints-toc.html index 238dee05..f2ccae3b 100644 --- a/layouts/_partials/endpoints-toc.html +++ b/layouts/_partials/endpoints-toc.html @@ -19,6 +19,7 @@ {{ .method }} {{ .endpoint }} + {{ if .deprecated }}(deprecated){{ end }} {{ end }} diff --git a/layouts/_partials/openapi/render-operation.html b/layouts/_partials/openapi/render-operation.html index d59ea16d..dbfdf346 100644 --- a/layouts/_partials/openapi/render-operation.html +++ b/layouts/_partials/openapi/render-operation.html @@ -32,8 +32,8 @@ {{/* Collect endpoints for the on-page endpoints TOC */}} {{ if $page }} - {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary }} {{/* Store each endpoint's metadata in a scratch variable */}} + {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary "deprecated" $operation_data.deprecated }} {{ if not (reflect.IsSlice ($page.Scratch.Get "api_endpoints")) }} {{ $page.Scratch.Set "api_endpoints" (slice) }} {{ end }} From 42a1bc370f4c2892dca5fc164657237866e2cc4e Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 15:57:28 +0000 Subject: [PATCH 06/10] newsfile --- changelogs/internal/newsfragments/2262.clarification | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/internal/newsfragments/2262.clarification diff --git a/changelogs/internal/newsfragments/2262.clarification b/changelogs/internal/newsfragments/2262.clarification new file mode 100644 index 00000000..117c2bec --- /dev/null +++ b/changelogs/internal/newsfragments/2262.clarification @@ -0,0 +1 @@ +Add a list of endpoints to the top of each spec page. \ No newline at end of file From 2d0e4ea471b4301ed2e5392e59dd91c09e089f56 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 19:06:10 +0000 Subject: [PATCH 07/10] Source endpoints from CS API modules as well Any endpoint in a CS API module was not getting listed. This is because they are stored in nested pages. We need to hoist them up to the outer page, such that they can be retrieved and rendered by our endpoints TOC partial. --- layouts/_partials/openapi/render-api.html | 9 +++++---- layouts/_partials/openapi/render-operation.html | 3 ++- layouts/_shortcodes/http-api.html | 9 ++++++++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/layouts/_partials/openapi/render-api.html b/layouts/_partials/openapi/render-api.html index a40fb04a..0ac245aa 100644 --- a/layouts/_partials/openapi/render-api.html +++ b/layouts/_partials/openapi/render-api.html @@ -16,6 +16,7 @@ {{ $base_url := .base_url }} {{ $anchor_base := .anchor_base }} {{ $page := .page }} +{{ $module := .module }} {{ range $path_name, $path_data := $api_data.paths }} @@ -27,28 +28,28 @@ {{ with $path_data.get }} - {{ $operation_params := merge $params (dict "method" "GET" "operation_data" . "anchor_base" $anchor_base "page" $page) }} + {{ $operation_params := merge $params (dict "method" "GET" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.post }} - {{ $operation_params := merge $params (dict "method" "POST" "operation_data" . "anchor_base" $anchor_base "page" $page) }} + {{ $operation_params := merge $params (dict "method" "POST" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.put }} - {{ $operation_params := merge $params (dict "method" "PUT" "operation_data" . "anchor_base" $anchor_base "page" $page) }} + {{ $operation_params := merge $params (dict "method" "PUT" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} {{ with $path_data.delete }} - {{ $operation_params := merge $params (dict "method" "DELETE" "operation_data" . "anchor_base" $anchor_base "page" $page) }} + {{ $operation_params := merge $params (dict "method" "DELETE" "operation_data" . "anchor_base" $anchor_base "page" $page "module" $module) }} {{ partial "openapi/render-operation" $operation_params }} {{ end }} diff --git a/layouts/_partials/openapi/render-operation.html b/layouts/_partials/openapi/render-operation.html index dbfdf346..7ab30a8f 100644 --- a/layouts/_partials/openapi/render-operation.html +++ b/layouts/_partials/openapi/render-operation.html @@ -23,6 +23,7 @@ {{ $endpoint := .endpoint }} {{ $operation_data := .operation_data }} {{ $page := .page }} +{{ $module := .module }} {{ $anchor := "" }} {{ if .anchor_base }} @@ -33,7 +34,7 @@ {{/* Collect endpoints for the on-page endpoints TOC */}} {{ if $page }} {{/* Store each endpoint's metadata in a scratch variable */}} - {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary "deprecated" $operation_data.deprecated }} + {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary "deprecated" $operation_data.deprecated "module" $module }} {{ if not (reflect.IsSlice ($page.Scratch.Get "api_endpoints")) }} {{ $page.Scratch.Set "api_endpoints" (slice) }} {{ end }} diff --git a/layouts/_shortcodes/http-api.html b/layouts/_shortcodes/http-api.html index dc2b7d02..109465a1 100644 --- a/layouts/_shortcodes/http-api.html +++ b/layouts/_shortcodes/http-api.html @@ -23,6 +23,13 @@ {{ $api := .Params.api}} {{ $anchor_base := .Params.anchor_base}} +{{/* Allow an outer page to collect endpoints (used for modules). */}} +{{ $target_page := .Page }} +{{ with .Page.Scratch.Get "endpoint_page" }} + {{ $target_page = . }} +{{ end }} +{{ $module_name := .Page.Scratch.Get "endpoint_module" }} + {{ $api_data := index .Site.Data.api .Params.spec .Params.api }} {{ $base_url := (index $api_data.servers 0).variables.basePath.default }} {{ $path := delimit (slice "api" $spec $api) "/" }} @@ -30,4 +37,4 @@ {{ $api_data = partial "json-schema/resolve-refs" (dict "schema" $api_data "path" $path) }} {{ $api_data = partial "json-schema/resolve-allof" $api_data }} -{{ partial "openapi/render-api" (dict "api_data" $api_data "base_url" $base_url "anchor_base" $anchor_base "page" .Page) }} +{{ partial "openapi/render-api" (dict "api_data" $api_data "base_url" $base_url "anchor_base" $anchor_base "page" $target_page "module" $module_name) }} From 468fcb3992f29b83bbb62c4da642f51f42b68819 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Fri, 5 Dec 2025 19:06:44 +0000 Subject: [PATCH 08/10] Group endpoints by module Makes the list of endpoints easier to scan. --- assets/scss/_styles_project.scss | 12 ++++++++- data/cs_modules.yaml | 39 ++++++++++++++++++++++++++++ layouts/_partials/endpoints-toc.html | 22 +++++++++++++--- layouts/_shortcodes/cs-module.html | 28 ++++++++++++++++++++ 4 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 data/cs_modules.yaml diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 2e1d2da9..c0a9c457 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -281,7 +281,6 @@ Custom SCSS for the Matrix spec } .endpoint-list .http-api-method { - font-weight: $font-weight-bold; margin-right: 0.35rem; } @@ -295,6 +294,17 @@ Custom SCSS for the Matrix spec font-weight: $font-weight-bold; margin-left: 0.35rem; } + + .endpoint-module { + &:not(:first-child) { + margin-top: 0.75rem; + } + } + + .endpoint-module-title { + font-weight: $font-weight-bold; + margin-bottom: 0.35rem; + } } .page-description { diff --git a/data/cs_modules.yaml b/data/cs_modules.yaml new file mode 100644 index 00000000..d6df20aa --- /dev/null +++ b/data/cs_modules.yaml @@ -0,0 +1,39 @@ +account_data: "Client Config" +admin: "Server Administration" +content_repo: "Content repository" +device_management: "Device Management" +dm: "Direct Messaging" +end_to_end_encryption: "End-to-End Encryption" +event_annotations: "Event annotations and reactions" +event_context: "Event Context" +event_replacements: "Event replacements" +guest_access: "Guest Access" +history_visibility: "Room History Visibility" +ignore_users: "Ignoring Users" +instant_messaging: "Instant Messaging" +mentions: "User and room mentions" +moderation_policies: "Moderation policy lists" +openid: "OpenID" +presence: "Presence" +push: "Push Notifications" +read_markers: "Read and unread markers" +receipts: "Receipts" +reference_relations: "Reference relations" +report_content: "Reporting Content" +rich_replies: "Rich replies" +room_previews: "Room Previews" +room_upgrades: "Room Upgrades" +search: "Server Side Search" +secrets: "Secrets" +send_to_device: "Send-to-Device messaging" +server_acls: "Server Access Control Lists (ACLs) for rooms" +server_notices: "Server Notices" +spaces: "Spaces" +sso_login: "SSO client login/authentication" +stickers: "Sticker Messages" +tags: "Room Tagging" +third_party_invites: "Third-party invites" +third_party_networks: "Third-party Networks" +threading: "Threading" +typing_notifications: "Typing Notifications" +voip_events: "Voice over IP" diff --git a/layouts/_partials/endpoints-toc.html b/layouts/_partials/endpoints-toc.html index f2ccae3b..88d37a09 100644 --- a/layouts/_partials/endpoints-toc.html +++ b/layouts/_partials/endpoints-toc.html @@ -13,8 +13,23 @@
List of Endpoints -
    - {{ range $endpoints }} + {{/* Sort by module to group visually */}} + {{ $sorted := sort $endpoints "module" }} + {{ $current := "" }} + {{ $seen := newScratch }} + {{ range $sorted }} + {{ $mod := .module }} + {{ if not $mod }}{{ $mod = "Required" }}{{ end }} + {{ if ne $mod $current }} + {{ if $current }}
{{ end }} +
+
{{ $mod }}
+
    + {{ $current = $mod }} + {{ end }} + {{ $key := printf "%s|%s" .method .anchor }} + {{ if not ($seen.Get $key) }} + {{ $seen.Set $key true }}
  • {{ .method }} @@ -23,7 +38,8 @@
  • {{ end }} -
+ {{ end }} + {{ if $current }}
{{ end }}
{{ end }} diff --git a/layouts/_shortcodes/cs-module.html b/layouts/_shortcodes/cs-module.html index 52c9a5d9..090c6558 100644 --- a/layouts/_shortcodes/cs-module.html +++ b/layouts/_shortcodes/cs-module.html @@ -11,6 +11,34 @@ {{ with .Site.GetPage "client-server-api/modules" }} {{ with .Resources.GetMatch (printf "%s%s" $name ".md") }} + {{/* Preserve previous scratch values so nested modules don't leak */}} + {{ $prevPage := .Scratch.Get "endpoint_page" }} + {{ $prevModule := .Scratch.Get "endpoint_module" }} + + {{/* Allow endpoints rendered in the module to accumulate on the parent page */}} + {{ .Scratch.Set "endpoint_page" $.Page }} + {{/* Name the module for grouping in the endpoints list */}} + {{ $display := $.Get "title" }} + {{ if not $display }} + {{ $display = index $.Site.Data.cs_modules $name }} + {{ end }} + {{ if not $display }} + {{ $display = $name }} + {{ end }} + {{ .Scratch.Set "endpoint_module" $display }} + {{ .RenderShortcodes }} + + {{/* Restore previous scratch values */}} + {{ if $prevPage }} + {{ .Scratch.Set "endpoint_page" $prevPage }} + {{ else }} + {{ .Scratch.Delete "endpoint_page" }} + {{ end }} + {{ if $prevModule }} + {{ .Scratch.Set "endpoint_module" $prevModule }} + {{ else }} + {{ .Scratch.Delete "endpoint_module" }} + {{ end }} {{ end }} {{ end }} From f30e850bf1d8ac192231fc2102fbfb39fed42728 Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 10 Dec 2025 20:34:11 +0000 Subject: [PATCH 09/10] Fix duplicate modules endpoints I was seeing duplicate endpoints appearing under each module (typically 2 of each). This turned out to be due to the `render-operation` partial being called multiple times (once when rendering the page, and another when rendering the left-hand-side TOC). We now check whether the endpoint has already been added to the list before insertion, via a "seen" map (for quick lookup). --- layouts/_partials/endpoints-toc.html | 19 ++++++++----------- .../_partials/openapi/render-operation.html | 11 +++++++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/layouts/_partials/endpoints-toc.html b/layouts/_partials/endpoints-toc.html index 88d37a09..740160c6 100644 --- a/layouts/_partials/endpoints-toc.html +++ b/layouts/_partials/endpoints-toc.html @@ -16,9 +16,9 @@ {{/* Sort by module to group visually */}} {{ $sorted := sort $endpoints "module" }} {{ $current := "" }} - {{ $seen := newScratch }} {{ range $sorted }} {{ $mod := .module }} + {{/* Set a title for the base endpoints */}} {{ if not $mod }}{{ $mod = "Required" }}{{ end }} {{ if ne $mod $current }} {{ if $current }}{{ end }} @@ -28,16 +28,13 @@ {{ $current = $mod }} {{ end }} {{ $key := printf "%s|%s" .method .anchor }} - {{ if not ($seen.Get $key) }} - {{ $seen.Set $key true }} -
  • - - {{ .method }} - {{ .endpoint }} - {{ if .deprecated }}(deprecated){{ end }} - -
  • - {{ end }} +
  • + + {{ .method }} + {{ .endpoint }} + {{ if .deprecated }}(deprecated){{ end }} + +
  • {{ end }} {{ if $current }}{{ end }} diff --git a/layouts/_partials/openapi/render-operation.html b/layouts/_partials/openapi/render-operation.html index 7ab30a8f..710993b2 100644 --- a/layouts/_partials/openapi/render-operation.html +++ b/layouts/_partials/openapi/render-operation.html @@ -35,10 +35,21 @@ {{ if $page }} {{/* Store each endpoint's metadata in a scratch variable */}} {{ $entry := dict "anchor" $anchor "method" $method "endpoint" $endpoint "summary" $operation_data.summary "deprecated" $operation_data.deprecated "module" $module }} + {{ if not ($page.Scratch.Get "api_endpoints_seen") }} + {{ $page.Scratch.Set "api_endpoints_seen" dict }} + {{ end }} + {{/* Keep a map of seen endpoints. This is necessary as this partial may be + rendered multiple times for the same endpoint (e.g. in the TOC and + in the main content), leading to duplicates. */}} + {{ $seen := $page.Scratch.Get "api_endpoints_seen" }} + {{ $key := printf "%s|%s" $method $endpoint }} + {{ if not (index $seen $key) }} {{ if not (reflect.IsSlice ($page.Scratch.Get "api_endpoints")) }} {{ $page.Scratch.Set "api_endpoints" (slice) }} {{ end }} {{ $page.Scratch.Add "api_endpoints" (slice $entry) }} + {{ $page.Scratch.SetInMap "api_endpoints_seen" $key true }} + {{ end }} {{ end }}
    From 715e66fa00a6fa4e90ef1d55185fe9648527bdda Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Wed, 10 Dec 2025 20:49:17 +0000 Subject: [PATCH 10/10] Improve styling of the endpoints list - Add a hover effect over endpoints - Make the method bold to differentiate it from the endpoint itself - Make cs module titles larger --- assets/scss/_styles_project.scss | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index c0a9c457..9e1f6d6a 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -278,10 +278,17 @@ Custom SCSS for the Matrix spec .endpoint-list a { text-decoration: none; color: inherit; + padding: 0.05rem 0.25rem; + border-radius: 0.2rem; + + &:hover { + background-color: $secondary-background; + } } .endpoint-list .http-api-method { margin-right: 0.35rem; + font-weight: $font-weight-bold; } .endpoint-path { @@ -302,7 +309,8 @@ Custom SCSS for the Matrix spec } .endpoint-module-title { - font-weight: $font-weight-bold; + // font-weight: $font-weight-bold; + font-size: 1.20rem; margin-bottom: 0.35rem; } }