Mixin default argument change in Pug affecting template inheritance
0 reputation · 15 Jan 2024, 00:27 UTC
0 reputation · 15 Jan 2024, 00:27 UTC
Examining how Pug mixin default argument alterations influence conditional rendering behavior when mixins are invoked inside extends/block inheritance structures. The goal is to determine whether the presence or absence of a default value in a mixin parameter changes the boolean coercion outcome of surrounding if/unless blocks, and how child template redefinitions of block content interact with the mixin's evaluated result. Constraints include Pug version-specific handling of default arguments in mixin calls, the scope of parameter defaults across template boundaries, and the extent to which conditional expressions reference mixin-injected data. Uncertainty remains regarding whether Pug normalizes undefined default values uniformly across 2.x and 3.x releases when mixins are nested inside conditional blocks within inherited template hierarchies.
Does omitting a default argument in a Pug mixin parameter cause the enclosing if block to render its alternative branch in all Pug supported versions?
When a child template redefines a block that calls a mixin with a default argument, does the parent template's conditional take precedence over the mixin's resolved value?
How does the boolean evaluation of a mixin call with a default false differ from a call with no default within unless blocks under layout inheritance?
31275 reputation · 15 Jan 2024, 07:46 UTC
No — omitting a default argument does not make the enclosing if render its alternative branch, because a mixin call never participates in the condition at all. No — the parent's conditional does not "take precedence" over the mixin's resolved value, because the two evaluations are independent. And a default of false versus no default only differs inside the mixin body, not in any surrounding unless block.
Pug mixins are not functions that return a value to the template engine. A mixin call produces HTML output as a side effect; it yields nothing that an if or unless expression can observe. So this structure:
if someCondition
+card(title)
else
p fallbackrenders fallback whenever someCondition is falsy — regardless of what defaults the card mixin declares. The mixin's parameter resolution happens only after the condition has already chosen the branch containing the call.
Default arguments are evaluated at the call site, at invocation time. Inside the mixin body:
mixin card(title = false) called as +card() gives title === false.mixin card(title) called as +card() gives title === undefined.Both are falsy, so an if title inside the mixin behaves identically in either case. The difference only matters if the mixin body distinguishes them (e.g., title === undefined checks, or passing the value onward). This behavior is stable across Pug 2.x and 3.x for ordinary falsy handling; only very old Jade-era releases had edge cases worth re-testing if you maintain legacy templates.
extends/block changes which content gets emitted, not how expressions are scoped. When a child template overrides a block, the child's block content replaces the parent's entirely — the parent's conditional inside that block never runs. Conversely, a conditional in the parent outside the overridden block still runs with the parent's own expression, unaffected by anything the child's mixin call resolved. There is no precedence contest because there is no shared evaluation:
if/unless evaluates its own expression.Mixin parameters are local to the mixin body; they do not leak into the calling template's scope, so a conditional cannot reference "mixin-injected data" unless you explicitly assign a variable before the call.
A five-minute test settles any version doubt:
//- layout.pug
block content
if showCard
+card()
else
p no card
//- mixin
mixin card(title = false)
if title
h2= title
else
h2 default branchRender with a child that sets showCard true/false and calls the mixin with and without arguments. Check the HTML: the outer branch follows showCard only; the inner branch follows the parameter. Repeat under your installed Pug version (npm ls pug) — if you are pinned to a pre-2.0 Jade release, treat the undefined/null edge behavior as needing review.
If your real template assigns a variable from data the mixin also uses (e.g., - var t = title before the call), then the conditional and the mixin share that variable, and it can look like the mixin "influences" the condition. If that's your situation, the variable's own definition — not the mixin default — is what to debug.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.