feat(guilds): a third place on the guild page, and where that page lives
All checks were successful
PR Checks / server-tests (pull_request) Successful in 23s
PR Checks / client-build (pull_request) Successful in 17s
PR Checks / frozen-manifest (pull_request) Successful in 34s

Two lines only core cannot supply for itself.

`uo.guild.header` is a third declared slot, at the top of the page, for core's
per-Team notification control. A third rather than a corner of the feed because a
slot holds one component and the first fill wins: the control is an action ON this
page and the other two are content IN it, and separate slots are what let this
module say so.

`pageUrlTemplate` tells core where a guild page actually is. Teams are a contract
primitive with no core surface — core owns the tables and the access rules, this
module owns the word "guild" and therefore the page — which leaves core unable to
write a link to one. A notification email that cannot take you to the thread it is
about is most of the way to useless. Core substitutes `{externalId}` and does
nothing else with it; a template naming its own host is refused at registration.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-18 14:35:36 -05:00
parent 7ce78e303c
commit c57310c505
4 changed files with 39 additions and 5 deletions

View File

@@ -75,6 +75,13 @@ export default function Guild() {
{data.alliance && ` · ${data.alliance}`}
</p>
{/* A third place for core, up here rather than below the roster: core
puts this guild's notification control in it, and a control that
acts on the page belongs beside the page's title and not after its
content. Empty for a visitor with no membership, and on a core
that fills nothing. */}
<Slot name="uo.guild.header" externalId={String(id)} moduleId="uo" />
{roster.length > 0 && (
<div style={{ overflowX: 'auto', marginTop: 18 }}>
<table style={{ width: '100%', borderCollapse: 'collapse' }}>