Skip to content

Component

Components are reusable message elements that can render content in both plain text and HTML. Subclasses implement to_plain_text and render, and can then be passed to methods such as Context.reply. matrix.py includes a built-in Table component for displaying labeled fields in a configurable column layout.

from matrix import Bot, Table

bot = Bot()


@bot.command()
async def weather(ctx):
    weather = Table(title="Los Angeles")

    weather.add_field("Description", "Clear Sky")
    weather.add_field("Visibility", "10000m | 32808ft")
    weather.add_field("Temperature", "71.33°F | 21.85°C")
    weather.add_field("Feels Like", "71.33°F | 21.85°C")
    weather.add_field("Atmospheric Pressure", "1012 hPa")
    weather.add_field("Humidity", "66%")

    await ctx.reply(component=weather)

matrix.component.Component

Bases: ABC

Base class for message components.

to_plain_text abstractmethod

to_plain_text()
Source code in matrix/component.py
14
15
16
@abstractmethod
def to_plain_text(self) -> str:
    pass

render abstractmethod

render()
Source code in matrix/component.py
18
19
20
@abstractmethod
def render(self) -> str:
    pass

matrix.component.Table

Table(*, title, column_count=2)

Bases: Component

A component that renders labeled fields as a table.

Fields are displayed in rows using the configured number of columns. Incomplete rows are padded with empty cells. Field names, values, and the table title are HTML-escaped when rendered.

Source code in matrix/component.py
31
32
33
34
35
36
37
def __init__(self, *, title: str, column_count: int = 2) -> None:
    if column_count < 1:
        raise ValueError("column_count must be greater than 0")

    self.title: str = title
    self.column_count: int = column_count
    self.fields: list[tuple[str, str]] = []

title instance-attribute

title = title

column_count instance-attribute

column_count = column_count

fields instance-attribute

fields = []

add_field

add_field(name, value)

Add a labeled field to the table.

Example
table = Table(title="User Info")
table.add_field("Name", "Astra")
Source code in matrix/component.py
42
43
44
45
46
47
48
49
50
51
52
def add_field(self, name: str, value: str) -> None:
    """Add a labeled field to the table.

    ## Example

    ```python
    table = Table(title="User Info")
    table.add_field("Name", "Astra")
    ```
    """
    self.fields.append((name, value))

to_plain_text

to_plain_text()

Render the table as plain text.

Example
table = Table(title="User Info")
table.add_field("Name", "Astra")

result = table.to_plain_text()
# User Info
# Name: Astra
Source code in matrix/component.py
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def to_plain_text(self) -> str:
    """Render the table as plain text.

    ## Example

    ```python
    table = Table(title="User Info")
    table.add_field("Name", "Astra")

    result = table.to_plain_text()
    # User Info
    # Name: Astra
    ```
    """
    return "\n".join(
        [self.title, *[f"{name}: {value}" for name, value in self.fields]]
    )

render

render()

Render the table as HTML with escaped field content.

Incomplete rows are padded with empty cells based on the configured column count.

Example
table = Table(title="User Info")
table.add_field("Name", "Astra")
table.add_field("Role", "Engineer")

html = table.render()
Source code in matrix/component.py
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
def render(self) -> str:
    """Render the table as HTML with escaped field content.

    Incomplete rows are padded with empty cells based on the configured
    column count.

    ## Example

    ```python
    table = Table(title="User Info")
    table.add_field("Name", "Astra")
    table.add_field("Role", "Engineer")

    html = table.render()
    ```
    """
    cells = []
    for name, value in self.fields:
        cells.append(
            CELL_TEMPLATE.format(
                name=escape(name),
                value=escape(value),
            )
        )

    rows = []
    for i in range(0, len(cells), self.column_count):
        row_cells = cells[i : i + self.column_count]

        while len(row_cells) < self.column_count:
            row_cells.append("<td></td>")

        rows.append(ROW_TEMPLATE.format(cells="".join(row_cells)))

    return TABLE_TEMPLATE.format(
        title=escape(self.title),
        rows="".join(rows),
    )