Add distributions page (#2907)

* feat: Add Distributions Page

* chore: Fix the description having a trailing space

* Add synapse-operator and BundesMessenger distributions

* chore: remove .vscode directory from version control

* update ESS to ESS Community

* update summary from PR review

* reorder, add opendesk

* add matrix_standard tooltip

* update support levels

Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>

* reorder ecosystem

Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>

* add distros to CONTENT.md

Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>

* highly visible disclaimer

Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>

* remove non-standard distro code

Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>

---------

Signed-off-by: HarHarLinks <2803622+HarHarLinks@users.noreply.github.com>
Co-authored-by: MTRNord <mtrnord1@gmail.com>
This commit is contained in:
Kim Brose 2025-09-26 14:55:53 +02:00 committed by GitHub
parent 1a434e5d4a
commit cac177f004
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 343 additions and 7 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
/public
.DS_Store
gatsby
.vscode

View file

@ -241,7 +241,7 @@ maintainer = "Your name or organisation"
maturity = "PICK ONE Stable OR Beta OR Alpha OR Obsolete"
language = "The programminglanguage of your server. For example 'Python'"
licence = "PICK ONE identifier from https://spdx.org/licenses/"
repository = "github.com/example-org/example-repo"
repository = "https://github.com/example-org/example-repo"
# In which type of application this SDK is meant to get used. This should be an array.
# Possible values are "bridge", "bot", "client"
purpose = ["bot", "bridge"]
@ -250,11 +250,31 @@ A short description about the SDK.
"""
```
### Distributions
Distros are listed in [`/content/ecosystem/distributions/distributions.toml`](https://github.com/matrix-org/matrix.org/blob/main/content/ecosystem/distributions/distributions.toml). A distribution is an artifact grouping multiple components of a Matrix stack and making them easy to deploy in one package.
To add a distribution please use this template and append it to the `distributions.toml`:
```toml
[[distributions]]
name = "My Matrix Distro"
description = "This is my distro, exactly how I like it."
vendor = "Your name or organisation"
maturity = "PICK ONE Stable OR Beta OR Alpha OR Obsolete"
frameworks = ["Name at least one installation technology.", "You may also add more."]
licence = "PICK ONE identifier from https://spdx.org/licenses/"
repository = "https://github.com/example-org/example-repo"
room = "#your-matrix-room:example.com"
support_level = "PICK ONE Community OR Commercial"
matrix_standard = true if it is compatible with Matrix standard apps, false if it only works fully when self-contained
```
### Hosting providers
Hosting provders are listed in [`/content/ecosystem/hosting/providers.toml`](https://github.com/matrix-org/matrix.org/blob/main/content/ecosystem/hosting/providers.toml). It lists providers which provide Matrix components like servers or bots to customers. We require this section to only contain providers that do the actual hosting. Providers which either provide a setup script or only provide selfhosting should go into the in the future existing Distributions section instead.
To add a hosting provider entry, add the following template to the `providers.toml`. Logos should be placed next to the the toml file. A logo should be in the SVG format. However if this is not available a PNG is acceptable provided it has sufficient resolution while also having reasonable filesize.
To add a hosting provider entry, add the following template to the `providers.toml`. Logos should be placed next to the toml file. A logo should be in the SVG format. However if this is not available a PNG is acceptable provided it has sufficient resolution while also having reasonable filesize.
```toml
[[providers]]

View file

@ -1,6 +1,6 @@
+++
title = "Bridges"
weight = 2
weight = 3
template = "ecosystem/bridges.html"
extra.summary = """
Bridges allow you to connect Matrix to a third-party platform, and interact

View file

@ -0,0 +1,56 @@
[[distributions]]
name = "openDesk CE"
description = "The customisable office and collaboration suite designed specifically for your needs in public administration."
vendor = "ZenDiS GmbH"
maturity = "Stable"
frameworks = ["Helmfile", "Helm", "Kubernetes"]
licence = "Apache-2.0"
repository = "https://gitlab.opencode.de/bmi/opendesk"
support_level = "Community"
matrix_standard = true
[[distributions]]
name = "synapse-operator"
description = "The Synapse operator offers a convenient way to deploy and manage a Synapse server. It was built with operator-sdk."
vendor = "Red Hat"
maturity = "Stable"
frameworks = ["Kubernetes"]
licence = "Apache-2.0"
repository = "https://github.com/opdev/synapse-operator"
support_level = "Community"
matrix_standard = true
[[distributions]]
name = "ESS Community"
description = "Element Server Suite Community Edition allows you to deploy a Matrix stack using the provided Helm charts and a Kubernetes distribution of your choice, even if you don't have Kubernetes knowledge."
vendor = "Element"
maturity = "Stable"
frameworks = ["Kubernetes"]
licence = "AGPL-3.0"
repository = "https://github.com/element-hq/ess-helm"
support_level = "Community"
matrix_standard = true
[[distributions]]
name = "Ananace Helm Charts"
description = "Kubernetes applications packaged into helm charts"
vendor = "Ananace"
maturity = "Stable"
frameworks = ["Helm", "Kubernetes"]
licence = "Apache-2.0"
repository = "https://gitlab.com/ananace/charts"
room = "#matrix-on-kubernetes:fiksel.info"
support_level = "Community"
matrix_standard = true
[[distributions]]
name = "matrix-docker-ansible-deploy"
description = "🐳 Matrix (An open network for secure, decentralized communication) server setup using Ansible and Docker"
vendor = "Splanteev"
maturity = "Stable"
frameworks = ["Ansible", "Docker"]
licence = "AGPL-3.0"
repository = "https://github.com/spantaleev/matrix-docker-ansible-deploy"
room = "#matrix-docker-ansible-deploy:devture.com"
support_level = "Community"
matrix_standard = true

View file

@ -0,0 +1,10 @@
+++
title = "Distributions"
template = "ecosystem/distributions.html"
weight = 5
extra.summary = """
A Matrix distribution is a collection of software related to Matrix that is deployed and automatically configured so the different pieces integrate with one another. To appear on this list, users need to be able to join and participate in the public federation from an instance of a distribution if the administrator configures it for this purpose.
"""
+++
{{ all_distributions() }}

View file

@ -1,7 +1,7 @@
+++
title = "Hosting"
template = "ecosystem/hosting.html"
weight = 4
weight = 6
extra.summary = """
Everyone can host their Matrix server, but not everybody wants to. These are the providers the Matrix.org Foundation knows about.
"""

View file

@ -1,6 +1,7 @@
+++
title = "SDKs"
weight = 3
weight = 4
extra.order = 4
template = "ecosystem/sdks.html"
extra.summary = """
Develop great apps, bots, and bridges. Focus on what you do best. Let the SDKs

70
sass/_distributions.scss Normal file
View file

@ -0,0 +1,70 @@
.distributions {
p {
text-align: center;
font-weight: 400;
font-size: 1.125rem;
line-height: 120%;
margin: 0 auto 4rem auto;
}
}
.distribution-links {
margin-top: auto;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
gap: .7rem;
a {
display: flex;
align-items: center;
gap: .3rem;
border: 1px solid #777;
border-radius: 999px;
padding-inline: .5rem;
font-size: .8rem;
svg {
width: 1.2em;
height: 1.2em;
* {
fill: #777;
}
line {
stroke: #777;
}
}
}
a:hover {
color: #fff;
background-color: #777;
svg {
* {
fill: #fff;
}
line {
stroke: #fff;
}
}
}
}
.standard {
border: 1px solid var(--borders-color);
border-radius: 9999px;
padding: 0 .6rem;
font-weight: 600;
justify-self: flex-end;
background-color: #F6D5D5;
border-color: #8B1212;
color: #8B1212;
}

View file

@ -37,7 +37,7 @@
}
h3 {
margin: 0;
margin: 0 .2rem 0 0;
font-style: normal;
font-weight: 700;
@ -192,6 +192,7 @@
font-size: 1rem;
font-weight: 400;
max-width: fit-content;
justify-self: flex-end;
&.stable {
background-color: #DFF6D5;
@ -225,6 +226,7 @@
justify-content: space-between;
gap: .2rem;
align-items: start;
flex-wrap: wrap;
}
#filters-overlay {

View file

@ -11,6 +11,7 @@
@import '_clients';
@import '_bridges';
@import '_servers';
@import '_distributions';
@import '_sdks';
@import '_otwsu';
@import '_about-bios';

View file

@ -0,0 +1,20 @@
import { AllOfFilter, AnyOfFilter, refreshCardsView } from "./projects.js";
document.addEventListener('DOMContentLoaded', (event) => {
var filters = [];
let maturityFilter = new AnyOfFilter("filter-maturity", "all-distributions", filters);
let supportFilter = new AnyOfFilter("filter-support", "all-distributions", filters);
let licenceFilter = new AnyOfFilter("filter-licence", "all-distributions", filters);
let frameworkFilter = new AnyOfFilter("filter-framework", "all-distributions", filters);
filters.push(
maturityFilter,
supportFilter,
licenceFilter,
frameworkFilter
);
refreshCardsView("all-distributions", filters);
for (const filter of filters) {
filter.refreshActiveState();
}
})

View file

@ -0,0 +1,19 @@
{% extends "page.html" %}
{% block head_extra %}
<meta name="description" content="{{ page.extra.summary }}">
<noscript>
<link rel="stylesheet" href="/no-js.css" />
</noscript>
<script type="module" src="/js/distributions.js"></script>
{% endblock head_extra%}
{% block content %}
<div class="page-header">
<div class="hero-block">
<h1>{{ page.title }}</h1>
<p>{{ page.extra.summary }}</p>
</div>
</div>
<div class="content distributions">
<p>{{ page.content | safe }}</p>
</div>
{% endblock content %}

View file

@ -0,0 +1,11 @@
{% macro classes(distribution) %}
maturity-{{ distribution.maturity | lower }}
licence-{{ distribution.licence | slugify }}
{% for framework in distribution.frameworks %}
framework-{{ framework | slugify }}
{% endfor %}
support-{{ distribution.support_level | slugify }}
{% endmacro %}

View file

@ -0,0 +1,126 @@
{% import "macros/distributions.html" as srvutils %}
{% set distributions_data = load_data(path="content/ecosystem/distributions/distributions.toml") %}
{% set licences = [] %}
{% set frameworks = [] %}
{% set support_levels = [] %}
{% for distribution in distributions_data.distributions %}
{% set_global licences = licences | concat(with=distribution.licence) %}
{% set_global frameworks = frameworks | concat(with=distribution.frameworks) %}
{% set_global support_levels = support_levels | concat(with=distribution.support_level) %}
{% endfor %}
{% set licences = licences | unique | sort %}
{% set frameworks = frameworks | unique | sort %}
{% set support_levels = support_levels | unique | sort %}
<div class="filters">
<div class="filter-wrap">
<button id="filter-maturity" class="filter">
Maturity
<div class="divider"></div>
<img src="/assets/down-arrow.svg" alt="Downard facing arrow">
</button>
<div id="filter-maturity-menu" class="filter-menu">
<p>The distribution can support any of the maturity levels checked.</p>
<div class="filter-option">
<input id="maturity-stable" type="checkbox" checked>
<label for="maturity-stable">Stable</label>
</div>
<div class="filter-option">
<input id="maturity-beta" type="checkbox" checked>
<label for="maturity-beta">Beta</label>
</div>
<div class="filter-option">
<input id="maturity-alpha" type="checkbox" checked>
<label for="maturity-alpha">Alpha</label>
</div>
<div class="filter-option">
<input id="maturity-obsolete" type="checkbox">
<label for="maturity-obsolete">Obsolete</label>
</div>
<div class="reset-links">Select <button>all</button> - <button>none</button></div>
</div>
</div>
<div class="filter-wrap">
<button id="filter-licence" class="filter">
Licence
<div class="divider"></div>
<img src="/assets/down-arrow.svg" alt="Downard facing arrow">
</button>
<div id="filter-licence-menu" class="filter-menu">
<p>The distribution can support any of the licences checked.</p>
{% for licence in licences %}
<div class="filter-option">
<input id="licence-{{ licence | slugify }}" type="checkbox" checked>
<label for="licence-{{ licence | slugify }}">{{ licence }}</label>
</div>
{% endfor %}
<div class="reset-links">Select <button>all</button> - <button>none</button></div>
</div>
</div>
<div class="filter-wrap">
<button id="filter-framework" class="filter">
Framework
<div class="divider"></div>
<img src="/assets/down-arrow.svg" alt="Downard facing arrow">
</button>
<div id="filter-framework-menu" class="filter-menu">
<p>The distribution is using any of the frameworks checked.</p>
{% for framework in frameworks %}
<div class="filter-option">
<input id="framework-{{ framework | slugify }}" type="checkbox" checked>
<label for="framework-{{ framework | slugify }}">{{ framework }}</label>
</div>
{% endfor %}
<div class="reset-links">Select <button>all</button> - <button>none</button></div>
</div>
</div>
<div class="filter-wrap">
<button id="filter-support" class="filter">
Support Level
<div class="divider"></div>
<img src="/assets/down-arrow.svg" alt="Downard facing arrow">
</button>
<div id="filter-support-menu" class="filter-menu">
<p>The distribution has any of these support levels.</p>
{% for support in support_levels %}
<div class="filter-option">
<input id="support-{{ support | slugify }}" type="checkbox" checked>
<label for="support-{{ support | slugify }}">{{ support }}</label>
</div>
{% endfor %}
<div class="reset-links">Select <button>all</button> - <button>none</button></div>
</div>
</div>
</div>
<div id="filters-overlay"></div>
<div id="all-distributions" class="projects-card-deck">
{% for distribution in distributions_data.distributions | sort(attribute="maturity") | reverse %}
<div>
<div class="project-card {{ srvutils::classes(distribution=distribution) }}">
<div class="title-row">
<h3>{{ distribution.name }}</h3>
<div class="maturity {{ distribution.maturity | lower }}">{{ distribution.maturity }}</div>
</div>
<div>{{ distribution.licence }} &middot; {% for framework in distribution.frameworks %}{{
framework }}{% if not loop.last %} &ndash; {% endif %}{% endfor %}</div>
<span>{{ distribution.description | safe }}</span>
<div class="distribution-links">
{% if distribution.repository %}
<a href="{{ distribution.repository }}">
{{ load_data(path="/assets/projects/repo.svg") | safe }}
Repository
</a>
{% endif %}
{% if distribution.room %}
<a href="https://matrix.to/#/{{ distribution.room }}">
{{ load_data(path="/assets/projects/matrix.svg") | safe }}
Matrix Room
</a>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>