mirror of
https://github.com/matrix-org/matrix-spec
synced 2026-04-02 09:14:10 +02:00
Merge branch 'main'
Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
commit
a26024107e
89
.github/workflows/main.yml
vendored
89
.github/workflows/main.yml
vendored
|
|
@ -1,8 +1,9 @@
|
||||||
name: "Spec"
|
name: "Spec"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
HUGO_VERSION: 0.148.1
|
HUGO_VERSION: 0.153.3
|
||||||
PYTHON_VERSION: 3.13
|
PYTHON_VERSION: 3.13
|
||||||
|
NODE_VERSION: 24
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|
@ -27,7 +28,7 @@ jobs:
|
||||||
- name: "➕ Setup Node"
|
- name: "➕ Setup Node"
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
- name: "🔎 Run validator"
|
- name: "🔎 Run validator"
|
||||||
run: |
|
run: |
|
||||||
npx @redocly/cli@latest lint data/api/*/*.yaml
|
npx @redocly/cli@latest lint data/api/*/*.yaml
|
||||||
|
|
@ -195,11 +196,13 @@ jobs:
|
||||||
needs: [calculate-baseurl, build-openapi, generate-changelog]
|
needs: [calculate-baseurl, build-openapi, generate-changelog]
|
||||||
# run even if generate-changelog was skipped
|
# run even if generate-changelog was skipped
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
|
env:
|
||||||
|
baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}"
|
||||||
steps:
|
steps:
|
||||||
- name: "➕ Setup Node"
|
- name: "➕ Setup Node"
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
- name: "➕ Setup Hugo"
|
- name: "➕ Setup Hugo"
|
||||||
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
|
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
|
||||||
with:
|
with:
|
||||||
|
|
@ -217,8 +220,10 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: changelog-artifact
|
name: changelog-artifact
|
||||||
path: content/changelog
|
path: content/changelog
|
||||||
|
|
||||||
- name: "⚙️ hugo"
|
- name: "⚙️ hugo"
|
||||||
run: hugo --baseURL "${{ needs.calculate-baseurl.outputs.baseURL }}" -d "spec"
|
run: hugo --baseURL "${baseURL}" -d "spec${baseURL}"
|
||||||
|
|
||||||
# We manually unpack the spec OpenAPI definition JSON to the website tree
|
# We manually unpack the spec OpenAPI definition JSON to the website tree
|
||||||
# to make it available to the world in a canonical place:
|
# to make it available to the world in a canonical place:
|
||||||
# https://spec.matrix.org/latest/client-server-api/api.json
|
# https://spec.matrix.org/latest/client-server-api/api.json
|
||||||
|
|
@ -229,10 +234,13 @@ jobs:
|
||||||
name: openapi-artifact
|
name: openapi-artifact
|
||||||
- name: "📝 Unpack the OpenAPI definitions in the right location"
|
- name: "📝 Unpack the OpenAPI definitions in the right location"
|
||||||
run: |
|
run: |
|
||||||
tar -xzf openapi.tar.gz
|
tar -C "spec${baseURL}" --strip-components=1 -xzf openapi.tar.gz
|
||||||
|
|
||||||
- name: "📦 Tarball creation"
|
- name: "📦 Tarball creation"
|
||||||
run: tar -czf spec.tar.gz spec
|
run: |
|
||||||
|
cd spec
|
||||||
|
tar -czf ../spec.tar.gz *
|
||||||
|
|
||||||
- name: "📤 Artifact upload"
|
- name: "📤 Artifact upload"
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
|
@ -243,6 +251,14 @@ jobs:
|
||||||
name: "🔎 Validate generated HTML"
|
name: "🔎 Validate generated HTML"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [calculate-baseurl, build-spec]
|
needs: [calculate-baseurl, build-spec]
|
||||||
|
# Run even if `generate-changelog` was skipped.
|
||||||
|
#
|
||||||
|
# `build-spec` has a dependency on `generate-changelog` to ensure order of execution
|
||||||
|
# and to access `needs.generate-changelog.result`. However, `generate-changelog` is
|
||||||
|
# skipped on tag builds; even a transient dependency on `generate-changelog` is then
|
||||||
|
# enough for this step to also be skipped by default on tag builds. Hence the need for
|
||||||
|
# this explicit `if`.
|
||||||
|
if: ${{ !failure() && !cancelled() }}
|
||||||
steps:
|
steps:
|
||||||
- name: "📥 Source checkout"
|
- name: "📥 Source checkout"
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
@ -253,14 +269,9 @@ jobs:
|
||||||
name: spec-artifact
|
name: spec-artifact
|
||||||
|
|
||||||
- name: "📝 Unpack the spec"
|
- name: "📝 Unpack the spec"
|
||||||
# we have to unpack it into the right path given the baseurl, so that the
|
|
||||||
# links are correct.
|
|
||||||
# eg if baseurl is `/unstable`, we want to put the site in `spec/unstable`.
|
|
||||||
run: |
|
run: |
|
||||||
mkdir -p "spec${baseURL}"
|
mkdir spec
|
||||||
tar -C "spec${baseURL}" --strip-components=1 -xvzf spec.tar.gz
|
tar -C spec -xvzf spec.tar.gz
|
||||||
env:
|
|
||||||
baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}"
|
|
||||||
|
|
||||||
- name: "Run htmltest"
|
- name: "Run htmltest"
|
||||||
uses: wjdp/htmltest-action@master
|
uses: wjdp/htmltest-action@master
|
||||||
|
|
@ -270,13 +281,15 @@ jobs:
|
||||||
build-historical-spec:
|
build-historical-spec:
|
||||||
name: "📖 Build the historical backup spec"
|
name: "📖 Build the historical backup spec"
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-openapi]
|
needs: [calculate-baseurl, build-openapi]
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||||
|
env:
|
||||||
|
baseURL: "${{ needs.calculate-baseurl.outputs.baseURL }}"
|
||||||
steps:
|
steps:
|
||||||
- name: "➕ Setup Node"
|
- name: "➕ Setup Node"
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: ${{ env.NODE_VERSION }}
|
||||||
- name: "➕ Setup Hugo"
|
- name: "➕ Setup Hugo"
|
||||||
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
|
uses: peaceiris/actions-hugo@75d2e84710de30f6ff7268e08f310b60ef14033f # v3.0.0
|
||||||
with:
|
with:
|
||||||
|
|
@ -291,9 +304,8 @@ jobs:
|
||||||
- name: "⚙️ hugo"
|
- name: "⚙️ hugo"
|
||||||
env:
|
env:
|
||||||
HUGO_PARAMS_VERSION_STATUS: "historical"
|
HUGO_PARAMS_VERSION_STATUS: "historical"
|
||||||
# Create a baseURL like `/v1.2` out of the `v1.2` tag
|
|
||||||
run: |
|
run: |
|
||||||
hugo --baseURL "/${GITHUB_REF/refs\/tags\//}" -d "spec"
|
hugo --baseURL "${baseURL}" -d "spec${baseURL}"
|
||||||
|
|
||||||
- name: "📥 Spec definition download"
|
- name: "📥 Spec definition download"
|
||||||
uses: actions/download-artifact@v4
|
uses: actions/download-artifact@v4
|
||||||
|
|
@ -301,12 +313,51 @@ jobs:
|
||||||
name: openapi-artifact
|
name: openapi-artifact
|
||||||
- name: "📝 Unpack the OpenAPI definitions in the right location"
|
- name: "📝 Unpack the OpenAPI definitions in the right location"
|
||||||
run: |
|
run: |
|
||||||
tar -xzf openapi.tar.gz
|
tar -C "spec${baseURL}" --strip-components=1 -xzf openapi.tar.gz
|
||||||
|
|
||||||
- name: "📦 Tarball creation"
|
- name: "📦 Tarball creation"
|
||||||
run: tar -czf spec-historical.tar.gz spec
|
run: |
|
||||||
|
cd spec
|
||||||
|
tar -czf ../spec-historical.tar.gz *
|
||||||
|
|
||||||
- name: "📤 Artifact upload"
|
- name: "📤 Artifact upload"
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: spec-historical-artifact
|
name: spec-historical-artifact
|
||||||
path: spec-historical.tar.gz
|
path: spec-historical.tar.gz
|
||||||
|
|
||||||
|
# If we're building a tag, create a release and publish the artifacts
|
||||||
|
create_release:
|
||||||
|
name: "Create release"
|
||||||
|
if: ${{ !failure() && !cancelled() && startsWith(github.ref, 'refs/tags/') }}
|
||||||
|
needs:
|
||||||
|
- build-spec
|
||||||
|
- build-historical-spec
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: "📥 Check out changelogs"
|
||||||
|
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
|
||||||
|
with:
|
||||||
|
sparse-checkout: |
|
||||||
|
content/changelog
|
||||||
|
- name: "📥 Download built spec"
|
||||||
|
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||||
|
with:
|
||||||
|
name: spec-artifact
|
||||||
|
- name: "📥 Download historical spec artifact"
|
||||||
|
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
|
||||||
|
with:
|
||||||
|
name: spec-historical-artifact
|
||||||
|
- name: "✨ Create draft release"
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
# Remove front-matter from changelog
|
||||||
|
sed '1,/^---$/d' "content/changelog/${{ github.ref_name }}.md" > changelog.md
|
||||||
|
|
||||||
|
# Create a draft release, using the changelog as release notes, and attaching the spec artifacts.
|
||||||
|
gh release create -d -t "${{ github.ref_name }}" \
|
||||||
|
-F "changelog.md" \
|
||||||
|
"${{ github.ref_name }}" \
|
||||||
|
spec.tar.gz \
|
||||||
|
spec-historical.tar.gz
|
||||||
|
|
|
||||||
4
.github/workflows/netlify.yaml
vendored
4
.github/workflows/netlify.yaml
vendored
|
|
@ -45,7 +45,9 @@ jobs:
|
||||||
name: spec-artifact
|
name: spec-artifact
|
||||||
|
|
||||||
- name: "📦 Extract Artifacts"
|
- name: "📦 Extract Artifacts"
|
||||||
run: tar -xzvf spec.tar.gz && rm spec.tar.gz
|
run: |
|
||||||
|
mkdir spec
|
||||||
|
tar -C spec -xzvf spec.tar.gz && rm spec.tar.gz
|
||||||
|
|
||||||
- name: "📤 Deploy to Netlify"
|
- name: "📤 Deploy to Netlify"
|
||||||
id: netlify
|
id: netlify
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ function getHeadings() {
|
||||||
let headings = [];
|
let headings = [];
|
||||||
|
|
||||||
// First get the anchors in the ToC.
|
// First get the anchors in the ToC.
|
||||||
const toc_anchors = document.querySelectorAll("#toc nav a");
|
const toc_anchors = document.querySelectorAll("#TableOfContents a");
|
||||||
|
|
||||||
for (const anchor of toc_anchors) {
|
for (const anchor of toc_anchors) {
|
||||||
// Then get the heading from its selector in the anchor's href.
|
// Then get the heading from its selector in the anchor's href.
|
||||||
|
|
@ -59,7 +59,7 @@ function getHeadings() {
|
||||||
console.error("Got ToC anchor without href");
|
console.error("Got ToC anchor without href");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const heading = document.querySelector(selector);
|
const heading = document.querySelector(selector);
|
||||||
if (!heading) {
|
if (!heading) {
|
||||||
console.error("Heading not found for selector:", selector);
|
console.error("Heading not found for selector:", selector);
|
||||||
|
|
@ -122,13 +122,13 @@ function getCurrentHeading(headings, headerOffset) {
|
||||||
*/
|
*/
|
||||||
function selectTocEntry(id) {
|
function selectTocEntry(id) {
|
||||||
// Deselect previously selected entries.
|
// Deselect previously selected entries.
|
||||||
const activeEntries = document.querySelectorAll("#toc nav a.active");
|
const activeEntries = document.querySelectorAll("#TableOfContents a.active");
|
||||||
for (const activeEntry of activeEntries) {
|
for (const activeEntry of activeEntries) {
|
||||||
activeEntry.classList.remove('active');
|
activeEntry.classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the new entry and select it.
|
// Find the new entry and select it.
|
||||||
const newEntry = document.querySelector(`#toc nav a[href="#${id}"]`);
|
const newEntry = document.querySelector(`#TableOfContents a[href="#${id}"]`);
|
||||||
if (!newEntry) {
|
if (!newEntry) {
|
||||||
console.error("ToC entry not found for ID:", id);
|
console.error("ToC entry not found for ID:", id);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -76,52 +76,126 @@ Custom SCSS for the Matrix spec
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
overscroll-behavior: contain;
|
overscroll-behavior: contain;
|
||||||
|
|
||||||
&>.td-sidebar-nav__section {
|
& > .td-sidebar-nav__section {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
}
|
|
||||||
|
|
||||||
.td-sidebar-nav__section .ul-1 ul {
|
.ul-1 ul {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* This is to make the width of the items that have sub-items (like room versions)
|
|
||||||
the same as the width of items that don't (like changelog) */
|
|
||||||
.pr-md-3, .px-md-3 {
|
|
||||||
padding-right: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ul-1 > li > a {
|
|
||||||
padding-left: 1rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ul-2 > li > a {
|
|
||||||
padding-left: 2rem !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.td-sidebar-link.tree-root {
|
|
||||||
color: $gray-800;
|
|
||||||
font-weight: $font-weight-bold;
|
|
||||||
font-size: 1.3rem;
|
|
||||||
margin-bottom: 0;
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a, a.td-sidebar-link {
|
|
||||||
color: $gray-800;
|
|
||||||
font-weight: $font-weight-normal;
|
|
||||||
padding-top: .2rem;
|
|
||||||
padding-bottom: .2rem;
|
|
||||||
|
|
||||||
display: block;
|
|
||||||
transition: all 100ms ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $secondary-lighter-background;
|
|
||||||
color: $gray-800;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.active, &active:hover {
|
/* This is to make the width of the items that have sub-items (like room versions)
|
||||||
background-color: $secondary-background;
|
the same as the width of items that don't (like changelog) */
|
||||||
|
.pr-md-3, .px-md-3 {
|
||||||
|
padding-right: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ul-1 > li > a {
|
||||||
|
padding-left: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ul-2 > li > a {
|
||||||
|
padding-left: 2rem !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Styles for the table of contents */
|
||||||
|
& > .td-toc {
|
||||||
|
padding-top: 1rem;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
/* Add border above the toc */
|
||||||
|
border-top: 1px solid var(--bs-tertiary-color);
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding-left: 1rem;
|
||||||
|
counter-reset: section;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#TableOfContents {
|
||||||
|
/* Remove the space between the title and the ToC */
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
|
&>ol>li {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
|
||||||
|
&>a {
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ol {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>ol>li>a {
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>ol>li>ol>li>a {
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>ol>li>ol>li>ol>li>a {
|
||||||
|
padding-left: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>ol>li>ol>li>ol>li>ol>li>a {
|
||||||
|
padding-left: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&>ol>li>ol>li>ol>li>ol>li>ol>li>a {
|
||||||
|
padding-left: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
li a:before {
|
||||||
|
counter-increment: section;
|
||||||
|
content: counters(section, ".") " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
.td-toc-title {
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
|
||||||
|
/* Remove the border under the title */
|
||||||
|
border-bottom: 0;
|
||||||
|
/* Remove the space under the title */
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
/* Fix the top of page link color */
|
||||||
|
a, a:hover {
|
||||||
|
color: $secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply the same style to links in the navigation and in the ToC */
|
||||||
|
& > .td-sidebar-nav__section, & > .td-toc #TableOfContents {
|
||||||
|
li a.td-sidebar-link.tree-root {
|
||||||
|
color: $gray-800;
|
||||||
|
font-weight: $font-weight-bold;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
li a, li a.td-sidebar-link {
|
||||||
|
color: $gray-800;
|
||||||
|
font-weight: $font-weight-normal;
|
||||||
|
padding-top: .2rem;
|
||||||
|
padding-bottom: .2rem;
|
||||||
|
|
||||||
|
transition: all 100ms ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: $secondary-lighter-background;
|
||||||
|
color: $gray-800;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active, &active:hover {
|
||||||
|
background-color: $secondary-background;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -199,62 +273,67 @@ Custom SCSS for the Matrix spec
|
||||||
scroll-margin-top: 5.5rem;
|
scroll-margin-top: 5.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for the table of contents */
|
.endpoints-toc {
|
||||||
#toc {
|
summary {
|
||||||
padding-top: .5rem;
|
cursor: pointer;
|
||||||
padding-left: 1.5rem;
|
|
||||||
|
|
||||||
ol {
|
|
||||||
padding-left: 1rem;
|
|
||||||
counter-reset: section;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#TableOfContents {
|
|
||||||
&>ol>li {
|
|
||||||
margin-bottom: .5rem;
|
|
||||||
|
|
||||||
&>a {
|
|
||||||
font-weight: $font-weight-bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ol {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>ol>li>a {
|
|
||||||
padding-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>ol>li>ol>li>a {
|
|
||||||
padding-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>ol>li>ol>li>ol>li>a {
|
|
||||||
padding-left: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>ol>li>ol>li>ol>li>ol>li>a {
|
|
||||||
padding-left: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&>ol>li>ol>li>ol>li>ol>li>ol>li>a {
|
|
||||||
padding-left: 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
li a:before {
|
|
||||||
counter-increment: section;
|
|
||||||
content: counters(section, ".") " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
#toc-title {
|
|
||||||
font-weight: $font-weight-bold;
|
font-weight: $font-weight-bold;
|
||||||
font-size: 1.3rem;
|
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;
|
||||||
|
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 {
|
||||||
|
font-family: $font-family-monospace;
|
||||||
|
color: $secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.endpoint-deprecated {
|
||||||
|
color: $danger;
|
||||||
|
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;
|
||||||
|
font-size: 1.20rem;
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-description {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for alert boxes */
|
/* Styles for alert boxes */
|
||||||
|
|
@ -581,4 +660,4 @@ dd {
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ $primary: #FFF;
|
||||||
$secondary: #0098D4;
|
$secondary: #0098D4;
|
||||||
$dark: #333;
|
$dark: #333;
|
||||||
$gray-100: #FBFBFB;
|
$gray-100: #FBFBFB;
|
||||||
|
$code-color: #005b7f;
|
||||||
|
|
||||||
$secondary-background: #E5F5FB;
|
$secondary-background: #E5F5FB;
|
||||||
$secondary-lighter-background: #F4FAFC;
|
$secondary-lighter-background: #F4FAFC;
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Fix JSON formatting in the "Server admin style permissions" examples.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326).
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Remove legacy mentions, as per [MSC4210](https://github.com/matrix-org/matrix-spec-proposals/issues/4210).
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Push rule IDs are globally unique within their kind.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Don't advertise `creator` field in description of room creation.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
`room_id` is required for peeking via `/_matrix/client/v3/events`.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
The `server-name` segment of MXC URIs is sanitised differently from the `media-id` segment.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326).
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add note to each endpoint that uses capability negotiation.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Fix various typos throughout the specification.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Additional OpenGraph properties can be present in URL previews.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Fix various typos throughout the specification.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify the special casing of membership events and redactions in power levels.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
`M_RESOURCE_LIMIT_EXCEEDED` is now listed as a common error code.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add `m.login.terms` to enumeration of authentication types.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add the `m.oauth` authentication type for User-Interactive Authentication as per [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312).
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify how to use `state_after` ahead of declaring full support for its spec version.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
`device_one_time_keys_count` is only optional if no unclaimed one-time keys exist.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Clarify that servers may choose not to use `M_USER_DEACTIVATED` at login time, for example for privacy reasons when they can't authenticate deactivated users.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Minor grammatical fix in the Secrets module description.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Usage of the `event_id_only` format for push notifications is not mandatory.
|
|
||||||
1
changelogs/client_server/newsfragments/2270.feature
Normal file
1
changelogs/client_server/newsfragments/2270.feature
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add the account management capabilities for the OAuth 2.0 authentication API, as per [MSC4191](https://github.com/matrix-org/matrix-spec-proposals/pull/4191).
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
The optional `submit_url` response parameter of the `/requestToken` endpoints uses the same request
|
||||||
|
and response parameters and error codes as the Identity Service API's `POST /_matrix/identity/v2/validate/email/submitToken`,
|
||||||
|
as per [MSC4183](https://github.com/matrix-org/matrix-spec-proposals/pull/4183).
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Update non-historic mentions of matrix-doc repo to matrix-spec/-proposals. Contributed by @HarHarLinks.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Remove unintended TeX formatting. Contributed by @HarHarLinks.
|
||||||
1
changelogs/client_server/newsfragments/2291.feature
Normal file
1
changelogs/client_server/newsfragments/2291.feature
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Add `m.recent_emoji` account data event to track recently used emoji as per [MSC4356](https://github.com/matrix-org/matrix-spec-proposals/pull/4356).
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
Clarify the error codes that can be returned with a 400 HTTP status code by the `POST /_matrix/identity/v2/validate/email/submitToken`
|
||||||
|
and `POST /_matrix/identity/v2/validate/msisdn/submitToken` endpoints, introducing the `M_TOKEN_INCORRECT`
|
||||||
|
error code, as per [MSC4183](https://github.com/matrix-org/matrix-spec-proposals/pull/4183).
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Swapped icon for X (fka. twitter) to updated logo in footer.
|
|
||||||
1
changelogs/internal/newsfragments/2222.clarification
Normal file
1
changelogs/internal/newsfragments/2222.clarification
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Clarify vendor prefixing requirements.
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Inline Olm & Megolm specifications.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Silence failing redocly-cli rule.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Use NPM Trusted Publishers for publishing `@matrix-org/spec` to npm.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Inline Olm & Megolm specifications.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Inline Olm & Megolm specifications.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Add version picker in the navbar.
|
|
||||||
1
changelogs/internal/newsfragments/2275.clarification
Normal file
1
changelogs/internal/newsfragments/2275.clarification
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Auto-create draft releases when building release tags.
|
||||||
1
changelogs/internal/newsfragments/2276.feature
Normal file
1
changelogs/internal/newsfragments/2276.feature
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Include the spec release version in the filenames in the tarballs generated by CI.
|
||||||
1
changelogs/internal/newsfragments/2282.clarification
Normal file
1
changelogs/internal/newsfragments/2282.clarification
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Replace the Twitter link in the footer with our BlueSky and Mastodon socials.
|
||||||
1
changelogs/internal/newsfragments/2287.clarification
Normal file
1
changelogs/internal/newsfragments/2287.clarification
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Upgrade to docsy v0.13.0.
|
||||||
1
changelogs/internal/newsfragments/2289.clarification
Normal file
1
changelogs/internal/newsfragments/2289.clarification
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Updates to the release documentation.
|
||||||
1
changelogs/internal/newsfragments/2290.clarification
Normal file
1
changelogs/internal/newsfragments/2290.clarification
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
Remove unused leftover CSS files.
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
In room versions 8 through 12, clarify that "sufficient permission to invite users" on restricted joins also includes being a joined member of the room.
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
In room versions 3 through 12, clarify that when you have the power to redact, it is possible to redact events that you don't have the power to send.
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Specify that callers of `/_matrix/federation/v1/openid/userinfo` must validate the returned user ID.
|
||||||
|
|
@ -75,8 +75,8 @@ status = "unstable"
|
||||||
current_version_url = "https://spec.matrix.org/latest"
|
current_version_url = "https://spec.matrix.org/latest"
|
||||||
# The following is used when status = "stable", and is displayed in various UI elements on a released version
|
# The following is used when status = "stable", and is displayed in various UI elements on a released version
|
||||||
# of the spec.
|
# of the spec.
|
||||||
# major = "1"
|
#major = "1"
|
||||||
# minor = "16"
|
#minor = "17"
|
||||||
|
|
||||||
[[params.versions]]
|
[[params.versions]]
|
||||||
# We must include this parameter to enable docsy's version picker in the navbar. The picker
|
# We must include this parameter to enable docsy's version picker in the navbar. The picker
|
||||||
|
|
@ -106,25 +106,30 @@ sidebar_menu_compact = true
|
||||||
# desc = "Matrix on GitHub"
|
# desc = "Matrix on GitHub"
|
||||||
# Custom links shown in the center of the footer. (Only supported by our fork of docsy's 'footer/central' partial.)
|
# Custom links shown in the center of the footer. (Only supported by our fork of docsy's 'footer/central' partial.)
|
||||||
[[params.links.bottom]]
|
[[params.links.bottom]]
|
||||||
name = "GitHub"
|
name = "GitHub"
|
||||||
url = "https://github.com/matrix-org"
|
url = "https://github.com/matrix-org"
|
||||||
icon = "fab fa-github"
|
icon = "fab fa-github"
|
||||||
desc = "Matrix on GitHub"
|
desc = "Matrix on GitHub"
|
||||||
[[params.links.bottom]]
|
[[params.links.bottom]]
|
||||||
name = "GitLab"
|
name = "GitLab"
|
||||||
url = "https://gitlab.matrix.org/matrix-org"
|
url = "https://gitlab.matrix.org/matrix-org"
|
||||||
icon = "fab fa-gitlab"
|
icon = "fab fa-gitlab"
|
||||||
desc = "Matrix on GitLab"
|
desc = "Matrix on GitLab"
|
||||||
[[params.links.bottom]]
|
[[params.links.bottom]]
|
||||||
name = "YouTube"
|
name = "YouTube"
|
||||||
url = "https://www.youtube.com/channel/UCVFkW-chclhuyYRbmmfwt6w"
|
url = "https://www.youtube.com/channel/UCVFkW-chclhuyYRbmmfwt6w"
|
||||||
icon = "fab fa-youtube"
|
icon = "fab fa-youtube"
|
||||||
desc = "Matrix YouTube channel"
|
desc = "Matrix YouTube channel"
|
||||||
[[params.links.bottom]]
|
[[params.links.bottom]]
|
||||||
name = "Twitter"
|
name = "Mastodon"
|
||||||
url = "https://twitter.com/matrixdotorg"
|
url = "https://mastodon.matrix.org/@matrix"
|
||||||
icon = "fab fa-x-twitter"
|
icon = "fab fa-mastodon"
|
||||||
desc = "Matrix on Twitter"
|
desc = "Matrix on Mastodon"
|
||||||
|
[[params.links.bottom]]
|
||||||
|
name = "Bluesky"
|
||||||
|
url = "https://bsky.app/profile/matrix.org"
|
||||||
|
icon = "fab fa-bluesky"
|
||||||
|
desc = "Matrix on Bluesky"
|
||||||
|
|
||||||
|
|
||||||
# configuration for the hugo development server
|
# configuration for the hugo development server
|
||||||
|
|
@ -161,3 +166,11 @@ sidebar_menu_compact = true
|
||||||
mediaType = "text/markdown"
|
mediaType = "text/markdown"
|
||||||
isPlainText = true
|
isPlainText = true
|
||||||
baseName = "checklist"
|
baseName = "checklist"
|
||||||
|
|
||||||
|
# Add font media types for downloading KaTeX fonts.
|
||||||
|
# See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#create-media-types-for-katex-fonts
|
||||||
|
[mediaTypes]
|
||||||
|
[mediaTypes.'font/woff']
|
||||||
|
suffixes = ['woff']
|
||||||
|
[mediaTypes.'font/woff2']
|
||||||
|
suffixes = ['woff2']
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,14 @@
|
||||||
title: "Application Service API"
|
title: "Application Service API"
|
||||||
weight: 30
|
weight: 30
|
||||||
type: docs
|
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
|
||||||
|
|
||||||
Application services are passive and can only observe events from the
|
Application services are passive and can only observe events from the
|
||||||
|
|
@ -428,6 +426,8 @@ imports and similar behaviour).
|
||||||
|
|
||||||
#### Server admin style permissions
|
#### Server admin style permissions
|
||||||
|
|
||||||
|
{{% changed-in v="1.17" %}}
|
||||||
|
|
||||||
The homeserver needs to give the application service *full control* over
|
The homeserver needs to give the application service *full control* over
|
||||||
its namespace, both for users and for room aliases. This means that the
|
its namespace, both for users and for room aliases. This means that the
|
||||||
AS should be able to manage any users and room alias in its namespace. No additional API
|
AS should be able to manage any users and room alias in its namespace. No additional API
|
||||||
|
|
@ -444,33 +444,59 @@ achieved by including the `as_token` on a `/register` request, along
|
||||||
with a login type of `m.login.application_service` to set the desired
|
with a login type of `m.login.application_service` to set the desired
|
||||||
user ID without a password.
|
user ID without a password.
|
||||||
|
|
||||||
POST /_matrix/client/v3/register
|
```http
|
||||||
Authorization: Bearer YourApplicationServiceTokenHere
|
POST /_matrix/client/v3/register
|
||||||
|
Authorization: Bearer YourApplicationServiceTokenHere
|
||||||
|
```
|
||||||
|
|
||||||
Content:
|
```json
|
||||||
{
|
{
|
||||||
"type": "m.login.application_service",
|
"type": "m.login.application_service",
|
||||||
"username": "_irc_example"
|
"username": "_irc_example"
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Similarly, logging in as users needs API changes in order to allow the AS to
|
{{% boxes/note %}}
|
||||||
log in without needing the user's password. This is achieved by including the
|
{{% added-in v="1.17" %}}
|
||||||
`as_token` on a `/login` request, along with a login type of
|
Servers MUST still allow application services to use the `/register` endpoint
|
||||||
`m.login.application_service`:
|
with a login type of `m.login.application_service` even if they don't support
|
||||||
|
the [Legacy Authentication API](/client-server-api/#legacy-api).
|
||||||
|
|
||||||
|
In that case application services MUST set the `"inhibit_login": true` parameter
|
||||||
|
as they cannot use it to log in as users. If the `inhibit_login` parameter is
|
||||||
|
not set to `true`, the server MUST return a 400 HTTP status code with an
|
||||||
|
`M_APPSERVICE_LOGIN_UNSUPPORTED` error code.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
|
Similarly, logging in as users using the [Legacy authentication API](/client-server-api/#legacy-api)
|
||||||
|
needs API changes in order to allow the AS to log in without needing the user's
|
||||||
|
password. This is achieved by including the `as_token` on a `/login` request,
|
||||||
|
along with a login type of `m.login.application_service`:
|
||||||
|
|
||||||
{{% added-in v="1.2" %}}
|
{{% added-in v="1.2" %}}
|
||||||
|
|
||||||
POST /_matrix/client/v3/login
|
```http
|
||||||
Authorization: Bearer YourApplicationServiceTokenHere
|
POST /_matrix/client/v3/login
|
||||||
|
Authorization: Bearer YourApplicationServiceTokenHere
|
||||||
|
```
|
||||||
|
|
||||||
Content:
|
```json
|
||||||
{
|
{
|
||||||
"type": "m.login.application_service",
|
"type": "m.login.application_service",
|
||||||
"identifier": {
|
"identifier": {
|
||||||
"type": "m.id.user",
|
"type": "m.id.user",
|
||||||
"user": "_irc_example"
|
"user": "_irc_example"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
{{% added-in v="1.17" %}}
|
||||||
|
Application services MUST NOT use the `/login` endpoint if the server doesn't
|
||||||
|
support the Legacy authentication API. If `/login` is called with the
|
||||||
|
`m.login.application_service` login type the server MUST return a 400 HTTP
|
||||||
|
status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
Application services which attempt to create users or aliases *outside*
|
Application services which attempt to create users or aliases *outside*
|
||||||
of their defined namespaces, or log in as users outside of their defined
|
of their defined namespaces, or log in as users outside of their defined
|
||||||
|
|
@ -512,6 +538,38 @@ client-server endpoint.
|
||||||
|
|
||||||
{{% http-api spec="client-server" api="appservice_room_directory" %}}
|
{{% http-api spec="client-server" api="appservice_room_directory" %}}
|
||||||
|
|
||||||
|
#### Device management
|
||||||
|
|
||||||
|
{{% added-in v="1.17" %}}
|
||||||
|
|
||||||
|
Application services need to be able to create and delete devices to manage the
|
||||||
|
encryption for their users without having to rely on `/login`, which also
|
||||||
|
generates an access token for the user, and which might not be available for
|
||||||
|
homeservers that only support the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||||
|
|
||||||
|
##### Creating devices
|
||||||
|
|
||||||
|
Application services can use the [`PUT /_matrix/client/v3/devices/{deviceId}`](/client-server-api/#put_matrixclientv3devicesdeviceid)
|
||||||
|
endpoint to create new devices.
|
||||||
|
|
||||||
|
##### Deleting devices
|
||||||
|
|
||||||
|
The following endpoints used to delete devices MUST NOT require [User-Interactive
|
||||||
|
Authentication](/client-server-api/#user-interactive-authentication-api) when
|
||||||
|
used by an application service:
|
||||||
|
|
||||||
|
* [`DELETE /_matrix/client/v3/devices/{deviceId}`](/client-server-api/#delete_matrixclientv3devicesdeviceid)
|
||||||
|
* [`POST /_matrix/client/v3/delete_devices`](/client-server-api/#post_matrixclientv3delete_devices)
|
||||||
|
|
||||||
|
#### Cross-signing
|
||||||
|
|
||||||
|
{{% added-in v="1.17" %}}
|
||||||
|
|
||||||
|
Appservices need to be able to verify themselves and replace their cross-signing
|
||||||
|
keys, so the [`POST /_matrix/client/v3/keys/device_signing/upload`](/client-server-api/#post_matrixclientv3keysdevice_signingupload)
|
||||||
|
endpoint MUST NOT require [User-Interactive Authentication](/client-server-api/#user-interactive-authentication-api)
|
||||||
|
when used by an application service, even if cross-signing keys already exist.
|
||||||
|
|
||||||
### Referencing messages from a third-party network
|
### Referencing messages from a third-party network
|
||||||
|
|
||||||
Application services should include an `external_url` in the `content`
|
Application services should include an `external_url` in the `content`
|
||||||
|
|
|
||||||
91
content/changelog/v1.17.md
Normal file
91
content/changelog/v1.17.md
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
---
|
||||||
|
title: v1.17 Changelog
|
||||||
|
linkTitle: v1.17
|
||||||
|
type: docs
|
||||||
|
layout: changelog
|
||||||
|
outputs:
|
||||||
|
- html
|
||||||
|
- checklist
|
||||||
|
date: 2025-12-18
|
||||||
|
---
|
||||||
|
|
||||||
|
## Client-Server API
|
||||||
|
|
||||||
|
**Removed Endpoints**
|
||||||
|
|
||||||
|
- Remove legacy mentions, as per [MSC4210](https://github.com/matrix-org/matrix-spec-proposals/issues/4210). ([#2186](https://github.com/matrix-org/matrix-spec/issues/2186))
|
||||||
|
|
||||||
|
**Backwards Compatible Changes**
|
||||||
|
|
||||||
|
- Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). ([#2221](https://github.com/matrix-org/matrix-spec/issues/2221))
|
||||||
|
- Add the `m.oauth` authentication type for User-Interactive Authentication, as per [MSC4312](https://github.com/matrix-org/matrix-spec-proposals/pull/4312). ([#2234](https://github.com/matrix-org/matrix-spec/issues/2234))
|
||||||
|
- Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). ([#2267](https://github.com/matrix-org/matrix-spec/issues/2267))
|
||||||
|
|
||||||
|
**Spec Clarifications**
|
||||||
|
|
||||||
|
- Push rule IDs are globally unique within their kind. ([#2214](https://github.com/matrix-org/matrix-spec/issues/2214))
|
||||||
|
- Don't advertise `creator` field in description of room creation. ([#2215](https://github.com/matrix-org/matrix-spec/issues/2215))
|
||||||
|
- `room_id` is required for peeking via `/_matrix/client/v3/events`. ([#2216](https://github.com/matrix-org/matrix-spec/issues/2216))
|
||||||
|
- The `server-name` segment of MXC URIs is sanitised differently from the `media-id` segment. ([#2217](https://github.com/matrix-org/matrix-spec/issues/2217))
|
||||||
|
- Add note to each endpoint that uses capability negotiation. ([#2223](https://github.com/matrix-org/matrix-spec/issues/2223))
|
||||||
|
- Additional OpenGraph properties can be present in URL previews. ([#2225](https://github.com/matrix-org/matrix-spec/issues/2225))
|
||||||
|
- Clarify the special casing of membership events and redactions in power levels. ([#2231](https://github.com/matrix-org/matrix-spec/issues/2231))
|
||||||
|
- `M_RESOURCE_LIMIT_EXCEEDED` is now listed as a common error code. ([#2232](https://github.com/matrix-org/matrix-spec/issues/2232))
|
||||||
|
- Add `m.login.terms` to enumeration of authentication types. ([#2233](https://github.com/matrix-org/matrix-spec/issues/2233))
|
||||||
|
- Clarify how to use `state_after` ahead of declaring full support for its spec version. ([#2240](https://github.com/matrix-org/matrix-spec/issues/2240))
|
||||||
|
- `device_one_time_keys_count` is only optional if no unclaimed one-time keys exist. ([#2245](https://github.com/matrix-org/matrix-spec/issues/2245))
|
||||||
|
- Clarify that servers may choose not to use `M_USER_DEACTIVATED` at login time, for example for privacy reasons when they can't authenticate deactivated users. ([#2246](https://github.com/matrix-org/matrix-spec/issues/2246))
|
||||||
|
- Usage of the `event_id_only` format for push notifications is not mandatory. ([#2255](https://github.com/matrix-org/matrix-spec/issues/2255))
|
||||||
|
- Fix various typos throughout the specification. ([#2224](https://github.com/matrix-org/matrix-spec/issues/2224), [#2227](https://github.com/matrix-org/matrix-spec/issues/2227), [#2250](https://github.com/matrix-org/matrix-spec/issues/2250))
|
||||||
|
|
||||||
|
|
||||||
|
## Server-Server API
|
||||||
|
|
||||||
|
No significant changes.
|
||||||
|
|
||||||
|
|
||||||
|
## Application Service API
|
||||||
|
|
||||||
|
**Backwards Compatible Changes**
|
||||||
|
|
||||||
|
- Allow application services to masquerade as specific devices belonging to users, as per [MSC4326](https://github.com/matrix-org/matrix-spec-proposals/pull/4326). ([#2221](https://github.com/matrix-org/matrix-spec/issues/2221))
|
||||||
|
- Allow application services to manage devices and register users without the legacy authentication API, as per [MSC4190](https://github.com/matrix-org/matrix-spec-proposals/pull/4190). ([#2267](https://github.com/matrix-org/matrix-spec/issues/2267))
|
||||||
|
|
||||||
|
**Spec Clarifications**
|
||||||
|
|
||||||
|
- Fix JSON formatting in the "Server admin style permissions" examples. ([#2213](https://github.com/matrix-org/matrix-spec/issues/2213))
|
||||||
|
|
||||||
|
|
||||||
|
## Identity Service API
|
||||||
|
|
||||||
|
No significant changes.
|
||||||
|
|
||||||
|
|
||||||
|
## Push Gateway API
|
||||||
|
|
||||||
|
No significant changes.
|
||||||
|
|
||||||
|
|
||||||
|
## Room Versions
|
||||||
|
|
||||||
|
**Spec Clarifications**
|
||||||
|
|
||||||
|
- In room versions 8 through 12, clarify that "sufficient permission to invite users" on restricted joins also includes being a joined member of the room. ([#2220](https://github.com/matrix-org/matrix-spec/issues/2220))
|
||||||
|
- In room versions 3 through 12, clarify that when you have the power to redact, it is possible to redact events that you don't have the power to send. ([#2249](https://github.com/matrix-org/matrix-spec/issues/2249))
|
||||||
|
|
||||||
|
|
||||||
|
## Appendices
|
||||||
|
|
||||||
|
No significant changes.
|
||||||
|
|
||||||
|
|
||||||
|
## Internal Changes/Tooling
|
||||||
|
|
||||||
|
**Spec Clarifications**
|
||||||
|
|
||||||
|
- Swapped icon for X (fka. twitter) to updated logo in footer. ([#2219](https://github.com/matrix-org/matrix-spec/issues/2219))
|
||||||
|
- Inline Olm & Megolm specifications. ([#2226](https://github.com/matrix-org/matrix-spec/issues/2226), [#2241](https://github.com/matrix-org/matrix-spec/issues/2241), [#2242](https://github.com/matrix-org/matrix-spec/issues/2242))
|
||||||
|
- Silence failing redocly-cli rule. ([#2238](https://github.com/matrix-org/matrix-spec/issues/2238))
|
||||||
|
- Use NPM Trusted Publishers for publishing `@matrix-org/spec` to npm. ([#2239](https://github.com/matrix-org/matrix-spec/issues/2239))
|
||||||
|
- Add version picker in the navbar. ([#2256](https://github.com/matrix-org/matrix-spec/issues/2256), [#2258](https://github.com/matrix-org/matrix-spec/issues/2258), [#2259](https://github.com/matrix-org/matrix-spec/issues/2259), [#2260](https://github.com/matrix-org/matrix-spec/issues/2260), [#2261](https://github.com/matrix-org/matrix-spec/issues/2261), [#2264](https://github.com/matrix-org/matrix-spec/issues/2264), [#2268](https://github.com/matrix-org/matrix-spec/issues/2268))
|
||||||
|
- Add a list of endpoints to the top of each spec page. ([#2262](https://github.com/matrix-org/matrix-spec/issues/2262))
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
title: "Client-Server API"
|
title: "Client-Server API"
|
||||||
weight: 10
|
weight: 10
|
||||||
type: docs
|
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
|
## API Standards
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
|
|
@ -477,8 +477,7 @@ the API that was used to obtain their current access token.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API,
|
Currently the OAuth 2.0 API doesn't cover all the use cases of the legacy API,
|
||||||
such as automated applications that cannot use a web browser, or
|
such as automated applications that cannot use a web browser.
|
||||||
user management by [application services](application-service-api/#server-admin-style-permissions).
|
|
||||||
{{% /boxes/note %}}
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
|
|
@ -509,6 +508,12 @@ user must do that directly in the homeserver's web UI. However, the client can
|
||||||
signal to the homeserver that the user wishes to create a new account with the
|
signal to the homeserver that the user wishes to create a new account with the
|
||||||
[`prompt=create`](#user-registration) parameter during authorization.
|
[`prompt=create`](#user-registration) parameter during authorization.
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
{{% added-in v="1.17" %}}
|
||||||
|
Application services can use the `/register` endpoint to create users regardless
|
||||||
|
of the authentication API supported by the homeserver.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
### Login
|
### Login
|
||||||
|
|
||||||
With the legacy API, a client can obtain an access token by using one of the
|
With the legacy API, a client can obtain an access token by using one of the
|
||||||
|
|
@ -647,7 +652,7 @@ manage their account like [changing their password](#password-management),
|
||||||
[deactivating their account](#account-deactivation).
|
[deactivating their account](#account-deactivation).
|
||||||
|
|
||||||
With the OAuth 2.0 API, all account management is done via the homeserver's web
|
With the OAuth 2.0 API, all account management is done via the homeserver's web
|
||||||
UI.
|
UI that can be accessed by users via the [account management URL](#oauth-20-account-management).
|
||||||
|
|
||||||
### Legacy API
|
### Legacy API
|
||||||
|
|
||||||
|
|
@ -1574,6 +1579,10 @@ If the access token does correspond to an appservice, but the user id does
|
||||||
not lie within its namespace then the homeserver will respond with an
|
not lie within its namespace then the homeserver will respond with an
|
||||||
errcode of `M_EXCLUSIVE`.
|
errcode of `M_EXCLUSIVE`.
|
||||||
|
|
||||||
|
{{% added-in v="1.17" %}} If this login type is used and the server doesn't
|
||||||
|
support logging in via the Legacy authentication API, it MUST return a 400 HTTP
|
||||||
|
status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code.
|
||||||
|
|
||||||
##### Login Fallback
|
##### Login Fallback
|
||||||
|
|
||||||
If a client does not recognize any or all login flows it can use the
|
If a client does not recognize any or all login flows it can use the
|
||||||
|
|
@ -2340,6 +2349,46 @@ The server SHOULD return one of the following responses:
|
||||||
- For other errors, the server returns a `400 Bad Request` response with error
|
- For other errors, the server returns a `400 Bad Request` response with error
|
||||||
details
|
details
|
||||||
|
|
||||||
|
#### Account management {id="oauth-20-account-management"}
|
||||||
|
|
||||||
|
{{% added-in v="1.18" %}}
|
||||||
|
|
||||||
|
All account management is done via the homeserver's web UI.
|
||||||
|
|
||||||
|
This specification defines extensions to the [OAuth Authorization Server
|
||||||
|
Metadata registry](https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#authorization-server-metadata)
|
||||||
|
to offer clients a way to deep-link to the account management capabilities of
|
||||||
|
the homeserver to allow the user to complete the account management operations
|
||||||
|
in a browser.
|
||||||
|
|
||||||
|
##### Account management URL discovery
|
||||||
|
|
||||||
|
The [OAuth 2.0 authorization server metadata](#server-metadata-discovery) is
|
||||||
|
extended to include the following **optional** fields.
|
||||||
|
|
||||||
|
{{% definition path="schemas/oauth2-account-management-server-metadata" %}}
|
||||||
|
|
||||||
|
##### Account management URL parameters
|
||||||
|
|
||||||
|
The account management URL MAY accept the following minimum query parameters.
|
||||||
|
|
||||||
|
{{% definition path="schemas/oauth2-account-management-url" %}}
|
||||||
|
|
||||||
|
##### Account management URL actions
|
||||||
|
|
||||||
|
Account management actions are unique to the application. They SHOULD follow the
|
||||||
|
[Common Namespaced Identifier Grammar](/appendices/#common-namespaced-identifier-grammar)
|
||||||
|
where feasible. The Matrix-specific actions are:
|
||||||
|
|
||||||
|
| Action | Description |
|
||||||
|
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| `org.matrix.profile` | The user wishes to view/edit their profile (name, avatar, contact details). |
|
||||||
|
| `org.matrix.devices_list` | The user wishes to view a list of their devices. |
|
||||||
|
| `org.matrix.device_view` | The user wishes to view the details of a specific device. A `device_id` SHOULD be provided. |
|
||||||
|
| `org.matrix.device_delete` | The user wishes to delete/log out a specific device. A `device_id` SHOULD be provided. |
|
||||||
|
| `org.matrix.account_deactivate` | The user wishes to deactivate their account. |
|
||||||
|
| `org.matrix.cross_signing_reset` | The user wishes to reset their cross-signing identity. Servers SHOULD use this action in the URL of the [`m.oauth`](#oauth-authentication) UIA type. |
|
||||||
|
|
||||||
### Account moderation
|
### Account moderation
|
||||||
|
|
||||||
#### Account locking
|
#### Account locking
|
||||||
|
|
@ -3967,6 +4016,7 @@ that profile.
|
||||||
| [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional |
|
| [Guest Access](#guest-access) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
|
| [Moderation Policy Lists](#moderation-policy-lists) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional |
|
| [OpenID](#openid) | Optional | Optional | Optional | Optional | Optional |
|
||||||
|
| [Recently used emoji](#recently-used-emoji) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |
|
| [Reference Relations](#reference-relations) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Reporting Content](#reporting-content) | Optional | Optional | Optional | Optional | Optional |
|
| [Reporting Content](#reporting-content) | Optional | Optional | Optional | Optional | Optional |
|
||||||
| [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional |
|
| [Rich replies](#rich-replies) | Optional | Optional | Optional | Optional | Optional |
|
||||||
|
|
@ -4031,42 +4081,43 @@ operations and run in a resource constrained environment. Like embedded
|
||||||
applications, they are not intended to be fully-fledged communication
|
applications, they are not intended to be fully-fledged communication
|
||||||
systems.
|
systems.
|
||||||
|
|
||||||
{{% cs-module name="instant_messaging" %}}
|
{{% cs-module name="Instant Messaging" filename="instant_messaging" %}}
|
||||||
{{% cs-module name="rich_replies" %}}
|
{{% cs-module name="Rich replies" filename="rich_replies" %}}
|
||||||
{{% cs-module name="voip_events" %}}
|
{{% cs-module name="Voice over IP" filename="voip_events" %}}
|
||||||
{{% cs-module name="typing_notifications" %}}
|
{{% cs-module name="Typing Notifications" filename="typing_notifications" %}}
|
||||||
{{% cs-module name="receipts" %}}
|
{{% cs-module name="Receipts" filename="receipts" %}}
|
||||||
{{% cs-module name="read_markers" %}}
|
{{% cs-module name="Read and unread markers" filename="read_markers" %}}
|
||||||
{{% cs-module name="presence" %}}
|
{{% cs-module name="Presence" filename="presence" %}}
|
||||||
{{% cs-module name="content_repo" %}}
|
{{% cs-module name="Content repository" filename="content_repo" %}}
|
||||||
{{% cs-module name="send_to_device" %}}
|
{{% cs-module name="Send-to-Device messaging" filename="send_to_device" %}}
|
||||||
{{% cs-module name="device_management" %}}
|
{{% cs-module name="Device Management" filename="device_management" %}}
|
||||||
{{% cs-module name="end_to_end_encryption" %}}
|
{{% cs-module name="End-to-End Encryption" filename="end_to_end_encryption" %}}
|
||||||
{{% cs-module name="secrets" %}}
|
{{% cs-module name="Secrets" filename="secrets" %}}
|
||||||
{{% cs-module name="history_visibility" %}}
|
{{% cs-module name="Room History Visibility" filename="history_visibility" %}}
|
||||||
{{% cs-module name="push" %}}
|
{{% cs-module name="Push Notifications" filename="push" %}}
|
||||||
{{% cs-module name="third_party_invites" %}}
|
{{% cs-module name="Third-party invites" filename="third_party_invites" %}}
|
||||||
{{% cs-module name="search" %}}
|
{{% cs-module name="Server Side Search" filename="search" %}}
|
||||||
{{% cs-module name="guest_access" %}}
|
{{% cs-module name="Guest Access" filename="guest_access" %}}
|
||||||
{{% cs-module name="room_previews" %}}
|
{{% cs-module name="Room Previews" filename="room_previews" %}}
|
||||||
{{% cs-module name="tags" %}}
|
{{% cs-module name="Room Tagging" filename="tags" %}}
|
||||||
{{% cs-module name="account_data" %}}
|
{{% cs-module name="Client Config" filename="account_data" %}}
|
||||||
{{% cs-module name="admin" %}}
|
{{% cs-module name="Server Administration" filename="admin" %}}
|
||||||
{{% cs-module name="event_context" %}}
|
{{% cs-module name="Event Context" filename="event_context" %}}
|
||||||
{{% cs-module name="sso_login" %}}
|
{{% cs-module name="SSO client login/authentication" filename="sso_login" %}}
|
||||||
{{% cs-module name="dm" %}}
|
{{% cs-module name="Direct Messaging" filename="dm" %}}
|
||||||
{{% cs-module name="ignore_users" %}}
|
{{% cs-module name="Ignoring Users" filename="ignore_users" %}}
|
||||||
{{% cs-module name="stickers" %}}
|
{{% cs-module name="Sticker Messages" filename="stickers" %}}
|
||||||
{{% cs-module name="report_content" %}}
|
{{% cs-module name="Reporting Content" filename="report_content" %}}
|
||||||
{{% cs-module name="third_party_networks" %}}
|
{{% cs-module name="Third-party Networks" filename="third_party_networks" %}}
|
||||||
{{% cs-module name="openid" %}}
|
{{% cs-module name="OpenID" filename="openid" %}}
|
||||||
{{% cs-module name="server_acls" %}}
|
{{% cs-module name="Server Access Control Lists (ACLs) for rooms" filename="server_acls" %}}
|
||||||
{{% cs-module name="mentions" %}}
|
{{% cs-module name="User and room mentions" filename="mentions" %}}
|
||||||
{{% cs-module name="room_upgrades" %}}
|
{{% cs-module name="Room Upgrades" filename="room_upgrades" %}}
|
||||||
{{% cs-module name="server_notices" %}}
|
{{% cs-module name="Server Notices" filename="server_notices" %}}
|
||||||
{{% cs-module name="moderation_policies" %}}
|
{{% cs-module name="Moderation policy lists" filename="moderation_policies" %}}
|
||||||
{{% cs-module name="spaces" %}}
|
{{% cs-module name="Spaces" filename="spaces" %}}
|
||||||
{{% cs-module name="event_replacements" %}}
|
{{% cs-module name="Event replacements" filename="event_replacements" %}}
|
||||||
{{% cs-module name="event_annotations" %}}
|
{{% cs-module name="Event annotations and reactions" filename="event_annotations" %}}
|
||||||
{{% cs-module name="threading" %}}
|
{{% cs-module name="Recently used emoji" filename="recent_emoji" %}}
|
||||||
{{% cs-module name="reference_relations" %}}
|
{{% cs-module name="Threading" filename="threading" %}}
|
||||||
|
{{% cs-module name="Reference relations" filename="reference_relations" %}}
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ Matrix 1.12 is expected to be released in the July-September 2024 calendar quart
|
||||||
The homeserver SHOULD be able to supply thumbnails for uploaded images
|
The homeserver SHOULD be able to supply thumbnails for uploaded images
|
||||||
and videos. The exact file types which can be thumbnailed are not
|
and videos. The exact file types which can be thumbnailed are not
|
||||||
currently specified - see [Issue
|
currently specified - see [Issue
|
||||||
\#1938](https://github.com/matrix-org/matrix-doc/issues/1938) for more
|
\#1938](https://github.com/matrix-org/matrix-spec/issues/453) for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
The thumbnail methods are "crop" and "scale". "scale" tries to return an
|
The thumbnail methods are "crop" and "scale". "scale" tries to return an
|
||||||
|
|
|
||||||
|
|
@ -921,7 +921,7 @@ collaborate to create a common set of translations for all languages.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
{{% boxes/note %}}
|
||||||
Known translations for the emoji are available from
|
Known translations for the emoji are available from
|
||||||
<https://github.com/matrix-org/matrix-doc/blob/master/data-definitions/>
|
<https://github.com/matrix-org/matrix-spec/tree/main/data-definitions/>
|
||||||
and can be translated online:
|
and can be translated online:
|
||||||
<https://translate.riot.im/projects/matrix-doc/sas-emoji-v1>
|
<https://translate.riot.im/projects/matrix-doc/sas-emoji-v1>
|
||||||
{{% /boxes/note %}}
|
{{% /boxes/note %}}
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ Clients SHOULD verify the structure of incoming events to ensure that
|
||||||
the expected keys exist and that they are of the right type. Clients can
|
the expected keys exist and that they are of the right type. Clients can
|
||||||
discard malformed events or display a placeholder message to the user.
|
discard malformed events or display a placeholder message to the user.
|
||||||
Redacted `m.room.message` events MUST be removed from the client. This
|
Redacted `m.room.message` events MUST be removed from the client. This
|
||||||
can either be replaced with placeholder text (e.g. "\[REDACTED\]") or
|
can either be replaced with placeholder text (e.g. "[REDACTED]") or
|
||||||
the redacted message can be removed entirely from the messages view.
|
the redacted message can be removed entirely from the messages view.
|
||||||
|
|
||||||
Events which have attachments (e.g. `m.image`, `m.file`) SHOULD be
|
Events which have attachments (e.g. `m.image`, `m.file`) SHOULD be
|
||||||
|
|
|
||||||
40
content/client-server-api/modules/recent_emoji.md
Normal file
40
content/client-server-api/modules/recent_emoji.md
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
### Recently used emoji
|
||||||
|
|
||||||
|
{{% added-in v="1.18" %}}
|
||||||
|
|
||||||
|
This module enables clients to track a user's cumulated emoji usage across different
|
||||||
|
devices. The data is stored in the [`m.recent_emoji`](#mrecent_emoji)
|
||||||
|
global [account data](#client-config) and can, among other things, be used to
|
||||||
|
generate recommendations in emoji pickers.
|
||||||
|
|
||||||
|
#### Events
|
||||||
|
|
||||||
|
{{% event event="m.recent_emoji" %}}
|
||||||
|
|
||||||
|
#### Client behaviour
|
||||||
|
|
||||||
|
What exactly constitutes trackable emoji usage is left as an implementation detail
|
||||||
|
for clients. It is RECOMMENDED to include sending emoji in both messages and
|
||||||
|
annotations.
|
||||||
|
|
||||||
|
When an emoji is used, the sending client moves (or adds) it to the beginning of
|
||||||
|
the `recent_emoji` array and increments (or initializes) its counter. This keeps
|
||||||
|
the array ordered by last usage time which facilitates evaluating the data. How
|
||||||
|
exactly the client evaluates and uses the collected data is deliberately left
|
||||||
|
unspecified.
|
||||||
|
|
||||||
|
To prevent excessive growth of the event as new emoji are being used, clients
|
||||||
|
SHOULD limit the length of the `recent_emoji` array by dropping elements from
|
||||||
|
its end. A RECOMMENDED maximum length is 100 emoji.
|
||||||
|
|
||||||
|
To enable future extension, clients MUST tolerate and preserve array elements
|
||||||
|
within `recent_emoji` regardless of whether they understand or support the
|
||||||
|
contained `emoji` value. This means ignoring entries with unrecognised values
|
||||||
|
of `emoji` when deciding what to display to the user while retaining them when
|
||||||
|
modifying the array (unless the modification is for truncation).
|
||||||
|
|
||||||
|
To prevent undefined behavior, clients SHOULD remove array elements that
|
||||||
|
don't conform to the event schema such as elements with negative counters.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2,17 +2,15 @@
|
||||||
title: "Identity Service API"
|
title: "Identity Service API"
|
||||||
weight: 40
|
weight: 40
|
||||||
type: docs
|
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
|
## General principles
|
||||||
|
|
||||||
The purpose of an identity server is to validate, store, and answer
|
The purpose of an identity server is to validate, store, and answer
|
||||||
|
|
|
||||||
|
|
@ -408,41 +408,9 @@ development or testing data.
|
||||||
that a particular MSC works) do not have to follow this process.
|
that a particular MSC works) do not have to follow this process.
|
||||||
|
|
||||||
1. Have an idea for a feature.
|
1. Have an idea for a feature.
|
||||||
1. Implement the feature using unstable endpoints, vendor prefixes, and
|
1. Implement the feature using [unstable endpoints, vendor prefixes, and
|
||||||
unstable feature flags as appropriate.
|
unstable feature flags](#unstable-endpoints-features-and-vendor-prefixes)
|
||||||
- When using unstable endpoints, they MUST include a vendor
|
as appropriate.
|
||||||
prefix. For example:
|
|
||||||
`/_matrix/client/unstable/com.example/login`. Vendor prefixes
|
|
||||||
throughout Matrix always use the Java package naming convention.
|
|
||||||
The MSC for the feature should identify which preferred vendor
|
|
||||||
prefix is to be used by early adopters.
|
|
||||||
- Note that unstable namespaces do not automatically inherit
|
|
||||||
endpoints from stable namespaces: for example, the fact that
|
|
||||||
`/_matrix/client/r0/sync` exists does not imply that
|
|
||||||
`/_matrix/client/unstable/com.example/sync` exists.
|
|
||||||
- If the client needs to be sure the server supports the feature,
|
|
||||||
an unstable feature flag that MUST be vendor prefixed is to be
|
|
||||||
used. This kind of flag shows up in the `unstable_features`
|
|
||||||
section of `/versions` as, for example, `com.example.new_login`.
|
|
||||||
The MSC for the feature should identify which preferred feature
|
|
||||||
flag is to be used by early adopters.
|
|
||||||
- When using this approach correctly, the implementation can
|
|
||||||
ship/release the feature at any time, so long as the
|
|
||||||
implementation is able to accept the technical debt that results
|
|
||||||
from needing to provide adequate backwards and forwards
|
|
||||||
compatibility. The implementation MUST support the flag (and
|
|
||||||
server-side implementation) disappearing and be generally safe
|
|
||||||
for users. Note that implementations early in the MSC review
|
|
||||||
process may also be required to provide backwards compatibility
|
|
||||||
with earlier editions of the proposal.
|
|
||||||
- If the implementation cannot support the technical debt (or if
|
|
||||||
it's impossible to provide forwards/backwards compatibility -
|
|
||||||
e.g. a user authentication change which can't be safely rolled
|
|
||||||
back), the implementation should not attempt to implement the
|
|
||||||
feature and should instead wait for a spec release.
|
|
||||||
- If at any point after early release, the idea changes in a
|
|
||||||
backwards-incompatible way, the feature flag should also change
|
|
||||||
so that implementations can adapt as needed.
|
|
||||||
1. In parallel, or ahead of implementation, open an MSC and solicit
|
1. In parallel, or ahead of implementation, open an MSC and solicit
|
||||||
review per above.
|
review per above.
|
||||||
1. Before FCP can be called, the Spec Core Team will require evidence
|
1. Before FCP can be called, the Spec Core Team will require evidence
|
||||||
|
|
@ -452,10 +420,7 @@ that a particular MSC works) do not have to follow this process.
|
||||||
forwards/backwards compatibility concerns mentioned here.
|
forwards/backwards compatibility concerns mentioned here.
|
||||||
1. The FCP process is completed, and assuming nothing is flagged the
|
1. The FCP process is completed, and assuming nothing is flagged the
|
||||||
MSC lands.
|
MSC lands.
|
||||||
1. Implementations can now switch to using stable prefixes
|
1. Implementations can now switch to using stable prefixes, assuming that the change
|
||||||
(for example, for an endpoint, moving from
|
|
||||||
`/unstable/org.matrix.mscxxxx/frobnicate`
|
|
||||||
to `/v1/frobnicate`), assuming that the change
|
|
||||||
is backwards compatible with older implementations. In the rare occasion
|
is backwards compatible with older implementations. In the rare occasion
|
||||||
where backwards compatibility is not possible without a new spec release,
|
where backwards compatibility is not possible without a new spec release,
|
||||||
implementations should continue to use unstable prefixes.
|
implementations should continue to use unstable prefixes.
|
||||||
|
|
@ -471,13 +436,6 @@ that a particular MSC works) do not have to follow this process.
|
||||||
started supporting the new spec release, some noise should be raised
|
started supporting the new spec release, some noise should be raised
|
||||||
in the general direction of the implementation.
|
in the general direction of the implementation.
|
||||||
|
|
||||||
{{% boxes/note %}}
|
|
||||||
MSCs MUST still describe what the stable endpoints/feature looks like
|
|
||||||
with a note towards the bottom for what the unstable feature
|
|
||||||
flag/prefixes are. For example, an MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/
|
|
||||||
com.example/new/endpoint`.
|
|
||||||
{{% /boxes/note %}}
|
|
||||||
|
|
||||||
In summary:
|
In summary:
|
||||||
|
|
||||||
- Implementations MUST NOT use stable endpoints before the MSC has
|
- Implementations MUST NOT use stable endpoints before the MSC has
|
||||||
|
|
@ -489,14 +447,90 @@ In summary:
|
||||||
- Implementations SHOULD be wary of the technical debt they are
|
- Implementations SHOULD be wary of the technical debt they are
|
||||||
incurring by moving faster than the spec.
|
incurring by moving faster than the spec.
|
||||||
- The vendor prefix is chosen by the developer of the feature, using
|
- The vendor prefix is chosen by the developer of the feature, using
|
||||||
the Java package naming convention. The foundation's preferred
|
the Java package naming convention.
|
||||||
vendor prefix is `org.matrix`.
|
|
||||||
- The vendor prefixes, unstable feature flags, and unstable endpoints
|
- The vendor prefixes, unstable feature flags, and unstable endpoints
|
||||||
should be included in the MSC, though the MSC MUST be written in a
|
should be included in the MSC, though the MSC MUST be written in a
|
||||||
way that proposes new stable endpoints. Typically this is solved by
|
way that proposes new stable endpoints. Typically this is solved by
|
||||||
a small table at the bottom mapping the various values from stable
|
a small table at the bottom mapping the various values from stable
|
||||||
to unstable.
|
to unstable.
|
||||||
|
|
||||||
|
#### Unstable endpoints, features and vendor prefixes
|
||||||
|
|
||||||
|
Unstable endpoints MUST use `/unstable` as the endpoint version and a
|
||||||
|
vendor prefix in Java package naming format. For example:
|
||||||
|
`/_matrix/client/unstable/com.example.mscxxxx/login`.
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
Proposal authors operating with a Matrix.org Foundation mandate SHOULD use
|
||||||
|
a vendor prefix within the `org.matrix` namespace. This namespace is otherwise
|
||||||
|
restricted. Authors who don't own a domain MAY use the `io.github` namespace
|
||||||
|
instead.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
|
Note that unstable namespaces do not automatically inherit endpoints from
|
||||||
|
stable namespaces: for example, the fact that `/_matrix/client/v3/sync`
|
||||||
|
exists does not imply that `/_matrix/client/unstable/com.example.mscxxxx/sync`
|
||||||
|
exists.
|
||||||
|
|
||||||
|
Vendor prefixes MUST also be used for:
|
||||||
|
|
||||||
|
- New parameters on existing endpoints. For example:
|
||||||
|
`/_matrix/client/v3/publicRooms?com.example.mscxxxx.ordered_by=member_count`.
|
||||||
|
- New properties in existing JSON objects. For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"avatar_url": "mxc://matrix.org/SDGdghriugerRg",
|
||||||
|
"displayname": "Alice Margatroid",
|
||||||
|
"com.example.mscxxxx.phone": [{
|
||||||
|
"type": "landline",
|
||||||
|
"number": "+1-206-555-7000"
|
||||||
|
}],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- New values for existing parameters or properties. For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"errcode": "COM.EXAMPLE.MSCXXXX.M_INVALID_EMAIL",
|
||||||
|
"error": "The email address you provided is invalid."
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If the client needs to be sure the server supports the feature, an
|
||||||
|
unstable feature flag that MUST also be vendor prefixed is to be used.
|
||||||
|
This flag shows up in the `unstable_features` section of
|
||||||
|
[`/_matrix/client/versions`](/client-server-api/#get_matrixclientversions)
|
||||||
|
as, for example, `com.example.mscxxxx.new_login`.
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
MSCs MUST still describe what the stable endpoints/feature looks like
|
||||||
|
with a note towards the bottom for what the unstable feature
|
||||||
|
flag/prefixes are. For example, an MSC would propose `/_matrix/client/v1/new/endpoint`,
|
||||||
|
not `/_matrix/client/unstable/com.example.mscxxxx/new/endpoint`.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
|
When using this approach correctly, the implementation can release
|
||||||
|
the feature at any time, so long as the implementation is able to
|
||||||
|
accept the technical debt that results from needing to provide
|
||||||
|
adequate backwards and forwards compatibility. The implementation
|
||||||
|
MUST support the flag (and server-side implementation) disappearing
|
||||||
|
and be generally safe for users. Note that implementations early in
|
||||||
|
the MSC review process may also be required to provide backwards
|
||||||
|
compatibility with earlier editions of the proposal.
|
||||||
|
|
||||||
|
If the implementation cannot support the technical debt (or if it's
|
||||||
|
impossible to provide forwards/backwards compatibility - e.g. a user
|
||||||
|
authentication change which can't be safely rolled back), the
|
||||||
|
implementation should not attempt to implement the feature and should
|
||||||
|
instead wait for a spec release.
|
||||||
|
|
||||||
|
If at any point after early release, the idea changes in a
|
||||||
|
backwards-incompatible way, the feature flag should also change so
|
||||||
|
that implementations can adapt as needed.
|
||||||
|
|
||||||
### Placeholder MSCs
|
### Placeholder MSCs
|
||||||
|
|
||||||
Some proposals may contain security-sensitive or private context which can't be
|
Some proposals may contain security-sensitive or private context which can't be
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@
|
||||||
title: "Push Gateway API"
|
title: "Push Gateway API"
|
||||||
weight: 50
|
weight: 50
|
||||||
type: docs
|
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
|
## Overview
|
||||||
|
|
||||||
A client's homeserver forwards information about received events to the
|
A client's homeserver forwards information about received events to the
|
||||||
|
|
|
||||||
|
|
@ -2,49 +2,46 @@
|
||||||
title: "Server-Server API"
|
title: "Server-Server API"
|
||||||
weight: 20
|
weight: 20
|
||||||
type: docs
|
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
|
## API standards
|
||||||
|
|
||||||
The mandatory baseline for server-server communication in Matrix is
|
The mandatory baseline for server-server communication in Matrix is
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,17 @@ paths:
|
||||||
x-addedInMatrixVersion: "1.1"
|
x-addedInMatrixVersion: "1.1"
|
||||||
x-changedInMatrixVersion:
|
x-changedInMatrixVersion:
|
||||||
"1.11": UIA is not always required for this endpoint.
|
"1.11": UIA is not always required for this endpoint.
|
||||||
|
"1.17": |-
|
||||||
|
This endpoint no longer requires User-Interactive Authentication when used by an
|
||||||
|
application service.
|
||||||
summary: Upload cross-signing keys.
|
summary: Upload cross-signing keys.
|
||||||
description: |-
|
description: |-
|
||||||
Publishes cross-signing keys for the user.
|
Publishes cross-signing keys for the user.
|
||||||
|
|
||||||
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
|
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api),
|
||||||
|
except when used by an application service.
|
||||||
|
|
||||||
User-Interactive Authentication MUST be performed, except in these cases:
|
User-Interactive Authentication MUST be performed for regular clients, except in these cases:
|
||||||
- there is no existing cross-signing master key uploaded to the homeserver, OR
|
- there is no existing cross-signing master key uploaded to the homeserver, OR
|
||||||
- there is an existing cross-signing master key and it exactly matches the
|
- there is an existing cross-signing master key and it exactly matches the
|
||||||
cross-signing master key provided in the request body. If there are any additional
|
cross-signing master key provided in the request body. If there are any additional
|
||||||
|
|
|
||||||
29
data/api/client-server/definitions/recent_emoji.yaml
Normal file
29
data/api/client-server/definitions/recent_emoji.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Copyright 2026 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
title: Recent Emoji
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
emoji:
|
||||||
|
type: string
|
||||||
|
description: The Unicode emoji as string.
|
||||||
|
example: 🚀
|
||||||
|
total:
|
||||||
|
type: number
|
||||||
|
description: |-
|
||||||
|
The number of times the emoji has been used.
|
||||||
|
MUST be non-negative and smaller than 2^53.
|
||||||
|
required:
|
||||||
|
- emoji
|
||||||
|
- total
|
||||||
|
|
@ -24,16 +24,23 @@ properties:
|
||||||
submit_url:
|
submit_url:
|
||||||
type: string
|
type: string
|
||||||
format: uri
|
format: uri
|
||||||
|
x-changedInMatrixVersion:
|
||||||
|
"1.18": |-
|
||||||
|
The URL has the same request and response parameters and error codes as
|
||||||
|
the Identity Service API's endpoint.
|
||||||
description: |-
|
description: |-
|
||||||
An optional field containing a URL where the client must submit the
|
An optional field containing a URL where the client must submit the
|
||||||
validation token to, with identical parameters to the Identity Service
|
validation token, with identical request and response parameters and error
|
||||||
API's `POST /validate/email/submitToken` endpoint (without the requirement
|
codes to the Identity Service API's
|
||||||
for an access token). The homeserver must send this token to the user (if
|
[`POST /validate/email/submitToken`](/identity-service-api/#post_matrixidentityv2validateemailsubmittoken)
|
||||||
applicable), who should then be prompted to provide it to the client.
|
and [`POST /validate/msisdn/submitToken`](/identity-service-api/#post_matrixidentityv2validatemsisdnsubmittoken)
|
||||||
|
endpoints (without the requirement for an access token). The homeserver
|
||||||
|
must send this token to the user (if applicable), who should then be
|
||||||
|
prompted to provide it to the client.
|
||||||
|
|
||||||
If this field is not present, the client can assume that verification
|
If this field is not present, the client can assume that verification
|
||||||
will happen without the client's involvement provided the homeserver
|
will happen without the client's involvement provided the homeserver
|
||||||
advertises this specification version in the `/versions` response
|
advertises a sufficiently recent version in the [`GET /versions`](/client-server-api/#get_matrixclientversions)
|
||||||
(ie: r0.5.0).
|
response (ie: r0.5.0).
|
||||||
example: "https://example.org/path/to/submitToken"
|
example: "https://example.org/path/to/submitToken"
|
||||||
required: ['sid']
|
required: ['sid']
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,21 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- Device management
|
- Device management
|
||||||
put:
|
put:
|
||||||
summary: Update a device
|
summary: Create or update a device
|
||||||
description: Updates the metadata on the given device.
|
x-changedInMatrixVersion:
|
||||||
|
"1.17": The ability to create new devices was added.
|
||||||
|
description: |-
|
||||||
|
Updates the metadata on the given device, or creates a new device.
|
||||||
|
|
||||||
|
The ability to create new devices is only available to application
|
||||||
|
services: regular clients may only update existing devices.
|
||||||
|
|
||||||
|
When a new device was created, the homeserver MUST return a 201 HTTP
|
||||||
|
status code. It MUST return a 200 HTTP status code if a device was
|
||||||
|
updated.
|
||||||
|
|
||||||
|
This endpoint is rate-limited for device creation. Servers MAY use login
|
||||||
|
rate limits.
|
||||||
operationId: updateDevice
|
operationId: updateDevice
|
||||||
security:
|
security:
|
||||||
- accessTokenQuery: []
|
- accessTokenQuery: []
|
||||||
|
|
@ -127,19 +140,34 @@ paths:
|
||||||
examples:
|
examples:
|
||||||
response:
|
response:
|
||||||
value: {}
|
value: {}
|
||||||
|
"201":
|
||||||
|
description: |-
|
||||||
|
The device was successfully created by the application service.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value: {}
|
||||||
"404":
|
"404":
|
||||||
description: The current user has no device with the given ID.
|
description: The current user has no device with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- Device management
|
- Device management
|
||||||
delete:
|
delete:
|
||||||
summary: Delete a device
|
summary: Delete a device
|
||||||
|
x-changedInMatrixVersion:
|
||||||
|
"1.17": |-
|
||||||
|
This endpoint no longer requires User-Interactive Authentication when used by an
|
||||||
|
application service.
|
||||||
description: |-
|
description: |-
|
||||||
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
|
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api),
|
||||||
|
except when used by an application service.
|
||||||
|
|
||||||
Deletes the given device, and invalidates any access token associated with it.
|
Deletes the given device, and invalidates any access token associated with it.
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
{{% boxes/warning %}}
|
||||||
Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained
|
When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained
|
||||||
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||||
{{% /boxes/warning %}}
|
{{% /boxes/warning %}}
|
||||||
|
|
||||||
|
|
@ -197,13 +225,18 @@ paths:
|
||||||
/delete_devices:
|
/delete_devices:
|
||||||
post:
|
post:
|
||||||
summary: Bulk deletion of devices
|
summary: Bulk deletion of devices
|
||||||
|
x-changedInMatrixVersion:
|
||||||
|
"1.17": |-
|
||||||
|
This endpoint no longer requires User-Interactive Authentication when used by an
|
||||||
|
application service.
|
||||||
description: |-
|
description: |-
|
||||||
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api).
|
This API endpoint uses the [User-Interactive Authentication API](/client-server-api/#user-interactive-authentication-api),
|
||||||
|
except when used by an application service.
|
||||||
|
|
||||||
Deletes the given devices, and invalidates any access token associated with them.
|
Deletes the given devices, and invalidates any access token associated with them.
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
{{% boxes/warning %}}
|
||||||
Since this endpoint uses User-Interactive Authentication, it cannot be used when the access token was obtained
|
When this endpoint requires User-Interactive Authentication, it cannot be used when the access token was obtained
|
||||||
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
via the [OAuth 2.0 API](/client-server-api/#oauth-20-api).
|
||||||
{{% /boxes/warning %}}
|
{{% /boxes/warning %}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -243,8 +243,13 @@ paths:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"400":
|
"400":
|
||||||
description: Part of the request was invalid. For example, the login type may
|
description: |-
|
||||||
not be recognised.
|
Part of the request was invalid. For example, the login type may not be recognised.
|
||||||
|
|
||||||
|
Specific error codes used with this status code include:
|
||||||
|
* {{% added-in v="1.17" %}} `M_APPSERVICE_LOGIN_UNSUPPORTED`: an application service
|
||||||
|
used the `m.login.application_service` type, but the server doesn't support logging
|
||||||
|
in via the Legacy authentication API.
|
||||||
content:
|
content:
|
||||||
application/json:
|
application/json:
|
||||||
schema:
|
schema:
|
||||||
|
|
|
||||||
|
|
@ -139,6 +139,32 @@ paths:
|
||||||
items:
|
items:
|
||||||
type: string
|
type: string
|
||||||
description: A prompt value that the server supports.
|
description: A prompt value that the server supports.
|
||||||
|
account_management_uri:
|
||||||
|
x-addedInMatrixVersion: "1.18"
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
description: |-
|
||||||
|
The URL where the user is able to access the account management capabilities
|
||||||
|
of the homeserver.
|
||||||
|
|
||||||
|
This is an extension [defined in this specification](/client-server-api/#oauth-20-account-management).
|
||||||
|
account_management_actions_supported:
|
||||||
|
x-addedInMatrixVersion: "1.18"
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
List of actions that the account management URL supports.
|
||||||
|
|
||||||
|
This is an extension [defined in this specification](/client-server-api/#oauth-20-account-management).
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- "org.matrix.profile"
|
||||||
|
- "org.matrix.devices_list"
|
||||||
|
- "org.matrix.device_view"
|
||||||
|
- "org.matrix.device_delete"
|
||||||
|
- "org.matrix.account_deactivate"
|
||||||
|
- "org.matrix.cross_signing_reset"
|
||||||
|
description: An action that the account management URL supports.
|
||||||
required:
|
required:
|
||||||
- issuer
|
- issuer
|
||||||
- authorization_endpoint
|
- authorization_endpoint
|
||||||
|
|
@ -159,6 +185,15 @@ paths:
|
||||||
"grant_types_supported": ["authorization_code", "refresh_token"],
|
"grant_types_supported": ["authorization_code", "refresh_token"],
|
||||||
"response_modes_supported": ["query", "fragment"],
|
"response_modes_supported": ["query", "fragment"],
|
||||||
"code_challenge_methods_supported": ["S256"],
|
"code_challenge_methods_supported": ["S256"],
|
||||||
|
"account_management_uri": "https://account.example.com/manage",
|
||||||
|
"account_management_actions_supported": [
|
||||||
|
"org.matrix.profile",
|
||||||
|
"org.matrix.devices_list",
|
||||||
|
"org.matrix.device_view",
|
||||||
|
"org.matrix.device_delete",
|
||||||
|
"org.matrix.account_deactivate",
|
||||||
|
"org.matrix.cross_signing_reset",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
tags:
|
tags:
|
||||||
- Session management
|
- Session management
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,18 @@ paths:
|
||||||
Any user ID returned by this API must conform to the grammar given in the
|
Any user ID returned by this API must conform to the grammar given in the
|
||||||
[Matrix specification](/appendices/#user-identifiers).
|
[Matrix specification](/appendices/#user-identifiers).
|
||||||
|
|
||||||
|
{{% boxes/note %}}
|
||||||
|
{{% added-in v="1.17" %}}
|
||||||
|
Even if the server doesn't support the Legacy authentication API, it
|
||||||
|
MUST support this endpoint for application services to be able to
|
||||||
|
[create users](/application-service-api/#server-admin-style-permissions).
|
||||||
|
|
||||||
|
In that case application services MUST set the `"inhibit_login": true`
|
||||||
|
parameter as they cannot use it to log in as users. If the
|
||||||
|
`inhibit_login` parameter is not set to `true`, the server MUST return a
|
||||||
|
400 HTTP status code with an `M_APPSERVICE_LOGIN_UNSUPPORTED` error code.
|
||||||
|
{{% /boxes/note %}}
|
||||||
|
|
||||||
{{% boxes/warning %}}
|
{{% boxes/warning %}}
|
||||||
{{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients)
|
{{% added-in v="1.18" %}} [OAuth 2.0 aware clients](/client-server-api/#oauth-20-aware-clients)
|
||||||
MUST NOT use this endpoint when the server offers the [`m.login.sso`
|
MUST NOT use this endpoint when the server offers the [`m.login.sso`
|
||||||
|
|
@ -211,6 +223,9 @@ paths:
|
||||||
* `M_INVALID_USERNAME` : The desired user ID is not a valid user name.
|
* `M_INVALID_USERNAME` : The desired user ID is not a valid user name.
|
||||||
* `M_EXCLUSIVE` : The desired user ID is in the exclusive namespace
|
* `M_EXCLUSIVE` : The desired user ID is in the exclusive namespace
|
||||||
claimed by an application service.
|
claimed by an application service.
|
||||||
|
* {{% added-in v="1.17" %}} `M_APPSERVICE_LOGIN_UNSUPPORTED`: an application service
|
||||||
|
used the `m.login.application_service` type without setting `inhibit_login` to `true`,
|
||||||
|
but the server doesn't support logging in via the Legacy authentication API.
|
||||||
|
|
||||||
These errors may be returned at any stage of the registration process,
|
These errors may be returned at any stage of the registration process,
|
||||||
including after authentication if the requested user ID was registered
|
including after authentication if the requested user ID was registered
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
# XXX: As mentioned in MSC1227, replacing `[not_]membership` with a JSON
|
# XXX: As mentioned in MSC1227, replacing `[not_]membership` with a JSON
|
||||||
# filter might be a better alternative.
|
# filter might be a better alternative.
|
||||||
# See https://github.com/matrix-org/matrix-doc/issues/1337
|
# See https://github.com/matrix-org/matrix-doc/issues/1227
|
||||||
- in: query
|
- in: query
|
||||||
name: membership
|
name: membership
|
||||||
description: |-
|
description: |-
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ paths:
|
||||||
},
|
},
|
||||||
"room": {
|
"room": {
|
||||||
"regexp": "[^\\s]+\\/[^\\s]+",
|
"regexp": "[^\\s]+\\/[^\\s]+",
|
||||||
"placeholder": "matrix-org/matrix-doc"
|
"placeholder": "matrix-org/matrix-spec"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"instances": [
|
"instances": [
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,24 @@ paths:
|
||||||
value: {
|
value: {
|
||||||
"success": true
|
"success": true
|
||||||
}
|
}
|
||||||
|
"400":
|
||||||
|
description: |
|
||||||
|
An error occurred. Some possible errors are:
|
||||||
|
|
||||||
|
- {{% added-in v="1.18" %}} `M_TOKEN_INCORRECT`: The token that the user entered to validate the session is
|
||||||
|
incorrect.
|
||||||
|
- {{% added-in v="1.18" %}} `M_INVALID_PARAM`: One of the supplied parameters is not valid.
|
||||||
|
- {{% added-in v="1.18" %}} `M_SESSION_EXPIRED`: The validation session in question has expired.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../client-server/definitions/errors/error.yaml
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value: {
|
||||||
|
"errcode": "M_TOKEN_INCORRECT",
|
||||||
|
"error": "The token is incorrect"
|
||||||
|
}
|
||||||
"403":
|
"403":
|
||||||
description: |
|
description: |
|
||||||
The user must do something in order to use this endpoint. One example
|
The user must do something in order to use this endpoint. One example
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,24 @@ paths:
|
||||||
value: {
|
value: {
|
||||||
"success": true
|
"success": true
|
||||||
}
|
}
|
||||||
|
"400":
|
||||||
|
description: |
|
||||||
|
An error occurred. Some possible errors are:
|
||||||
|
|
||||||
|
- {{% added-in v="1.18" %}} `M_TOKEN_INCORRECT`: The token that the user entered to validate the session is
|
||||||
|
incorrect.
|
||||||
|
- {{% added-in v="1.18" %}} `M_INVALID_PARAM`: One of the supplied parameters is not valid.
|
||||||
|
- {{% added-in v="1.18" %}} `M_SESSION_EXPIRED`: The validation session in question has expired.
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: ../client-server/definitions/errors/error.yaml
|
||||||
|
examples:
|
||||||
|
response:
|
||||||
|
value: {
|
||||||
|
"errcode": "M_TOKEN_INCORRECT",
|
||||||
|
"error": "The token is incorrect"
|
||||||
|
}
|
||||||
"403":
|
"403":
|
||||||
description: |
|
description: |
|
||||||
The user must do something in order to use this endpoint. One example
|
The user must do something in order to use this endpoint. One example
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,12 @@ paths:
|
||||||
properties:
|
properties:
|
||||||
sub:
|
sub:
|
||||||
type: string
|
type: string
|
||||||
description: The Matrix User ID who generated the token.
|
description: |
|
||||||
|
The Matrix User ID who generated the token.
|
||||||
|
|
||||||
|
The caller MUST validate that the returned user ID is on the server they
|
||||||
|
called (i.e. if you make a request to example.com and it returns
|
||||||
|
`@alice:matrix.org`, the result is invalid).
|
||||||
example: "@alice:example.com"
|
example: "@alice:example.com"
|
||||||
required:
|
required:
|
||||||
- sub
|
- sub
|
||||||
|
|
|
||||||
16
data/event-schemas/examples/m.recent_emoji.yaml
Normal file
16
data/event-schemas/examples/m.recent_emoji.yaml
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"$ref": "core/event.json",
|
||||||
|
"type": "m.recent_emoji",
|
||||||
|
"content": {
|
||||||
|
"recent_emoji": [{
|
||||||
|
"emoji": "🤔",
|
||||||
|
"total": 19
|
||||||
|
}, {
|
||||||
|
"emoji": "👍",
|
||||||
|
"total": 7
|
||||||
|
}, {
|
||||||
|
"emoji": "😅",
|
||||||
|
"total": 84
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
29
data/event-schemas/schema/m.recent_emoji.yaml
Normal file
29
data/event-schemas/schema/m.recent_emoji.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"type": "object",
|
||||||
|
"title": "Recent Emoji Event",
|
||||||
|
"description": "Lets clients maintain a list of recently used emoji.",
|
||||||
|
"allOf": [{
|
||||||
|
"$ref": "core-event-schema/event.yaml"
|
||||||
|
}],
|
||||||
|
"properties": {
|
||||||
|
"type": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": ["m.recent_emoji"]
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"recent_emoji": {
|
||||||
|
"description": "The list of recently used emoji. Elements in the list are ordered descendingly by last usage time.",
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "../../api/client-server/definitions/recent_emoji.yaml"
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["recent_emoji"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["type", "content"]
|
||||||
|
}
|
||||||
30
data/schemas/oauth2-account-management-server-metadata.yaml
Normal file
30
data/schemas/oauth2-account-management-server-metadata.yaml
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Copyright 2026 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
type: object
|
||||||
|
title: OAuth 2.0 Server Metadata Account Management Extension
|
||||||
|
properties:
|
||||||
|
account_management_uri:
|
||||||
|
type: string
|
||||||
|
format: uri
|
||||||
|
description: |-
|
||||||
|
The URL where the user is able to access the account management capabilities of the
|
||||||
|
server.
|
||||||
|
account_management_actions_supported:
|
||||||
|
type: array
|
||||||
|
description: |-
|
||||||
|
List of [actions](/client-server-api/#account-management-url-actions) that the account
|
||||||
|
management URL supports.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
description: An action that the account management URL supports.
|
||||||
29
data/schemas/oauth2-account-management-url.yaml
Normal file
29
data/schemas/oauth2-account-management-url.yaml
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Copyright 2026 The Matrix.org Foundation C.I.C.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
type: object
|
||||||
|
title: OAuth 2.0 Account Management URL Query Parameters
|
||||||
|
properties:
|
||||||
|
action:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The action that the user wishes to take. Must match one of the actions advertised by the
|
||||||
|
server in [`account_management_actions_supported`](/client-server-api/#account-management-url-discovery).
|
||||||
|
device_id:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
For Matrix-specific actions, the user's device ID. Actions which don't support the device ID
|
||||||
|
will ignore it.
|
||||||
|
|
||||||
|
If the `org.matrix.device_view` or `org.matrix.device_delete` actions are advertised as
|
||||||
|
supported by the server then the server SHOULD support the `device_id` parameter.
|
||||||
2
go.mod
2
go.mod
|
|
@ -2,4 +2,4 @@ module github.com/matrix-org/matrix-spec
|
||||||
|
|
||||||
go 1.12
|
go 1.12
|
||||||
|
|
||||||
require github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af // indirect
|
require github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a // indirect
|
||||||
|
|
|
||||||
6
go.sum
6
go.sum
|
|
@ -1,4 +1,4 @@
|
||||||
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
|
github.com/FortAwesome/Font-Awesome v0.0.0-20241216213156-af620534bfc3/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
|
||||||
github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af h1:XghgUC0H5BoGrvtT9/oWBUi+5Zux875qRHhpAZ0RURI=
|
github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a h1:WB3unuZJy7ewAf33sxbtEwYnC+i+Jt1sJpAR3BtzvEo=
|
||||||
github.com/matrix-org/docsy v0.0.0-20250722140156-5df72519f5af/go.mod h1:4/t21g/nPraob/DVMm3jrk26k0CDL5I7Mxf+ar0IAgs=
|
github.com/matrix-org/docsy v0.0.0-20260106184755-71d103ebb20a/go.mod h1:mdn1m5HJug6ZddQgrOyCrXNegbtdl5evHiqqbEQLzdI=
|
||||||
github.com/twbs/bootstrap v5.3.6+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
|
github.com/twbs/bootstrap v5.3.8+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,7 @@
|
||||||
We use it to send the delimited passthrough element through KaTeX to render maths
|
We use it to send the delimited passthrough element through KaTeX to render maths
|
||||||
in the Olm / Megolm spec.
|
in the Olm / Megolm spec.
|
||||||
|
|
||||||
See: https://gohugo.io/functions/transform/tomath/#step-2
|
See: https://www.docsy.dev/docs/content/diagrams-and-formulae/#add-passthrough-render-hook
|
||||||
|
|
||||||
*/ -}}
|
*/ -}}
|
||||||
{{- $opts := dict "output" "htmlAndMathml" "displayMode" (eq .Type "block") }}
|
{{ partial "scripts/math.html" . }}
|
||||||
{{- with try (transform.ToMath .Inner $opts) }}
|
|
||||||
{{- with .Err }}
|
|
||||||
{{- errorf "Unable to render mathematical markup to HTML using the transform.ToMath function. The KaTeX display engine threw the following error: %s: see %s." . $.Position }}
|
|
||||||
{{- else }}
|
|
||||||
{{- .Value }}
|
|
||||||
{{- $.Page.Store.Set "hasMath" true }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,35 @@
|
||||||
{{/*
|
{{/*
|
||||||
|
|
||||||
A copy of the breadcrumb.html partial in Docsy, modified
|
A copy of the breadcrumb.html partial in Docsy, modified to:
|
||||||
to:
|
|
||||||
|
* show the breadcrumbs by default by removing the `td-breadcrumbs__single`
|
||||||
|
class
|
||||||
* omit breadcrumbs when this is the homepage
|
* omit breadcrumbs when this is the homepage
|
||||||
* otherwise, include the homepage in the breadcrumbs
|
* otherwise, include the homepage in the breadcrumbs
|
||||||
|
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
{{ if not .IsHome }}
|
{{ if not .IsHome -}}
|
||||||
<nav aria-label="breadcrumb" class="td-breadcrumbs">
|
<nav aria-label="breadcrumb" class="td-breadcrumbs">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
{{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
|
{{- template "breadcrumbnav" (dict "p1" . "p2" .) }}
|
||||||
</ol>
|
</ol>
|
||||||
</nav >
|
</nav>
|
||||||
{{ end }}
|
{{ end -}}
|
||||||
|
|
||||||
{{ define "breadcrumbnav" }}
|
{{- define "breadcrumbnav" -}}
|
||||||
{{ if .p1.Parent }}
|
{{ if .p1.Parent -}}
|
||||||
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }}
|
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) -}}
|
||||||
{{ else if not .p1.IsHome }}
|
{{ else if not .p1.IsHome -}}
|
||||||
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
|
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) -}}
|
||||||
{{ end }}
|
{{ end -}}
|
||||||
{{ $isActive := eq .p1 .p2 }}
|
{{ $isActive := eq .p1 .p2 }}
|
||||||
<li class="breadcrumb-item{{ if $isActive }} active{{ end }}" {{ if $isActive }}aria-current="page"{{ end }}>
|
<li class="breadcrumb-item{{ if $isActive }} active{{ end }}"
|
||||||
<a href="{{ .p1.RelPermalink }}">{{ .p1.LinkTitle }}</a>
|
{{- if $isActive }}aria-current="page"{{ end }}>
|
||||||
</li>
|
{{ if $isActive -}}
|
||||||
{{ end }}
|
{{ .p1.LinkTitle -}}
|
||||||
|
{{ else -}}
|
||||||
|
<a href="{{ .p1.RelPermalink }}">{{ .p1.LinkTitle }}</a>
|
||||||
|
{{- end -}}
|
||||||
|
</li>
|
||||||
|
{{- end -}}
|
||||||
|
|
|
||||||
61
layouts/_partials/endpoints-toc.html
Normal file
61
layouts/_partials/endpoints-toc.html
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
{{/*
|
||||||
|
|
||||||
|
Renders a list of API endpoints for the current page, given:
|
||||||
|
|
||||||
|
The outer page's Scratch must contain an "api_endpoints" key, which is either
|
||||||
|
a slice of maps (a list of endpoint metadata dicts) or a map of module name ->
|
||||||
|
slice of endpoint metadata dicts (representing the API modules and the
|
||||||
|
endpoints they each contain). Each endpoint dict must contain the following
|
||||||
|
keys:
|
||||||
|
|
||||||
|
* `anchor`: the HTML anchor for the endpoint
|
||||||
|
* `method`: the HTTP method
|
||||||
|
* `endpoint`: the endpoint path
|
||||||
|
* `summary`: a short summary of the endpoint
|
||||||
|
* `deprecated`: whether the endpoint is deprecated
|
||||||
|
* `module`: the CS API module name, if any, for grouping purposes. If empty,
|
||||||
|
the endpoint is considered "base" or "required".
|
||||||
|
|
||||||
|
*/}}
|
||||||
|
|
||||||
|
{{ $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 }}
|
||||||
|
<div class="endpoints-toc mb-4">
|
||||||
|
<details>
|
||||||
|
<summary>List of Endpoints</summary>
|
||||||
|
{{/* Sort by module to group visually */}}
|
||||||
|
{{ $sorted := sort $endpoints "module" }}
|
||||||
|
{{ $current := "" }}
|
||||||
|
{{ range $sorted }}
|
||||||
|
{{ $mod := .module }}
|
||||||
|
{{/* Set a title for the base endpoints */}}
|
||||||
|
{{ if not $mod }}{{ $mod = "Required" }}{{ end }}
|
||||||
|
{{ if ne $mod $current }}
|
||||||
|
{{ if $current }}</ul></div>{{ end }}
|
||||||
|
<div class="endpoint-module">
|
||||||
|
<div class="endpoint-module-title">{{ $mod }}</div>
|
||||||
|
<ul class="endpoint-list">
|
||||||
|
{{ $current = $mod }}
|
||||||
|
{{ end }}
|
||||||
|
{{ $key := printf "%s|%s" .method .anchor }}
|
||||||
|
<li>
|
||||||
|
<a href="#{{ .anchor }}">
|
||||||
|
<span class="http-api-method">{{ .method }}</span>
|
||||||
|
<span class="endpoint-path">{{ .endpoint }}</span>
|
||||||
|
{{ if .deprecated }}<span class="endpoint-deprecated">(deprecated)</span>{{ end }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
{{ if $current }}</ul></div>{{ end }}
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
{{- /*
|
{{- /*
|
||||||
|
|
||||||
A version of the navbar.html partial in Docsy, only modified
|
A copy of the navbar.html partial in Docsy, modified to:
|
||||||
to include the spec version, which is calculated using an
|
|
||||||
inline `version-string` partial.
|
* remove `data-bs-theme` at L20, otherwise the title disappears on hover.
|
||||||
|
* replace the site title with "specification" at L31.
|
||||||
|
* include the spec version from the config at L34-35, which is calculated
|
||||||
|
using an inline `version-string` partial.
|
||||||
|
|
||||||
*/ -}}
|
*/ -}}
|
||||||
|
|
||||||
|
|
@ -13,8 +16,8 @@
|
||||||
{{ $baseURL := urls.Parse $.Site.Params.Baseurl -}}
|
{{ $baseURL := urls.Parse $.Site.Params.Baseurl -}}
|
||||||
|
|
||||||
<nav class="td-navbar js-navbar-scroll
|
<nav class="td-navbar js-navbar-scroll
|
||||||
{{- if $cover }} td-navbar-cover {{- end }}" data-bs-theme="light">
|
{{- if $cover }} td-navbar-cover {{- end }}">
|
||||||
<div class="container-fluid flex-column flex-md-row">
|
<div class="td-navbar-container container-fluid flex-column flex-md-row">
|
||||||
<a class="navbar-brand" href="{{ .Site.Home.RelPermalink }}">
|
<a class="navbar-brand" href="{{ .Site.Home.RelPermalink }}">
|
||||||
{{- /**/ -}}
|
{{- /**/ -}}
|
||||||
<span class="navbar-brand__logo navbar-logo">
|
<span class="navbar-brand__logo navbar-logo">
|
||||||
|
|
@ -32,7 +35,8 @@
|
||||||
<span class="navbar-version"> — {{ partial "version-string" . }}</span>
|
<span class="navbar-version"> — {{ partial "version-string" . }}</span>
|
||||||
{{- /**/ -}}
|
{{- /**/ -}}
|
||||||
</a>
|
</a>
|
||||||
<div class="td-navbar-nav-scroll ms-md-auto" id="main_navbar">
|
<div class="td-navbar-nav-scroll td-navbar-nav-scroll--indicator" id="main_navbar">
|
||||||
|
<div class="scroll-indicator scroll-left"></div>
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
{{ $p := . -}}
|
{{ $p := . -}}
|
||||||
{{ range .Site.Menus.main -}}
|
{{ range .Site.Menus.main -}}
|
||||||
|
|
@ -58,39 +62,41 @@
|
||||||
</li>
|
</li>
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ if .Site.Params.versions -}}
|
{{ if .Site.Params.versions -}}
|
||||||
<li class="nav-item dropdown d-none d-lg-block">
|
<li class="nav-item dropdown d-none d-lg-block td-navbar__version-menu">
|
||||||
{{ partial "navbar-version-selector.html" . -}}
|
{{ partial "navbar-version-selector.html" . -}}
|
||||||
</li>
|
</li>
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ if (gt (len .Site.Home.Translations) 0) -}}
|
{{ if (gt (len .Site.Home.Translations) 0) -}}
|
||||||
<li class="nav-item dropdown d-none d-lg-block">
|
<li class="nav-item td-navbar__lang-menu">
|
||||||
{{ partial "navbar-lang-selector.html" . -}}
|
{{ partial "navbar-lang-selector.html" . -}}
|
||||||
</li>
|
</li>
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ if .Site.Params.ui.showLightDarkModeMenu -}}
|
{{- $darkMode := partialCached "dark-mode-config.html" "dark-mode-global" -}}
|
||||||
<li class="td-light-dark-menu nav-item dropdown">
|
{{ if $darkMode.showMenu -}}
|
||||||
|
<li class="nav-item td-navbar__light-dark-menu">
|
||||||
{{ partial "theme-toggler" . }}
|
{{ partial "theme-toggler" . }}
|
||||||
</li>
|
</li>
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
</ul>
|
</ul>
|
||||||
|
<div class="scroll-indicator scroll-right"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-none d-lg-block">
|
<div class="d-none d-lg-block td-navbar__search">
|
||||||
{{ partial "search-input.html" . }}
|
{{ partial "search-input.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{{ define "_partials/version-string" }}
|
{{- define "_partials/version-string" -}}
|
||||||
{{ $ret := "unstable version"}}
|
{{ $ret := "unstable version" -}}
|
||||||
|
|
||||||
{{ $status := .Site.Params.version.status }}
|
{{ $status := .Site.Params.version.status -}}
|
||||||
|
|
||||||
{{ if ne $status "unstable"}}
|
{{ if ne $status "unstable" -}}
|
||||||
{{ $path := path.Join "changelogs" }}
|
{{ $path := path.Join "changelogs" -}}
|
||||||
|
|
||||||
{{/* produces a string similar to "version v1.5" */}}
|
{{/* produces a string similar to "version v1.5" */ -}}
|
||||||
{{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" }}
|
{{ $ret = delimit (slice "version v" .Site.Params.version.major "." .Site.Params.version.minor) "" -}}
|
||||||
{{ end }}
|
{{ end -}}
|
||||||
|
|
||||||
{{ return $ret }}
|
{{ return $ret -}}
|
||||||
{{ end }}
|
{{- end -}}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
of each value in `paths` to get a complete URL.
|
of each value in `paths` to get a complete URL.
|
||||||
* `anchor_base`: an optional prefix for the HTML IDs generated by
|
* `anchor_base`: an optional prefix for the HTML IDs generated by
|
||||||
this template.
|
this template.
|
||||||
|
* `page`: the (Hugo) Page object to store endpoint metadata in the Scratch of. Used to build the endpoints TOC.
|
||||||
|
* `module`: the current CS API module name, if any. Used to group endpoints in the TOC.
|
||||||
|
|
||||||
This template replaces the old {{*_http_api}} template.
|
This template replaces the old {{*_http_api}} template.
|
||||||
|
|
||||||
|
|
@ -15,6 +17,8 @@
|
||||||
{{ $api_data := index .api_data }}
|
{{ $api_data := index .api_data }}
|
||||||
{{ $base_url := .base_url }}
|
{{ $base_url := .base_url }}
|
||||||
{{ $anchor_base := .anchor_base }}
|
{{ $anchor_base := .anchor_base }}
|
||||||
|
{{ $page := .page }}
|
||||||
|
{{ $module := .module }}
|
||||||
|
|
||||||
{{ range $path_name, $path_data := $api_data.paths }}
|
{{ range $path_name, $path_data := $api_data.paths }}
|
||||||
|
|
||||||
|
|
@ -26,28 +30,28 @@
|
||||||
|
|
||||||
{{ with $path_data.get }}
|
{{ 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 "module" $module) }}
|
||||||
{{ partial "openapi/render-operation" $operation_params }}
|
{{ partial "openapi/render-operation" $operation_params }}
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ with $path_data.post }}
|
{{ 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 "module" $module) }}
|
||||||
{{ partial "openapi/render-operation" $operation_params }}
|
{{ partial "openapi/render-operation" $operation_params }}
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ with $path_data.put }}
|
{{ 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 "module" $module) }}
|
||||||
{{ partial "openapi/render-operation" $operation_params }}
|
{{ partial "openapi/render-operation" $operation_params }}
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ with $path_data.delete }}
|
{{ 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 "module" $module) }}
|
||||||
{{ partial "openapi/render-operation" $operation_params }}
|
{{ partial "openapi/render-operation" $operation_params }}
|
||||||
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
* `operation_data`: the OpenAPI data for the operation
|
* `operation_data`: the OpenAPI data for the operation
|
||||||
* `anchor_base`: an optional prefix for the HTML IDs generated by
|
* `anchor_base`: an optional prefix for the HTML IDs generated by
|
||||||
this template.
|
this template.
|
||||||
|
* `page`: the (Hugo) Page object to store endpoint metadata in the Scratch of. Used to build the endpoints TOC.
|
||||||
|
* `module`: the current CS API module name, if any. Used to group endpoints in the TOC.
|
||||||
|
|
||||||
This template renders the operation as a `<section>` containing:
|
This template renders the operation as a `<section>` containing:
|
||||||
|
|
||||||
|
|
@ -22,6 +24,8 @@
|
||||||
{{ $method := .method }}
|
{{ $method := .method }}
|
||||||
{{ $endpoint := .endpoint }}
|
{{ $endpoint := .endpoint }}
|
||||||
{{ $operation_data := .operation_data }}
|
{{ $operation_data := .operation_data }}
|
||||||
|
{{ $page := .page }}
|
||||||
|
{{ $module := .module }}
|
||||||
|
|
||||||
{{ $anchor := "" }}
|
{{ $anchor := "" }}
|
||||||
{{ if .anchor_base }}
|
{{ if .anchor_base }}
|
||||||
|
|
@ -29,6 +33,27 @@
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ $anchor = printf "%s%s%s" $anchor (lower $method) (anchorize $endpoint) }}
|
{{ $anchor = printf "%s%s%s" $anchor (lower $method) (anchorize $endpoint) }}
|
||||||
|
|
||||||
|
{{/* 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 "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 }}
|
||||||
|
|
||||||
<section class="rendered-data">
|
<section class="rendered-data">
|
||||||
|
|
||||||
<details {{ if not site.Params.ui.rendered_data_collapsed }}open{{ end }}>
|
<details {{ if not site.Params.ui.rendered_data_collapsed }}open{{ end }}>
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,57 @@
|
||||||
{{- /*
|
{{- /*
|
||||||
|
|
||||||
A modified version of the siderbar-tree.html partial in Docsy, adding:
|
A copy of the siderbar-tree.html partial in Docsy, modified to:
|
||||||
|
|
||||||
* The "toc.html" partial at L45.
|
* Ignore the `sidebarRoot` parameter, because of this regression:
|
||||||
|
<https://github.com/google/docsy/issues/2426>
|
||||||
|
* Add the "toc.html" partial at L68.
|
||||||
|
|
||||||
*/ -}}
|
*/ -}}
|
||||||
|
|
||||||
{{/* We cache this partial for bigger sites and set the active class client side. */ -}}
|
{{ $context := .context -}}
|
||||||
{{ $sidebarCacheLimit := .Site.Params.ui.sidebar_cache_limit | default 2000 -}}
|
{{ $sidebarRoot := .sidebarRoot -}}
|
||||||
{{ $shouldDelayActive := ge (len .Site.Pages) $sidebarCacheLimit -}}
|
{{ $sidebarRootID := .sidebarRootID -}}
|
||||||
|
{{ $cacheSidebar := .cacheSidebar -}}
|
||||||
|
|
||||||
|
{{ with $context -}}
|
||||||
|
{{/* When the sidebar is cached, "active" class is set client side. */ -}}
|
||||||
|
{{ $shouldDelayActive := $cacheSidebar -}}
|
||||||
|
|
||||||
<div id="td-sidebar-menu" class="td-sidebar__inner{{ if $shouldDelayActive }} d-none{{ end }}">
|
<div id="td-sidebar-menu" class="td-sidebar__inner{{ if $shouldDelayActive }} d-none{{ end }}">
|
||||||
{{ if not .Site.Params.ui.sidebar_search_disable -}}
|
{{ if not .Site.Params.ui.sidebar_search_disable -}}
|
||||||
|
|
||||||
<form class="td-sidebar__search d-flex align-items-center">
|
<form class="td-sidebar__search d-flex align-items-center">
|
||||||
{{ partial "search-input.html" . }}
|
{{ partial "search-input.html" . }}
|
||||||
<button class="btn btn-link td-sidebar__toggle d-md-none p-0 ms-3 fas fa-bars" type="button" data-bs-toggle="collapse" data-bs-target="#td-section-nav" aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
|
<button class="btn btn-link td-sidebar__toggle" type="button" {{/**/ -}}
|
||||||
|
data-bs-toggle="collapse" data-bs-target="#td-section-nav" {{/**/ -}}
|
||||||
|
aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
{{ else -}}
|
|
||||||
|
{{- else -}}
|
||||||
|
|
||||||
<div id="content-mobile">
|
<div id="content-mobile">
|
||||||
<form class="td-sidebar__search d-flex align-items-center">
|
<form class="td-sidebar__search d-flex align-items-center">
|
||||||
{{ partial "search-input.html" . }}
|
{{ partial "search-input.html" . }}
|
||||||
<button class="btn btn-link td-sidebar__toggle d-md-none p-0 ms-3 fas fa-bars" type="button" data-bs-toggle="collapse" data-bs-target="#td-section-nav" aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
|
<button class="btn btn-link td-sidebar__toggle" type="button" {{/**/ -}}
|
||||||
|
data-bs-toggle="collapse" data-bs-target="#td-section-nav" {{/**/ -}}
|
||||||
|
aria-controls="td-section-nav" aria-expanded="false" aria-label="Toggle section navigation">
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="content-desktop"></div>
|
<div id="content-desktop"></div>
|
||||||
{{ end -}}
|
|
||||||
|
{{- end }}
|
||||||
|
{{/* */ -}}
|
||||||
|
|
||||||
<nav class="td-sidebar-nav collapse
|
<nav class="td-sidebar-nav collapse
|
||||||
{{- if .Site.Params.ui.sidebar_search_disable }} td-sidebar-nav--search-disabled{{ end -}}
|
{{- if .Site.Params.ui.sidebar_search_disable }} td-sidebar-nav--search-disabled{{ end -}}
|
||||||
{{- if .Site.Params.ui.sidebar_menu_foldable }} foldable-nav{{ end -}}
|
{{- if .Site.Params.ui.sidebar_menu_foldable }} foldable-nav{{ end }}" {{/**/ -}}
|
||||||
" id="td-section-nav">
|
id="td-section-nav"
|
||||||
{{ if (gt (len .Site.Home.Translations) 0) -}}
|
{{- if .Site.Params.ui.sidebar_root_enabled }} data-sidebar-root-id="{{ $sidebarRootID }}"{{ end -}}
|
||||||
<div class="td-sidebar-nav__section nav-item dropdown d-block d-lg-none">
|
>
|
||||||
|
{{ if and .Site.Params.ui.sidebar_lang_menu (gt (len .Site.Home.Translations) 0) -}}
|
||||||
|
<div class="td-sidebar-nav__section nav-item d-block d-lg-none">
|
||||||
{{ partial "navbar-lang-selector.html" . }}
|
{{ partial "navbar-lang-selector.html" . }}
|
||||||
</div>
|
</div>
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
|
@ -45,44 +65,129 @@
|
||||||
{{ partial "toc.html" . }}
|
{{ partial "toc.html" . }}
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{- end }}{{/* with $context */ -}}
|
||||||
|
|
||||||
{{ define "section-tree-nav-section" -}}
|
{{ define "section-tree-nav-section" -}}
|
||||||
{{ $s := .section -}}
|
{{/* cSpell:ignore manuallink manuallinkrelref manuallinktitle */ -}}
|
||||||
{{ $p := .page -}}
|
{{ $s := .section -}}
|
||||||
{{ $shouldDelayActive := .shouldDelayActive -}}
|
{{ $p := .page -}}
|
||||||
{{ $sidebarMenuTruncate := .sidebarMenuTruncate -}}
|
{{ $shouldDelayActive := .shouldDelayActive -}}
|
||||||
{{ $treeRoot := cond (eq .ulNr 0) true false -}}
|
{{ $sidebarMenuTruncate := .sidebarMenuTruncate -}}
|
||||||
{{ $ulNr := .ulNr -}}
|
{{ $treeRoot := cond (eq .ulNr 0) true false -}}
|
||||||
{{ $ulShow := .ulShow -}}
|
{{ $ulNr := .ulNr -}}
|
||||||
{{ $active := and (not $shouldDelayActive) (eq $s $p) -}}
|
{{ $ulShow := .ulShow -}}
|
||||||
{{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}}
|
{{ $active := and (not $shouldDelayActive) (eq $s $p) -}}
|
||||||
{{ $show := cond (or (lt $ulNr $ulShow) $activePath (and (not $shouldDelayActive) (eq $s.Parent $p.Parent)) (and (not $shouldDelayActive) (eq $s.Parent $p)) (not $p.Site.Params.ui.sidebar_menu_compact) (and (not $shouldDelayActive) ($p.IsDescendant $s.Parent))) true false -}}
|
{{ $activePath := and (not $shouldDelayActive) (or (eq $p $s) ($p.IsDescendant $s)) -}}
|
||||||
{{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}}
|
{{ $show := cond
|
||||||
{{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}}
|
(or
|
||||||
{{ $pages := $pages_tmp | first $sidebarMenuTruncate -}}
|
(lt $ulNr $ulShow)
|
||||||
{{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}}
|
$activePath
|
||||||
{{ if gt $truncatedEntryCount 0 -}}
|
(and (not $shouldDelayActive) (eq $s.Parent $p.Parent))
|
||||||
{{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s"
|
(and (not $shouldDelayActive) (eq $s.Parent $p))
|
||||||
$truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}}
|
(not $p.Site.Params.ui.sidebar_menu_compact)
|
||||||
{{ end -}}
|
(and (not $shouldDelayActive) ($p.IsDescendant $s.Parent))
|
||||||
{{ $withChild := gt (len $pages) 0 -}}
|
)
|
||||||
{{ $manualLink := cond (isset $s.Params "manuallink") $s.Params.manualLink ( cond (isset $s.Params "manuallinkrelref") (relref $s $s.Params.manualLinkRelref) $s.RelPermalink) -}}
|
true false
|
||||||
{{ $manualLinkTitle := cond (isset $s.Params "manuallinktitle") $s.Params.manualLinkTitle $s.Title -}}
|
-}}
|
||||||
<li class="td-sidebar-nav__section-title td-sidebar-nav__section{{ if $withChild }} with-child{{ else }} without-child{{ end }}{{ if $activePath }} active-path{{ end }}{{ if (not (or $show $p.Site.Params.ui.sidebar_menu_foldable )) }} collapse{{ end }}" id="{{ $mid }}-li">
|
{{ $mid := printf "m-%s" ($s.RelPermalink | anchorize) -}}
|
||||||
{{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}}
|
{{ $pages_tmp := where (union $s.Pages $s.Sections).ByWeight ".Params.toc_hide" "!=" true -}}
|
||||||
<input type="checkbox" id="{{ $mid }}-check"{{ if $activePath}} checked{{ end }}/>
|
{{ $pages := $pages_tmp | first $sidebarMenuTruncate -}}
|
||||||
<label for="{{ $mid }}-check"><a href="{{ $manualLink }}"{{ if ne $s.LinkTitle $manualLinkTitle }} title="{{ $manualLinkTitle }}"{{ end }}{{ with $s.Params.manualLinkTarget }} target="{{ . }}"{{ if eq . "_blank" }} rel="noopener"{{ end }}{{ end }} class="align-left ps-0 {{ if $active}} active{{ end }} td-sidebar-link{{ if $s.IsPage }} td-sidebar-link__page{{ else }} td-sidebar-link__section{{ end }}{{ if $treeRoot }} tree-root{{ end }}" id="{{ $mid }}">{{ with $s.Params.Icon}}<i class="{{ . }}"></i>{{ end }}<span class="{{ if $active }}td-sidebar-nav-active-item{{ end }}">{{ $s.LinkTitle }}</span></a></label>
|
{{ $truncatedEntryCount := sub (len $pages_tmp) $sidebarMenuTruncate -}}
|
||||||
{{ else -}}
|
|
||||||
<a href="{{ $manualLink }}"{{ if ne $s.LinkTitle $manualLinkTitle }} title="{{ $manualLinkTitle }}"{{ end }}{{ with $s.Params.manualLinkTarget }} target="{{ . }}"{{ if eq . "_blank" }} rel="noopener"{{ end }}{{ end }} class="align-left ps-0{{ if $active}} active{{ end }} td-sidebar-link{{ if $s.IsPage }} td-sidebar-link__page{{ else }} td-sidebar-link__section{{ end }}{{ if $treeRoot }} tree-root{{ end }}" id="{{ $mid }}">{{ with $s.Params.Icon}}<i class="{{ . }}"></i>{{ end }}<span class="{{ if $active }}td-sidebar-nav-active-item{{ end }}">{{ $s.LinkTitle }}</span></a>
|
{{ if gt $truncatedEntryCount 0 -}}
|
||||||
{{- end }}
|
{{ warnf "WARNING: %d sidebar entries have been truncated. To avoid this, increase `params.ui.sidebar_menu_truncate` to at least %d (from %d) in your config file. Section: %s"
|
||||||
{{- if $withChild }}
|
$truncatedEntryCount (len $pages_tmp) $sidebarMenuTruncate $s.Path -}}
|
||||||
{{- $ulNr := add $ulNr 1 }}
|
{{ end -}}
|
||||||
<ul class="ul-{{ $ulNr }}{{ if (gt $ulNr 1)}} foldable{{end}}">
|
|
||||||
{{ range $pages -}}
|
{{ $withChild := gt (len $pages) 0 -}}
|
||||||
{{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}}
|
{{ $manualLink :=
|
||||||
{{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }}
|
cond
|
||||||
|
(isset $s.Params "manuallink")
|
||||||
|
$s.Params.manualLink
|
||||||
|
(cond
|
||||||
|
(isset $s.Params "manuallinkrelref")
|
||||||
|
(relref $s $s.Params.manualLinkRelref)
|
||||||
|
$s.RelPermalink
|
||||||
|
)
|
||||||
|
-}}
|
||||||
|
{{ $manualLinkTitle :=
|
||||||
|
cond
|
||||||
|
(isset $s.Params "manuallinktitle")
|
||||||
|
$s.Params.manualLinkTitle
|
||||||
|
$s.Title
|
||||||
|
-}}
|
||||||
|
{{ if and $treeRoot (eq $s.Params.sidebar_root_for "self") -}}
|
||||||
|
{{ with $s.Parent -}}
|
||||||
|
{{ $manualLink = .RelPermalink -}}
|
||||||
|
{{ end -}}
|
||||||
|
{{ end -}}
|
||||||
|
<li class="td-sidebar-nav__section-title td-sidebar-nav__section
|
||||||
|
{{- if $withChild }} with-child{{ else }} without-child{{ end -}}
|
||||||
|
{{ if $activePath }} active-path{{ end -}}
|
||||||
|
{{ if (not (or $show $p.Site.Params.ui.sidebar_menu_foldable )) }} collapse{{ end -}}
|
||||||
|
" {{/**/ -}}
|
||||||
|
id="{{ $mid }}-li" {{- /**/ -}}
|
||||||
|
>
|
||||||
|
{{ if (and $p.Site.Params.ui.sidebar_menu_foldable (ge $ulNr 1)) -}}
|
||||||
|
<input type="checkbox" id="{{ $mid }}-check"{{ if $activePath}} checked{{ end }}/>
|
||||||
|
<label for="{{ $mid }}-check">{{/**/ -}}
|
||||||
|
<a href="{{ $manualLink }}"
|
||||||
|
{{- if ne $s.LinkTitle $manualLinkTitle }} {{/**/ -}}
|
||||||
|
title="{{ $manualLinkTitle }}"
|
||||||
|
{{- end -}}
|
||||||
|
{{ with $s.Params.manualLinkTarget }} {{/**/ -}}
|
||||||
|
target="{{ . }}"
|
||||||
|
{{- if eq . "_blank" }} rel="noopener"{{ end -}}
|
||||||
|
{{ end }} {{/**/ -}}
|
||||||
|
class="align-left ps-0 {{ if $active}} active{{ end }} td-sidebar-link
|
||||||
|
{{- if $s.IsPage }} td-sidebar-link__page
|
||||||
|
{{- else }} td-sidebar-link__section
|
||||||
|
{{- end }}
|
||||||
|
{{- if $treeRoot }} tree-root{{ end }}" {{/**/ -}}
|
||||||
|
id="{{ $mid }}" {{- /**/ -}}
|
||||||
|
>
|
||||||
|
{{- with $s.Params.Icon -}}
|
||||||
|
<i class="{{ . }}"></i>
|
||||||
|
{{- end -}}
|
||||||
|
<span class="{{ if $active }}td-sidebar-nav-active-item{{ end }}">
|
||||||
|
{{- $s.LinkTitle -}}
|
||||||
|
</span> {{- /**/ -}}
|
||||||
|
</a> {{- /**/ -}}
|
||||||
|
</label>
|
||||||
|
{{ else -}}
|
||||||
|
<a href="{{ $manualLink }}"
|
||||||
|
{{- if ne $s.LinkTitle $manualLinkTitle }} title="{{ $manualLinkTitle }}"{{ end -}}
|
||||||
|
{{ with $s.Params.manualLinkTarget }} {{/**/ -}}
|
||||||
|
target="{{ . }}"
|
||||||
|
{{- if eq . "_blank" }} rel="noopener"{{ end -}}
|
||||||
|
{{ end }} {{/**/ -}}
|
||||||
|
class="align-left ps-0
|
||||||
|
{{- if $active}} active{{ end }} {{/**/ -}}
|
||||||
|
td-sidebar-link
|
||||||
|
{{- if $s.IsPage }} td-sidebar-link__page{{ else }} td-sidebar-link__section{{ end }}
|
||||||
|
{{- if $treeRoot }} tree-root{{ end }}" {{/**/ -}}
|
||||||
|
id="{{ $mid }}" {{- /**/ -}}
|
||||||
|
>
|
||||||
|
{{- with $s.Params.Icon -}}
|
||||||
|
<i class="{{ . }}"></i>
|
||||||
|
{{- end -}}
|
||||||
|
<span class="
|
||||||
|
{{- if $active }}td-sidebar-nav-active-item{{ end -}}
|
||||||
|
{{- if and $s.Params.sidebar_root_for site.Params.ui.sidebar_root_enabled }} td-sidebar-root-up-icon{{ end -}}
|
||||||
|
">
|
||||||
|
{{- $s.LinkTitle -}}
|
||||||
|
</span></a>
|
||||||
|
{{- end -}}
|
||||||
|
{{ if $withChild -}}
|
||||||
|
{{ $ulNr := add $ulNr 1 }}
|
||||||
|
<ul class="ul-{{ $ulNr }}{{ if (gt $ulNr 1)}} foldable{{end}}">
|
||||||
|
{{ range $pages -}}
|
||||||
|
{{ if (not (and (eq $s $p.Site.Home) (eq .Params.toc_root true))) -}}
|
||||||
|
{{ template "section-tree-nav-section" (dict "page" $p "section" . "shouldDelayActive" $shouldDelayActive "sidebarMenuTruncate" $sidebarMenuTruncate "ulNr" $ulNr "ulShow" $ulShow) }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
</ul>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
</li>
|
||||||
</ul>
|
{{- end }}
|
||||||
{{- end }}
|
|
||||||
</li>
|
|
||||||
{{- end -}}
|
|
||||||
|
|
|
||||||
14
layouts/_partials/spec-content.html
Normal file
14
layouts/_partials/spec-content.html
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{{- /* Shared render for spec pages: title, optional description, endpoints list, body, and last-mod info. */ -}}
|
||||||
|
<div class="td-content">
|
||||||
|
<h1>{{ .Title }}</h1>
|
||||||
|
{{ with .Params.description }}<p class="page-description">{{ . | markdownify }}</p>{{ end }}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
Render an endpoints table of contents. This is the main difference
|
||||||
|
between our templates (which call the spec-content partial) and the default
|
||||||
|
Docsy template.
|
||||||
|
*/}}
|
||||||
|
{{ partial "endpoints-toc.html" . }}
|
||||||
|
|
||||||
|
{{ .Content }}
|
||||||
|
</div>
|
||||||
|
|
@ -1,15 +1,29 @@
|
||||||
{{/*
|
{{/*
|
||||||
|
|
||||||
A modified version of the toc.html partial in Docsy.
|
A copy of the toc.html partial in Docsy, modified to:
|
||||||
|
|
||||||
*/}}
|
* show the page's title instead of "on this page"
|
||||||
{{ $page := .Params }}
|
|
||||||
|
*/ -}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
|
||||||
|
Always render the td-toc element. ScrollSpy is counting on it to exist,
|
||||||
|
even if it's empty.
|
||||||
|
|
||||||
|
cSpell:ignore notoc
|
||||||
|
*/ -}}
|
||||||
|
|
||||||
|
<div class="td-toc" data-proofer-ignore>
|
||||||
{{ if not .Params.notoc -}}
|
{{ if not .Params.notoc -}}
|
||||||
{{ with .TableOfContents -}}
|
{{ $toc := .TableOfContents -}}
|
||||||
<hr>
|
{{ if and $toc (ne $toc `<nav id="TableOfContents"></nav>`) -}}
|
||||||
<div id="toc">
|
<div class="td-toc-title">
|
||||||
<a id="toc-title" href="#">{{ $page.Title }}</a>
|
<span class="td-toc-title__text">{{ .Params.Title }}</span>
|
||||||
{{ . }}
|
<a class="td-toc-title__link" title="{{ i18n "toc_top_of_page" }}" href="#"></a>
|
||||||
</div>
|
</div>
|
||||||
|
{{ $toc | safeHTML }}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
{{ end -}}
|
{{ end -}}
|
||||||
|
</div>
|
||||||
|
{{/* */ -}}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,39 @@
|
||||||
This template is used to render a Client-Server API Module. Modules are defined
|
This template is used to render a Client-Server API Module. Modules are defined
|
||||||
alongside the `_index.md` for the CS API.
|
alongside the `_index.md` for the CS API.
|
||||||
|
|
||||||
The `name` parameter is the file name without extension.
|
The following parameters are expected:
|
||||||
|
|
||||||
|
* `filename` the name of the module file to render, without extension (i.e. `spaces`).
|
||||||
|
* `name` the display name of the module (i.e. `Spaces`).
|
||||||
|
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
{{ $name := .Params.name }}
|
{{ $name := .Params.name }}
|
||||||
|
{{ $filename := .Params.filename }}
|
||||||
|
|
||||||
{{ with .Site.GetPage "client-server-api/modules" }}
|
{{ with .Site.GetPage "client-server-api/modules" }}
|
||||||
{{ with .Resources.GetMatch (printf "%s%s" $name ".md") }}
|
{{ with .Resources.GetMatch (printf "%s%s" $filename ".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 */}}
|
||||||
|
{{ .Scratch.Set "endpoint_module" $name }}
|
||||||
|
|
||||||
{{ .RenderShortcodes }}
|
{{ .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 }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,20 @@
|
||||||
{{ $api := .Params.api}}
|
{{ $api := .Params.api}}
|
||||||
{{ $anchor_base := .Params.anchor_base}}
|
{{ $anchor_base := .Params.anchor_base}}
|
||||||
|
|
||||||
|
{{/*
|
||||||
|
|
||||||
|
Figure out which Page object to pass to the `openapi/render-api` partial.
|
||||||
|
Either our own, or one stored under `endpoint_page` in the Scratch, if one
|
||||||
|
exists.
|
||||||
|
|
||||||
|
*/}}
|
||||||
|
{{ $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 }}
|
{{ $api_data := index .Site.Data.api .Params.spec .Params.api }}
|
||||||
{{ $base_url := (index $api_data.servers 0).variables.basePath.default }}
|
{{ $base_url := (index $api_data.servers 0).variables.basePath.default }}
|
||||||
{{ $path := delimit (slice "api" $spec $api) "/" }}
|
{{ $path := delimit (slice "api" $spec $api) "/" }}
|
||||||
|
|
@ -30,4 +44,4 @@
|
||||||
{{ $api_data = partial "json-schema/resolve-refs" (dict "schema" $api_data "path" $path) }}
|
{{ $api_data = partial "json-schema/resolve-refs" (dict "schema" $api_data "path" $path) }}
|
||||||
{{ $api_data = partial "json-schema/resolve-allof" $api_data }}
|
{{ $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" $target_page "module" $module_name) }}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
<div class="td-content">
|
|
||||||
<h1>{{ .Title }}</h1>
|
|
||||||
{{ .Content }}
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
{{/*
|
{{/*
|
||||||
|
|
||||||
A copy of the baseof.html partial in Docsy, modified
|
A copy of the baseof.html partial in Docsy, modified to:
|
||||||
to remove the right-hand column from the layout.
|
|
||||||
|
|
||||||
*/}}
|
* generate a static file `versions.json` that can be used to populate the
|
||||||
|
version picker.
|
||||||
|
* remove the right-hand column from the layout.
|
||||||
|
|
||||||
{{/* Generate a static file versions.json that can be used to populate the version picker */}}
|
*/ -}}
|
||||||
|
|
||||||
|
{{/* Generate a static file versions.json that can be used to populate the version picker */ -}}
|
||||||
{{ if .IsHome }}
|
{{ if .IsHome }}
|
||||||
{{- /* Load all changelog subpages, sorted by release date */ -}}
|
{{- /* Load all changelog subpages, sorted by release date */ -}}
|
||||||
{{ $changelog := site.GetPage "changelog" }}
|
{{ $changelog := site.GetPage "changelog" }}
|
||||||
|
|
@ -28,20 +31,18 @@
|
||||||
<html itemscope itemtype="http://schema.org/WebPage"
|
<html itemscope itemtype="http://schema.org/WebPage"
|
||||||
{{- with .Site.Language.LanguageDirection }} dir="{{ . }}" {{- end -}}
|
{{- with .Site.Language.LanguageDirection }} dir="{{ . }}" {{- end -}}
|
||||||
{{ with .Site.Language.Lang }} lang="{{ . }}" {{- end }} {{/**/ -}}
|
{{ with .Site.Language.Lang }} lang="{{ . }}" {{- end }} {{/**/ -}}
|
||||||
class="no-js">
|
class="no-js"
|
||||||
|
{{- $darkMode := partialCached "dark-mode-config.html" "dark-mode-global" -}}
|
||||||
|
{{- if $darkMode.enable }} data-theme-init{{ end }}>
|
||||||
<head>
|
<head>
|
||||||
{{ partial "head.html" . }}
|
{{ partial "head.html" . }}
|
||||||
{{ if .Page.Store.Get "hasMath" }}
|
|
||||||
<link href="{{ relURL "css/katex.min.css" }}" rel="preload" as="style">
|
|
||||||
<link href="{{ relURL "css/katex.min.css" }}" rel="stylesheet">
|
|
||||||
{{ end }}
|
|
||||||
</head>
|
</head>
|
||||||
<body class="td-{{ .Kind }}{{ with .Page.Params.body_class }} {{ . }}{{ end }}">
|
<body class="td-{{ .Kind }}{{ with .Page.Params.body_class }} {{ . }}{{ end }}">
|
||||||
<header>
|
<header>
|
||||||
{{ partial "navbar.html" . }}
|
{{ partial "navbar.html" . }}
|
||||||
</header>
|
</header>
|
||||||
<div class="container-fluid td-outer">
|
<div class="container-fluid td-outer">
|
||||||
<div class="td-main">
|
<div class="td-main" {{- partialCached "td/scrollspy-attr.txt" . .Section | safeHTMLAttr }}>
|
||||||
<div class="row flex-xl-nowrap">
|
<div class="row flex-xl-nowrap">
|
||||||
<aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none">
|
<aside class="col-12 col-md-3 col-xl-2 td-sidebar d-print-none">
|
||||||
{{ partial "sidebar.html" . }}
|
{{ partial "sidebar.html" . }}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
{{/*
|
{{/*
|
||||||
|
|
||||||
A simplified version of the list.html partial in Docsy.
|
Override the `layouts/docs/list.html` template from Docsy. While this template
|
||||||
|
is equivalent to `single.html`, it's necessary to override both templates to
|
||||||
|
avoid falling back to the default Docsy templates.
|
||||||
|
|
||||||
|
https://gohugo.io/templates/types/#list
|
||||||
|
|
||||||
|
We use this list template to render the Client-Server API spec page and each
|
||||||
|
of its modules.
|
||||||
|
|
||||||
|
The contents of the "main" block below are inserted into the `./baseof.html`
|
||||||
|
base template.
|
||||||
|
|
||||||
*/}}
|
*/}}
|
||||||
|
|
||||||
{{ define "main" }}
|
{{ define "main" }}
|
||||||
<div class="td-content">
|
{{ partial "spec-content.html" . }}
|
||||||
<h1>{{ .Title }}</h1>
|
|
||||||
{{ with .Params.description }}<div class="lead">{{ . | markdownify }}</div>{{ end }}
|
|
||||||
{{ .Content }}
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
19
layouts/docs/single.html
Normal file
19
layouts/docs/single.html
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{{/*
|
||||||
|
|
||||||
|
Override the `layouts/docs/single.html` template from Docsy. While this template
|
||||||
|
is equivalent to `list.html`, it's necessary to override both templates to
|
||||||
|
avoid falling back to the default Docsy templates.
|
||||||
|
|
||||||
|
https://gohugo.io/templates/types/#single
|
||||||
|
|
||||||
|
We use this single template to render the all API spec pages *except* the
|
||||||
|
Client-Server API. The Client-Server API spec page contains modules, and thus
|
||||||
|
is handled separately, via the `layouts/docs/list.html` template.
|
||||||
|
|
||||||
|
The contents of the "main" block below are inserted into the `./baseof.html`
|
||||||
|
base template.
|
||||||
|
|
||||||
|
*/}}
|
||||||
|
{{ define "main" }}
|
||||||
|
{{ partial "spec-content.html" . }}
|
||||||
|
{{ end }}
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue