Skip to content

Commit 25144c0

Browse files
committed
Allow configuring page title (browser)
1 parent 7b6a513 commit 25144c0

File tree

6 files changed

+25
-3
lines changed

6 files changed

+25
-3
lines changed

mesop/examples/text_io.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import mesop.labs as mel
55

66

7-
@me.page(path="/text_io")
7+
@me.page(path="/text_io", title="Text I/O Example")
88
def app():
99
mel.text_io(upper_case_stream)
1010

mesop/features/page.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55

66
def page(
7-
*, path: str = "/"
7+
*,
8+
path: str = "/",
9+
title: str | None = None,
810
) -> Callable[[Callable[[], None]], Callable[[], None]]:
911
def decorator(func: Callable[[], None]) -> Callable[[], None]:
1012
def wrapper() -> None:
1113
return func()
1214

1315
runtime().register_path_fn(path, wrapper)
16+
runtime().register_path_title(path, title or f"Mesop: {path}")
1417
return wrapper
1518

1619
return decorator

mesop/protos/ui.proto

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ message ContextLine {
144144

145145
message RenderEvent {
146146
optional Component root_component = 1;
147+
optional string title = 5;
147148
optional States states = 2;
148149
repeated Command commands = 3;
149150

mesop/runtime/runtime.py

+8
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class EmptyState:
2626

2727
class Runtime:
2828
_path_fns: dict[str, Callable[[], None]]
29+
_path_title: dict[str, str]
2930
_handlers: dict[str, Handler]
3031
_state_classes: list[type[Any]]
3132
_loading_errors: list[pb.ServerError]
@@ -36,6 +37,7 @@ class Runtime:
3637
def __init__(self):
3738
self.component_fns = set()
3839
self._path_fns = {}
40+
self._path_title = {}
3941
self._handlers = {}
4042
self.event_mappers: dict[Type[Any], Callable[[pb.UserEvent, Key], Any]] = {}
4143
self._state_classes = []
@@ -89,6 +91,12 @@ def run_path(self, path: str, trace_mode: bool = False) -> None:
8991
def register_path_fn(self, path: str, fn: Callable[[], None]) -> None:
9092
self._path_fns[path] = fn
9193

94+
def register_path_title(self, path: str, title: str) -> None:
95+
self._path_title[path] = title
96+
97+
def get_path_title(self, path: str) -> str:
98+
return self._path_title[path]
99+
92100
def register_handler(self, handler_id: str, handler: Handler) -> None:
93101
self._handlers[handler_id] = handler
94102

mesop/server/server.py

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ def render_loop(
2727
) -> Generator[str, None, None]:
2828
try:
2929
runtime().run_path(path=path, trace_mode=trace_mode)
30+
title = runtime().get_path_title(path=path)
3031
root_component = runtime().context().current_node()
3132

3233
data = pb.UiResponse(
@@ -35,6 +36,7 @@ def render_loop(
3536
states=runtime().context().serialize_state(),
3637
commands=runtime().context().commands(),
3738
component_configs=get_component_configs(),
39+
title=title,
3840
)
3941
)
4042
yield serialize(data)

mesop/web/src/services/channel.ts

+9-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
EditorEvent,
1313
} from 'mesop/mesop/protos/ui_jspb_proto_pb/mesop/protos/ui_pb';
1414
import {Logger} from '../dev_tools/services/logger';
15+
import {Title} from '@angular/platform-browser';
1516

1617
const anyWindow = window as any;
1718
const DEV_SERVER_HOST = anyWindow['MESOP_SERVER_HOST'] || '';
@@ -43,7 +44,10 @@ export class Channel {
4344
private componentConfigs: ComponentConfig[] = [];
4445
private queuedEvents: (() => void)[] = [];
4546

46-
constructor(private logger: Logger) {}
47+
constructor(
48+
private logger: Logger,
49+
private title: Title,
50+
) {}
4751

4852
getStatus(): ChannelStatus {
4953
return this.status;
@@ -96,6 +100,10 @@ export class Channel {
96100
onNavigate(navigate.getUrl()!);
97101
}
98102
}
103+
const title = uiResponse.getRender()!.getTitle();
104+
if (title) {
105+
this.title.setTitle(title);
106+
}
99107
this.rootComponent = rootComponent;
100108
this.componentConfigs = uiResponse
101109
.getRender()!

0 commit comments

Comments
 (0)