Перейти к содержимому

UIComponent

UIComponent — базовый класс для создания экранов бота с автоматической маршрутизацией callback_data.

from edgebot import UIComponent
АтрибутТипПо умолчаниюОписание
__prefix__str""Уникальный префикс для callback_data (обязательно)
promptstr | NoneNoneКлюч промпта в PromptRegistry
markupstr | NoneNoneКлюч клавиатуры в KeyboardRegistry
textstr""Inline-шаблон текста (альтернатива prompt)

Точка входа в экран. Обязательно переопределяется в наследнике.

async def open(self, ctx: Context, **kwargs) -> None:
...

Обычно внутри:

  1. Загружает данные из KV / реестров
  2. Вызывает self.send(ctx, prompt_kwargs=..., markup_kwargs=...)

Отправляет новое сообщение экрана.

async def send(
self,
ctx: Context,
*,
prompt: str | Prompt | None = None,
markup: str | InlineKeyboard | None = None,
prompt_kwargs: dict | None = None,
markup_kwargs: dict | None = None,
parse_mode: str | None = None,
) -> dict
ПараметрОписание
promptЯвный источник промпта (ключ или Prompt). Если Noneself.prompt или self.text
markupЯвный источник клавиатуры (ключ или InlineKeyboard). Если Noneself.markup
prompt_kwargsДанные для фабрики промпта и Prompt.render()
markup_kwargsДанные для фабрики клавиатуры
parse_modeРежим парсинга; по умолчанию — bot.parse_mode

Редактирует текущее сообщение. Сигнатура идентична send().

async def update(self, ctx, ...) -> dict | None

Быстрая проверка принадлежности callback к этому компоненту.

def matches(self, callback_data: str) -> bool

Возвращает True, если callback_data начинается с "{__prefix__}:".

Внутренний метод маршрутизации. Вызывается из Bot.process_update().

async def handle_callback(self, ctx: Context) -> bool

Последовательность:

  1. Проверка startswith("{prefix}:")
  2. Сопоставление с зарегистрированными паттернами (first-match)
  3. Fallback "*" (если задан)

Возвращает True, если callback был обработан.

Привязывает метод к паттерну callback_data.

@UIComponent.callback(pattern: str)
ПаттернПример callback_datakwargs
"toggle""prof:toggle"
"del:{user_id}""prof:del:123"user_id="123"
"page:{num}""prof:page:5"num="5"
"*""prof:anything"
  • Паттерн пишется без префикса компонента
  • {name} — именованная переменная, значение передаётся в метод как kwarg
  • "*" — fallback, ловит всё не подошедшее под другие паттерны
class OrderScreen(UIComponent):
__prefix__ = "order"
@UIComponent.callback("confirm:{order_id}")
async def on_confirm(self, ctx: Context, order_id: str) -> None:
await ctx.answer_callback(f"Заказ {order_id} подтверждён")
@UIComponent.callback("cancel:{order_id}")
async def on_cancel(self, ctx: Context, order_id: str) -> None:
await ctx.answer_callback(f"Заказ {order_id} отменён")
@UIComponent.callback("*")
async def on_fallback(self, ctx: Context) -> None:
await ctx.answer_callback("Неизвестное действие")

Приоритет определения текста сообщения:

  1. Аргумент prompt в send() / update() (str → ключ в реестре; Prompt → как есть)
  2. Атрибут self.prompt (ключ в PromptRegistry)
  3. Атрибут self.text (inline-шаблон, оборачивается в Prompt)

Если ни один источник не найден — UIError.

Приоритет определения клавиатуры:

  1. Аргумент markup в send() / update() (str → ключ в реестре; InlineKeyboard → как есть)
  2. Атрибут self.markup (ключ в KeyboardRegistry)
  3. None — экран без клавиатуры (допустимо)