Whether anything a page or a layout draws can read the signed-in user — the question that decides, once at compile time, whether serving that page has to load and verify one at all.
MishkaCmsWeb.RuntimeLive used to be handed a finished @current_user on every mount, because
the live session it is routed in loads one for every LiveView under it. For a signed-in visitor
that is a token-row read and a user read on every page and every live navigation, and the great
majority of database pages are brochure pages that never mention a visitor at all.
So the compiler answers it instead, and the answer is baked into the record's own module:
MishkaCmsCore.Runtime.Compilers.LiveViewCompiler.build_assigns/1 writes it into
__page_information__/0 and
MishkaCmsCore.Runtime.Compilers.LayoutCompiler.build_layout_information/1 into
__layout_information__/0, both under private.reads_user. A page whose own answer and whose
layout's answer are both false is served without anything being looked up; every other page is
served exactly as it was, by the same verification. A page that names permissions is judged by a
user whatever this says — see MishkaCmsWeb.RuntimeLive's admit/3, which asks for one before it
asks this.
One record at a time, which is what keeps the answer fresh
A page and its layout are asked SEPARATELY and their answers are put together at request time, because a module is only ever rebuilt for its own record: editing a layout rebuilds the layout module and no page under it. An answer about somebody else's source, baked here, would go stale the moment that source changed — the layout would start reading the visitor and every page already compiled would go on saying nobody is signed in.
Nothing else has to be asked, because a runtime component is handed ONLY the assigns its call site
writes: MishkaCmsCore.Runtime.LiveViewHelpers.component/1 builds that map from the tag's own
attributes, so a component's assigns holds component_name, site and whatever else the tag
named, and nothing of the page's. A component can therefore reach the visitor in exactly two ways,
and this module reads both off the record's own source:
- the tag hands it something naming
current_user, which is text in this record; or - the tag hands it the caller's WHOLE bag —
assigns, or@socket, whose ownassignsis thePhoenix.LiveView.Socket.AssignsNotInSocketstruct holding that same map in__assigns__, and whoseprivateholds the visitor's session besides.
So the question never leaves the record being compiled, and the answer cannot be made wrong by editing anything else.
Asked of the text, on purpose
MishkaCmsCore.Runtime.Compilers.LiveViewCompiler.shows_messages?/1 asks its question of the
PARSED template, because a wrong yes there is a visitor who is told nothing. Here the polarity is
the other way round: a wrong yes costs two queries on one page, and a wrong no is a signed-in
visitor shown a page that believes nobody is signed in. So this one looks for the name in every
piece of source the record can reach and over-approximates deliberately — a page whose prose
happens to contain current_user pays for a user it does not need, and nothing breaks.
That also makes it indifferent to spelling, which matters here: @current_user,
assigns[:current_user] — the form MishkaCmsCore.Runtime.PageBuilder.Conditions writes —
socket.assigns.current_user in a handler and @current_user inside a helper's ~H sigil are
four shapes in three grammars, and the name is the only thing all of them share.
What it reads
Every field of the record that is markup or Elixir — template, body, helpers, events, infos, and
the prelude, clauses and module attributes a component keeps in extra. The name is looked for in
all of them, and all of them are scanned for <.component …/> tags, because a tag written inside
a helper's ~H sigil hands over exactly what one in the template does.
Everything it cannot decide is a yes
A tag that spreads a map of attributes, a template that cannot be tokenised, a record that is not
there: each answers true. The one thing this must never do is answer false for a page that
turns out to want a user.
Summary
Functions
Whether anything record — a page or a layout — draws can read the signed-in user.