diff --git a/CONTENT.md b/CONTENT.md index 943cdacb35..a6a63525fd 100644 --- a/CONTENT.md +++ b/CONTENT.md @@ -356,3 +356,21 @@ To keep documentation on matrix.org tidy and approachable, it needs to be sorted Images make concepts easier to understand than walls of text. Screenshots make the documentation easier to follow in the onboarding and community sections. Diagrams and other illustrations can help break down more technical or complicated documentation. We are happy to review your documentation contributions and help you with any questions that you may end up with. + +### Glossary + +The glossary at [`/docs/glossary/`](https://matrix.org/docs/glossary/) defines the words, jargon, and acronyms used across Matrix and The Matrix.org Foundation. All entries live in a single file, [`/content/docs/glossary/terms.toml`](https://github.com/matrix-org/matrix.org/blob/main/content/docs/glossary/terms.toml), grouped into one array-of-tables per category (`[[terms.core]]`, `[[terms.security]]`, `[[terms.trust_safety]]`, `[[terms.governance]]`). You do not need to know Markdown, TOML tooling, or how the site builds to contribute — the file can be edited directly from GitHub's web UI. + +To add a term, append the following template under the right category's block in `terms.toml` (or start a new `[[terms.]]` block for a new category - the page picks up and labels any category automatically): + +```toml +[[terms.core]] +term = "My term" +aliases = ["Optional alternate names or abbreviations"] +definition = "One or two plain-language sentences explaining the term." +learn_more = "/docs/some/relevant/page/#anchor" # optional, internal or external link +``` + +Only `term` and `definition` are required; `aliases` and `learn_more` can be omitted. Terms don't need to be added in alphabetical order — the page sorts them itself. If you do start a new category, also add its display label to the `categories` list in `templates/docs/glossary.html` (e.g. `{"label": "My Category", "terms": data.terms.my_category}`). + +If a term is really about the correct spelling or capitalisation of an official Matrix or Foundation name rather than what it means, it likely belongs on the [style guide](https://matrix.org/branding/#commonly-used-terms) instead. diff --git a/content/branding.md b/content/branding.md index 6238c061b9..28bf6248c2 100644 --- a/content/branding.md +++ b/content/branding.md @@ -42,4 +42,3 @@ The following table lists some terms that either are wordmarks of The Matrix.org | other organs | | Other organs of the Foundation are similarly capitalised, e.g. "Guardians", "Spec Core Team", "Trust & Safety". | | `#room:server.tld` | | Pronounced "[hash room on server dot tld](https://matrix.org/blog/wp-content/uploads/2014/09/Introducing-matrix.pdf)". | | `@user:server.tld` | | Pronounced "[at user on server dot tld](https://matrix.org/blog/wp-content/uploads/2014/09/Introducing-matrix.pdf)". | -| [vodozemac](https://github.com/matrix-org/vodozemac) | | Named after [vodozémac](https://hjp.znanje.hr/index.php?show=search_by_id&id=f19vXxZ%2F), the Croatian word for "amphibian". Pronounced "[vo-do-ze-mats](https://www.youtube.com/watch?v=mjndO734kco&t=38)". | diff --git a/content/docs/glossary/_index.md b/content/docs/glossary/_index.md new file mode 100644 index 0000000000..e6754b90d9 --- /dev/null +++ b/content/docs/glossary/_index.md @@ -0,0 +1,9 @@ ++++ +title = "Glossary" +weight = 500 +template = "docs/glossary.html" +[extra] +tile = "Definitions for the words and acronyms used across Matrix" +meta_description = "Definitions for the terms, jargon, and acronyms used across Matrix and The Matrix.org Foundation." +updated = "2026-07-15T00:00:00Z" ++++ diff --git a/content/docs/glossary/terms.toml b/content/docs/glossary/terms.toml new file mode 100644 index 0000000000..4693057ae2 --- /dev/null +++ b/content/docs/glossary/terms.toml @@ -0,0 +1,140 @@ +# Glossary entries shown on /docs/glossary/. +# +# Terms are grouped into arrays-of-tables named terms., one per +# category. To add a term, append a new block under the right category below +# (or start a new terms. for a new one - the page picks it up and +# labels/sorts it automatically). Only `term` and `definition` are required. +# +# [[terms.core]] +# term = "Your term" +# aliases = ["Optional alternate names or abbreviations"] +# definition = "One or two plain-language sentences." +# learn_more = "/docs/some/relevant/page/#anchor" # optional, internal or external + +[[terms.core]] +term = "Homeserver" +aliases = ["HS"] +definition = "A server that hosts Matrix user accounts and participates in the network. Every account belongs to exactly one homeserver, identified by that server's domain." +learn_more = "/docs/matrix-concepts/elements-of-matrix/#homeserver" + +[[terms.core]] +term = "Client" +definition = "An application people use to read and send messages on Matrix, such as Element. Clients talk to a homeserver, never directly to other clients." +learn_more = "/docs/matrix-concepts/elements-of-matrix/#client" + +[[terms.core]] +term = "Federation" +definition = "The process by which independently-run homeservers exchange room data with each other, so users on different servers can share rooms without depending on a central server." +learn_more = "/docs/matrix-concepts/elements-of-matrix/" + +[[terms.core]] +term = "Matrix user ID" +aliases = ["Matrix ID", "MXID", "User ID"] +definition = "A user's identifier, made up of a local part and the domain of their homeserver, written as `@username:example.com`. Pronounced \"at username on example dot com\"." +learn_more = "/docs/matrix-concepts/elements-of-matrix/#homeserver" + +[[terms.core]] +term = "Room" +definition = "A conversation, shared between the homeservers of everyone taking part. Each participating server keeps its own local copy of the room, which is kept in sync with the others." +learn_more = "/docs/matrix-concepts/rooms_and_events/" + +[[terms.core]] +term = "Room ID" +definition = "The internal, permanent identifier of a room, written as `!opaqueid:example.com`. Unlike a room's published address, it never changes for the lifetime of the room." +learn_more = "/docs/matrix-concepts/rooms_and_events/" + +[[terms.core]] +term = "Event" +definition = "A single timestamped, signed item in a room's history: a message, a membership change, a room setting being updated, and so on. Rooms are built up from a directed acyclic graph of events." +learn_more = "/docs/matrix-concepts/rooms_and_events/" + +[[terms.core]] +term = "State event" +definition = "An event that represents a piece of persistent room state (such as the room name, topic, or a member's membership) rather than a one-off message. Only the latest state event for a given type and key is considered current." +learn_more = "/docs/matrix-concepts/rooms_and_events/" + +[[terms.core]] +term = "Power level" +aliases = ["PL"] +definition = "A per-user or per-action number in a room that determines what a user is allowed to do, such as sending certain event types, kicking, or banning." +learn_more = "/docs/matrix-concepts/rooms_and_events/#administration-privileges" + +[[terms.core]] +term = "Application Service" +aliases = ["AppService"] +definition = "A privileged piece of software, registered with a homeserver, that can puppet many virtual users and rooms at once. Bridges and some advanced bots are built as Application Services." +learn_more = "https://spec.matrix.org/latest/application-service-api/" + +[[terms.core]] +term = "Bridge" +definition = "A form of Application Service that relays messages between Matrix and a third-party chat platform (for example IRC, Slack, or Discord), so users on either side can talk to each other." +learn_more = "/ecosystem/bridges/" + +[[terms.core]] +term = "Identity server" +definition = "A separate, optional service that maps third-party identifiers (such as email addresses or phone numbers) to Matrix IDs, used when inviting someone by contact detail instead of by their Matrix ID." + +[[terms.security]] +term = "End-to-end encryption" +aliases = ["E2EE"] +definition = "Encryption where messages are only readable by the sending and receiving devices, not by the homeservers relaying them. Matrix implements this using the Olm and Megolm cryptographic ratchets." +learn_more = "/docs/matrix-concepts/end-to-end-encryption/" + +[[terms.security]] +term = "vodozemac" +definition = "The Rust library implementing the Olm and Megolm cryptographic ratchets used for Matrix end-to-end encryption, replacing the older, now-deprecated libolm. Named after [vodozémac](https://hjp.znanje.hr/index.php?show=search_by_id&id=f19vXxZ%2F), the Croatian word for \"amphibian\". Pronounced \"[vo-do-ze-mats](https://www.youtube.com/watch?v=mjndO734kco&t=38)\"." +learn_more = "https://github.com/matrix-org/vodozemac" + +[[terms.security]] +term = "Device verification" +definition = "The process of two devices confirming each other's cryptographic identity keys out-of-band, so they can trust that messages are really coming from who they claim to be from." +learn_more = "/docs/matrix-concepts/end-to-end-encryption/#blocking-verifying-devices" + +[[terms.security]] +term = "Cross-signing" +definition = "A mechanism where a user signs their own devices with a private master key, so other users only need to verify that one master key to trust all of that user's current and future devices." + +[[terms.security]] +term = "Key backup" +definition = "An encrypted, server-side backup of a user's message decryption keys, so they aren't lost if all of a user's devices are lost or logged out at once." + +[[terms.security]] +term = "Unable to decrypt" +aliases = ["UTD"] +definition = "An error state shown for a message a client received but could not decrypt, usually because it never obtained the room key for that message." + +[[terms.trust_safety]] +term = "Account locking" +definition = "A reversible action where a user is prevented from logging in to their account, but the account itself is preserved in place." + +[[terms.trust_safety]] +term = "Account suspension" +definition = "A reversible action similar to locking, except the user can still log in and read their account; they just cannot write (send messages, join rooms, and so on)." + +[[terms.trust_safety]] +term = "Account deactivation" +definition = "A destructive, irreversible action where an account is removed from all rooms and permanently deleted." + +[[terms.governance]] +term = "Working Group" +aliases = ["WG"] +definition = "A standing group, formed under the Foundation's Governing Board, focused on getting a specific area of work done - for example events, or a part of the ecosystem." +learn_more = "/foundation/working-groups/" + +[[terms.governance]] +term = "Governing Board" +aliases = ["GB"] +definition = "The organ of The Matrix.org Foundation through which the ecosystem participates in its governance, made up of representatives elected or appointed from across the community." +learn_more = "/foundation/governing-board/" + +[[terms.governance]] +term = "Spec Core Team" +aliases = ["SCT"] +definition = "The team responsible for stewarding the Matrix specification itself, including reviewing and merging Matrix Spec Changes (MSCs)." +learn_more = "/foundation/about/#the-spec-core-team" + +[[terms.governance]] +term = "Matrix Spec Change" +aliases = ["MSC"] +definition = "A proposal to change or extend the Matrix specification, following the process defined by the Spec Core Team." +learn_more = "https://spec.matrix.org/proposals/" diff --git a/navigation.toml b/navigation.toml index e7bfc709cd..d683eba6bb 100644 --- a/navigation.toml +++ b/navigation.toml @@ -28,9 +28,14 @@ title = "Categories" href = "/category/" [[header]] +id = "docs" title = "Docs" href = "/docs/" +[[header.children]] +title = "Glossary" +href = "/docs/glossary/" + [[header]] title = "Ecosystem" section = "ecosystem" diff --git a/sass/_base.scss b/sass/_base.scss index 95e1354d3d..094abcb48a 100644 --- a/sass/_base.scss +++ b/sass/_base.scss @@ -18,6 +18,14 @@ --borders-color: #ddd; --notice-box-color: #ffcb006b; + + // Tokens for the shared breadcrumb/page-header component below. Kept + // distinct from the older --borders-color/--color-text-light pair above + // rather than merged into them, since those are already used with their + // own (slightly different) shades elsewhere. + --color-border: #d2d2d2; + --color-text-muted: #555; + --color-bg-tint: #fafafa; } * { diff --git a/sass/_breadcrumb.scss b/sass/_breadcrumb.scss new file mode 100644 index 0000000000..5dcfc2f0e6 --- /dev/null +++ b/sass/_breadcrumb.scss @@ -0,0 +1,81 @@ +// Breadcrumb navigation +// Used via macros/breadcrumb.html. Two contexts: +// 1. Inside .page-header (dark background) - text is white/muted-white +// 2. Inside .detail-page (light background) - text is muted grey + +.breadcrumb { + ol { + display: flex; + flex-wrap: wrap; + align-items: center; + list-style: none; + margin: 0; + padding: 0; + gap: 0.25rem; + font-size: 0.85rem; + } + + li { + display: flex; + align-items: center; + + // Chevron separator before every item except the first + & + li::before { + content: "/"; + margin-right: 0.25rem; + opacity: 0.45; + } + } + + a, + span { + text-decoration: none; + line-height: 1; + } + + // Dark context (inside .page-header) + .page-header & { + margin-bottom: 0.75rem; + + a { + color: rgb(255 255 255 / 70%); + + &:hover { + color: #fff; + } + } + + // 45% white only clears ~4.4:1 against the black hero background, + // just under AA's 4.5:1 for text; 60% keeps it safely above. + span { + color: rgb(255 255 255 / 60%); + } + + li + li::before { + color: rgb(255 255 255 / 45%); + } + } + + // Light context (inside .detail-page) + .detail-page & { + margin-bottom: 1.25rem; + + a { + color: var(--color-text-muted); + + &:hover { + color: var(--color-text); + } + } + + // The current-page label is text, not decoration, so it still needs + // to clear WCAG AA (4.5:1); #aaa on white only manages ~2.3:1. + span { + color: var(--color-text-light); + } + + li + li::before { + color: #ccc; + } + } +} diff --git a/sass/_glossary.scss b/sass/_glossary.scss new file mode 100644 index 0000000000..3a36f8e71c --- /dev/null +++ b/sass/_glossary.scss @@ -0,0 +1,188 @@ +// /docs/glossary/ - pure CSS/HTML, no JS. The jump nav is a set of plain +// anchor links to each category's #id, and .glossary-category headings use +// position: sticky so the current category stays visible while its terms +// scroll past, same idea as MDN's glossary letter headings. +// +// This page has its own breadcrumb markup instead of a shared macro, so it +// can land as an independent PR without depending on other in-flight work - +// but it does add (and use) --color-border/--color-bg-tint/--color-text-muted +// in _base.scss, so later work can build on those instead of redefining them. +.glossary-breadcrumb { + margin-bottom: 0.75rem; + + ol { + display: flex; + flex-wrap: wrap; + align-items: center; + list-style: none; + margin: 0; + padding: 0; + gap: 0.25rem; + font-size: 0.85rem; + } + + li { + display: flex; + align-items: center; + + & + li::before { + content: "/"; + margin-right: 0.25rem; + opacity: 0.45; + } + } + + a { + color: var(--color-text-muted); + text-decoration: none; + line-height: 1; + + &:hover { + color: var(--color-text); + } + } + + // The current-page label is text, not decoration, so it still needs to + // clear WCAG AA (4.5:1) against white; #aaa only manages ~2.3:1. + span { + color: var(--color-text-light); + line-height: 1; + } + + li + li::before { + color: #ccc; + } +} + +.glossary { + .glossary-contribute { + color: var(--color-text-muted); + font-size: 0.9rem; + } +} + +.glossary-jump { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin: 1.5rem 0; + + a { + padding: 0.4rem 0.9rem; + border: 1px solid var(--color-border); + border-radius: 999px; + color: inherit; + text-decoration: none; + font-size: 0.85rem; + font-weight: 600; + transition: background-color 0.15s ease; + + &:hover { + background-color: var(--color-bg-tint); + } + } +} + +.glossary-list { + display: flex; + flex-direction: column; + gap: 2rem; +} + +.glossary-category { + // The jump nav's #id targets this section, not the h2 - scroll-margin-top + // has to live here so the fixed .site-header (height: --navbar-height) + // doesn't end up covering the heading when the browser jumps to it. The + // 1.25rem (not 20px) is a fine-tuning offset, same idea as html's own + // scroll-padding-top below - it has to stay in rem too, or it stops + // cancelling out proportionally once the browser's base font size (and + // so --navbar-height/scroll-padding-top) is anything other than 16px. + scroll-margin-top: calc(var(--navbar-height) - 1.25rem); + + h2 { + position: sticky; + // Stick just below the fixed site header, not at the very top of the + // viewport, otherwise it's hidden behind the header and the first + // term ends up looking like the top of the section instead. + top: var(--navbar-height); + margin: 0; + padding: 0.5rem 0; + background-color: var(--color-bg-tint); + border-bottom: 1px solid var(--color-border); + // Big enough to read as a heading rather than blend into the term + // list below it (dt is 1.05rem) - matches the h4 step of the site's + // type scale (sass/_fonts.scss). + font-size: 1.44rem; + font-weight: 700; + } + + dl { + margin: 0; + } +} + +.glossary-term { + // Term anchors (the "#" permalinks) sit under both the fixed + // .site-header AND the sticky .glossary-category h2 above them, so they + // need clearance for both, unlike the category anchor above which only + // has the site-header to clear. 1.7rem is a fine-tuned offset for the + // h2's own rendered height - if that h2 changes, this needs to follow. + scroll-margin-top: calc(var(--navbar-height) + 1.7rem); + padding: 1.25rem 0; + + & + .glossary-term { + border-top: 1px solid var(--color-border); + } + + dt { + display: flex; + align-items: baseline; + gap: 0.35rem; + font-weight: 700; + font-size: 1.05rem; + } + + dd { + margin: 0.35rem 0 0; + color: var(--color-text-muted); + } + + // Only reveal the "#" permalink on hover/focus - it's a bonus for + // sighted mouse/keyboard users linking to a term, not something that + // needs to compete with the term name for attention at rest. + &:hover .glossary-term-anchor, + .glossary-term-anchor:focus { + opacity: 1; + } +} + +.glossary-aliases { + font-weight: 400; + font-size: 0.85rem; + color: var(--color-text-light); +} + +.glossary-term-anchor { + font-weight: 400; + font-size: 0.9rem; + color: var(--color-text-light); + text-decoration: none; + opacity: 0; + transition: opacity 0.15s ease; + + &:hover { + color: var(--color-link); + } +} + +.glossary-learn-more { + display: inline-block; + margin-top: 0.35rem; + font-weight: 600; + color: var(--color-link); + text-decoration: none; + + &:hover { + text-decoration: underline; + } +} diff --git a/sass/style.scss b/sass/style.scss index 93e0813b06..724c46ad4c 100644 --- a/sass/style.scss +++ b/sass/style.scss @@ -1,6 +1,7 @@ @import '_normalize'; @import '_fonts'; @import '_base'; +@import '_breadcrumb'; @import '_tables'; @import '_footer'; @import '_header'; @@ -18,6 +19,7 @@ @import '_about-bios'; @import '_legacy-docs'; @import '_docs'; +@import '_glossary'; @import '_security-hall-of-fame'; @import '_hosting'; @import '_try-matrix'; diff --git a/templates/docs/glossary.html b/templates/docs/glossary.html new file mode 100644 index 0000000000..c37fb244fd --- /dev/null +++ b/templates/docs/glossary.html @@ -0,0 +1,68 @@ +{% extends "docs/with_menu.html" %} +{% block head_extra %} + +{% endblock head_extra %} +{% block docs_content %} +{% set data = load_data(path="content/docs/glossary/terms.toml") %} +{# Category labels/keys, kept in alphabetical order by label (not by TOML + file order) so a reader doesn't get a seemingly-random category sequence. + Tera has no map literals to build a {label, terms} list dynamically and + sort it, so this is two parallel arrays instead - add new categories to + both, in the correct alphabetical position. #} +{% set category_labels = ["Core concepts", "Governance", "Security", "Trust & Safety"] %} +{% set category_keys = ["core", "governance", "security", "trust_safety"] %} +
+
+

