dhaga.docs
Using DhagaPages

Formulas

Compute a property from other properties with Notion-style formulas: variables, lists, dates, text, regular expressions, styled output, and a function reference.

A formula property computes its value from the row's other properties: the days left until a due date, a label that turns red when something is overdue, or a count of the contacts a row links to. Pages formulas use Notion's Formulas 2.0 language, so a formula you wrote in Notion works here, and Obsidian Bases function names work as alternatives. Formulas are worked out by Dhaga, never by running code you paste in.

Write a formula

Add a Formula property to a database and open it. Type the formula; its result for the first few rows shows as you type, and a mistake shows an error that points at the problem. A formula can be up to 10,000 characters long.

The formula editor with a formula, its live result and the function list

The formula editor with a formula, its live result and the function list

Refer to another property with prop("Name"). A few complete formulas:

// Days until the due date
dateBetween(prop("Due"), today(), "days")

// A label that changes with the status
if(prop("Status") == "Done", "Done", "Open")

// Name a value once, then use it
let(left, dateBetween(prop("Due"), today(), "days"),
  ifs(left < 0, style("Overdue", "b", "red"),
      left == 0, "Due today",
      format(left) + " days left"))

// How many scores in a list are above 7
prop("Scores").filter(current > 7).length()

Can't remember a function? Describe what you want in plain English and the formula writer drafts it for you. It uses AI credits; writing formulas yourself does not.

Operators

OperatorMeaning
+ - * / % ^Add, subtract, multiply, divide, remainder, power. + also joins text
== !=Equal, not equal
> >= < <=Comparisons on numbers, dates and text
and or notLogic. &&, `
? :A short if: prop("Done") ? "Yes" : "No"

Function reference

Logic

FunctionExampleResult
ifif(prop("Score") > 7, "High", "Low")One of two values
ifsifs(prop("Score") > 7, "High", prop("Score") > 4, "Mid", "Low")The first value whose condition is true
emptyempty(prop("Email"))true when the value is blank
and, or, notand(true, false)false: the same as the operators
equal, unequalequal(1, 1)true: the same as == and !=
letlet(x, 2, x * x)4: names a value for the rest of the formula
letslets(a, 1, b, 2, a + b)3: names several values

Numbers

FunctionExampleResult
round, ceil, floorround(3.14159, 2)3.14
abs, signabs(-4)4
sqrt, cbrt, pow, exppow(2, 10)1024
ln, log10, log2log10(1000)3
min, max, sum, mean, mediansum(1, 2, 3)6
modmod(10, 3)1
toNumbertoNumber("42")42
toFixedtoFixed(3.1, 2)"3.10" as text, with exactly that many decimals
pi, epi()3.14159...
add, subtract, multiply, divideadd(2, 3)5: the same as + - * /
formatformat(42)"42" as text. Given a date it also takes a pattern, like formatDate

Text

FunctionExampleResult
lengthlength("Atlas")5
containscontains(prop("Title"), "Atlas")true or false. Works on lists too, and includes is another name for it
containsAll, containsAnycontainsAny(prop("Title"), "Atlas", "Beta")true when the text or list holds every, or at least one, of the values
startsWith, endsWithstartsWith(prop("Title"), "Q3")true or false
trim, titletitle("north wind")"North Wind"
escapeHTMLescapeHTML("a & b")The text with &, angle brackets and quotes made safe for HTML
substring, slicesubstring("Northwind", 0, 5)"North" (slice also takes negative positions)
lower, upperupper("atlas")"ATLAS"
repeatrepeat("★", prop("Rating"))"★★★" for a rating of 3
padStart, padEndpadStart("7", 3, "0")"007"
splitsplit("a,b,c", ",")A list of three items
linklink("Docs", "https://example.com")A clickable link
style, unstylestyle("Overdue", "b", "red")Bold red text

Regular expressions

FunctionExampleResult
testtest(prop("Email"), "@example\\.com$")true when the pattern matches
matchmatch("Order 1234", "[0-9]+")A list of matches: ["1234"]
replacereplace("2026-10-12", "-", "/")Replaces the first match
replaceAllreplaceAll("2026-10-12", "-", "/")"2026/10/12"

Dates

FunctionExampleResult
now, todaytoday()Today's date (now() includes the time)
dateAdd, dateSubtractdateAdd(prop("Start"), 2, "weeks")A date two weeks later
dateBetweendateBetween(prop("Due"), today(), "days")Days from today to the due date
dateRange, dateStart, dateEnddateEnd(prop("Sprint"))The end of a date range
formatDateformatDate(prop("Due"), "D MMMM YYYY")"6 November 2026"
parseDateparseDate("2026-11-06")A date
year, month, week, date, day, hour, minuteyear(today())2026. month is 1 to 12, week the ISO week, date the day of the month and day the day of the week (0 is Sunday)
durationtoday() + duration("1 week")A length of time to add to or subtract from a date
timestamp, fromTimestamptimestamp(prop("Due"))Milliseconds since 1970

Units for dateAdd, dateSubtract and dateBetween are years, quarters, months, weeks, days, hours, minutes, seconds and milliseconds. Adding a month to 31 January gives the last day of February.

Lists

Lists come from multi-selects, relations, rollups, people properties and split. Inside map, filter and the other list functions, current is the item being looked at and index is its position.

FunctionExampleResult
at, first, lastfirst(prop("Tags"))The first item
slice, concatslice(prop("Tags"), 0, 2)The first two items
sort, reverse, unique, flatunique(prop("Tags"))The list without repeats
joinjoin(prop("Tags"), ", ")One piece of text
listlist(prop("Tags"))The value as a list: a single value becomes a one-item list
includesincludes(prop("Tags"), "urgent")true or false
find, findIndexfind(prop("Scores"), current > 7)The first item that matches
filterfilter(prop("Scores"), current > 7)Every item that matches
mapmap(prop("Scores"), current * 10)Each item changed
reducereduce(prop("Scores"), acc + current, 0)One value built from every item; the last argument is the starting value
some, everysome(prop("Tags"), current == "urgent")true or false
lengthlength(prop("Contacts"))How many items

Most functions can also be written as a method on their first argument: prop("Tags").join(", ") is the same as join(prop("Tags"), ", ").

Rows and people

FunctionExampleResult
idid()The row's unique id
name, emailname(prop("Owner"))A person's name or email address

Obsidian Bases names

If you write formulas in Obsidian Bases, its function names work too and mean the same thing as the Notion function they correspond to: average for mean, isEmpty for empty, number for toNumber, matches for test, count for length, and acc and value for accumulator and current. A few functions exist only for Bases formulas, mostly in base views that read from a search: hasTag, hasLink, hasProperty, inFolder, time and relative. A base file imported from an Obsidian vault keeps its formulas.

Limits

A view works out formulas for up to 5,000 rows at a time. Past that, the view shows an error saying the database is too large to compute there, instead of quietly showing partial results. Filter the view to bring it under the limit.

On this page