What is the best way to retrieve template argument outside the template?

Hey maucejo, recall this bit from my response:

This is why querying a state value requires a context { } block (see explanation: Context – Typst Documentation), which returns document content: the code inside it depends on where in the document it is evaluated, so the only way to know what the context block evaluates to is to place it somewhere in the document so it can use the correct values at that location.

It returns content regardless of what your code evaluates to, because code inside it is sensitive to where it is located in the document, so if you could access what is returned inside the context { } block outside of it (without placing some content somewhere), it would always be the same value as it would not have a fixed location in the document (which only content can have), but that’s not what you want (code outside of context { } is evaluated early, before document layout, so it would have no way to be aware of state updates, current location and other context-aware information). So, instead of:

#let value = context { value-state.get() + 5 }

// Error: trying to access context-aware code
// from non-context-aware code
#let sum = value + 10
The sum is #sum

Instead indicate that all of your relevant code is context-aware and needs to be placed in the document to work, as such:

#context {
   // Ok: All code depending on the context is
   // encapsulated in a context block
   let value = value-state.get() + 5
   let sum = value + 10
   [The sum is #sum]
}

Note that if you have a function which depends on the context to return a value that isn’t content, you can simply have it not return context to allow users to access what it returns, as long as they themselves use context:

// Don't:
#let get-height() = context here().pos().y
// Error: can't get contextual value from non-contextual code
#let sum = get-height() + 5pt 
#sum

// Do instead:
#let get-height() = here().pos().y
// Error: here() requires context, so this call fails
#let sum = get-height() + 5pt 

// Ok: wrapping in context, we can access what get-height()
// would return at this location
#context {
  let sum = get-height() + 5pt
  sum
}

For more information (and for further help on this matter), please check out this thread: Why is the value I receive from context always content? - #2 by laurmaedje

1 Like