{{ section.title }}

+
+ + {{ section.content | markdown | safe }} + +

+ Definitions for the words, jargon, and acronyms used across Matrix and + The Matrix.org Foundation. For the correct spelling and capitalisation + of Matrix-related names, see the commonly + used terms list instead. +

+

+ Missing a term, or spotted a mistake? + Suggest an edit on GitHub. +

+ + + +
+ {% for label in category_labels %} + {% set key = category_keys[loop.index0] %} +
+

{{ label }}

+
+ {% for term in data.terms[key] | sort(attribute="term") %} + {% set term_slug = term.term | slugify %} + {% set term_id = "term-" ~ term_slug %} +
+
+ {{ term.term }} + {% if term.aliases %} + ({{ term.aliases | join(sep=", ") }}) + {% endif %} + # +
+
+ {{ term.definition | markdown(inline=true) | safe }} + {% if term.learn_more %} + Learn more → + {% endif %} +
+
+ {% endfor %} +
+
+ {% endfor %} +
+
+{% endblock docs_content %} diff --git a/templates/docs/with_menu.html b/templates/docs/with_menu.html index f580de326a..0bae84a1a7 100644 --- a/templates/docs/with_menu.html +++ b/templates/docs/with_menu.html @@ -26,6 +26,14 @@ {% else %} {% set current = false %} {% endif %} + {% if doc_section.toc | length == 0 and doc_section.subsections | length == 0 %} + {# A flat page with no h2s/subsections of its own (e.g. the glossary) has + nothing to build an accordion out of - link straight to it instead of + rendering an empty, unclickable group. #} +
+ {{ doc_section.title }} +
+ {% else %}
@@ -65,11 +73,13 @@
{% endif %}
+ {% endif %} {% endfor %}
+ {% block docs_content %}

{{ section.title }}

@@ -90,6 +100,7 @@

{{ section.title }}

{{ section.content | markdown | safe }}
+ {% endblock docs_content %}
{% endblock content %} diff --git a/templates/macros/breadcrumb.html b/templates/macros/breadcrumb.html new file mode 100644 index 0000000000..506f8b8d79 --- /dev/null +++ b/templates/macros/breadcrumb.html @@ -0,0 +1,18 @@ +{% macro breadcrumb(l1_label, l1_path, l2_label="", l2_path="", l3_label="") %} + +{% endmacro %}