# A club's forum belongs to the club, not to the site

*12 August 2026*

## The report

> The forums still don't show under Clubs like it should. When you add forums
> in clubs it needs to actually show in the club. Just like Clubs in IPS or my
> social groups Flarum and original Convoro extension.

and then, with a screenshot of the admin Forums screen:

> The thing is forums in clubs should not show in the core forums area. Right
> now they are showing as uncategorized and they shouldn't even show there at
> all. Like it needs to be a feature inside Clubs but independent of the actual
> site forums.

Two halves of one complaint, and the second names the real defect. A club's
forum is currently a site forum that happens to be restricted. It should be a
club's forum that happens to be built out of the forum application.

## The half that already worked

`ListedElsewhere` exists for exactly this. A container claimed in it is listed
by whoever owns it rather than on the general index, `ClubContent` claims every
container it creates, and a migration backfilled the ones that predated it.

The reasoning in that class still stands and is not being revisited: no column
on `forums`, because the Clubs migration will not ALTER another module's table
and a club must work on a site with Forums switched off; and no Forums-asks-
Clubs, because that is the dependency the whole design avoids.

## The half that was missed

Exactly one caller ever used it: the front forum index. Every other place that
presents the site's forums queried `forums` directly and got the club's forum
back, which is what put "Uncategorised" in the screenshot.

Nine surfaces, all of them a list of *the site's forums* offered for browsing
or for choosing:

| Where | What it is |
| --- | --- |
| Admin → Forums | the screenshot; the site's forum structure |
| Activity filter | "show me activity in…" |
| Sitemap | 🚨 a private forum must never be in it |
| API `/v1/forums` | the site's forums, to an integration |
| Widget forum picker | which forum a widget draws from |
| Widget section scoping | where a widget appears |
| Page builder | which forum a page block reads |
| Downloads → announce in | where new-file topics go |
| Settings → forum picker | a site-wide default |

The sitemap one is the sharp one. Group restriction keeps a stranger from
*reading* a club forum, but the sitemap is generated for everybody and would
have published the club's forum URLs regardless.

A single filter at each. The call is the same one line everywhere, which is
deliberate: nine slightly different exclusions would be eight chances to write
one of them wrong.

## Then they must be manageable somewhere

Hiding them from Admin → Forums is only right if an administrator can still
reach them, otherwise the fix trades a wrong listing for an invisible one. The
Clubs admin screen already counts a club's contents; it now lists them — kind,
name, topic count, and a link — so the thing that owns them is the thing that
shows them.

## The other half: opening a club's forum

With the separation done, the club's own page lists the forum and the link goes
to `/forum/{slug}`. Following it still leaves: no club header, no members, no
way back, nothing saying which club it belongs to.

### Two ways, and why the second

**Nested routes.** `/clubs/{club}/forum/{forum}` renders the topic list in a
club template. Closest to what IPS does, and it means a second topic list. The
forum module already has one — display modes, covers, pinning, read markers,
realtime, bulk moderation — and a copy inside Clubs is a copy that drifts. The
first feature added to one and not the other is a club forum quietly worse than
a normal one, and nobody notices until a member asks why they cannot do the
thing their friend can. It also gives every topic list two URLs.

**The club renders around the forum.** `/forum/{slug}` stays the one URL, and
when the forum belongs to a club the club's header and contents render above
it. One topic list, one URL, and the club is visibly there.

Taking the second.

### 🚨 The dependency still runs one way

Forums gains no club lookup and no club branch. The Club module registers on
`forum.show.top`, a hook the forum page already exposed. Switch Clubs off and
nothing registers, so the forum renders as an ordinary forum rather than
erroring on a table that is no longer there.

The band carries the club's name linked back to it, the member count — so the
restriction is explained rather than merely imposed — and the club's other
contents, so you can move between them without going back first.

It asks the club's own rules rather than assuming the caller checked. A
restricted forum is already unreachable by a non-member, but a hook runs on
whatever page renders it, and a private club must not even confirm it exists.

## One-line bug found on the way

The club page computes its contents for `$isMember || $this->isAdmin()` and the
template then gates the section on `$isMember || $mayLead`. An administrator
who is not a member gets the list built and then hidden. The template follows
the controller.

## Scope

Forums, because that is what was reported and what people put in clubs.
Gallery, Calendar and Blogs already claim into `ListedElsewhere` the same way,
so their indexes were never wrong; each picks up the band with one registration
against its own `*.show.top` and no new reasoning.
