<aside>
💡 Note: This is very advanced formula stuff and a little experimental!
</aside>
👋 Intro
- A common formulas use-case is: How do we traverse relations with unknown depth?
- We may want to generate page breadcrumbs, identify ancestors or descendants, or do aggregations over dependencies.
- We can accomplish this using iterative or recursive solutions!
⚠️ Warnings
- Depth limit: It’s important to note there are limitations to calling other formulas and rollups recursively — we can only traverse up to a max of 15 formulas deep! As you go beyond this limit, you may run into issues.
- Performance: The deeper you go and the more properties and pages you fetch, the slower your setup will be! Simpler formulas with less depth are typically faster.
- Type outputs: It’s important to note final type outputs! If a formula is
Unknown
or List<Unknown>
— filters will operate as if type Text
! Learn more about Types and how they relate to properties.
- Unknown happens when the formula returns multiple types, e.g. one branch will return a
Boolean
, and another returns a Text
. Or one branch returns a Block
but another returns a List<Block>
. This has a recursive effect, meaning formulas that call it will also become Unknown
.
Recursive version
About
Recursion involves referencing the same formula within itself! It can be use for deep computational needs, and avoid redundant iteration like above.
Notes
- Writing: To write recursive formulas, you must type the
prop()
manually, since you won’t find it in the properties menu (we hide it cause it’s super advanced and 99% of people won’t use it!).
- Cycle: If you refer to the same formula and operate on the same page within a formula, then you will hit a Cycle warning. For example, if you have a prop Formula, a simple example is it being
prop("Formula")
.
- Depth: If we’re not worried about hitting a recursive depth limit (which is most use-cases), we can use recursion instead. You can only see up to 15 nested formulas and rollups.
- Performance: This is typically more performant than the iterative version above due to how we often cache previous formula computations.
Get deepest relation
- This formula is called
"Last_Recursive"
and returns type List<Page>
.
if(
empty(prop("Next")),
prop("Next"),
let(
nextLast,
prop("Next").at(0).prop("Last_Recursive"),
if(
empty(nextLast),
prop("Next").at(0),
nextLast
)
)
)