Phrase of the Day

:flower_playing_cards: Quote of the Day Card That Actually Changes Once a Day (Not Every Time You Blink)

Hi folks! I wanted to share a little build I just wrapped that might be useful if you’ve ever tried to show a “Quote of the Day” in Coda… only to find that RandomItem() has a mind of its own and changes every time you breathe.

I needed a card that updates once a day, shows exactly one quote, and cycles through a list cleanly. No chaos, no reload roulette.

:sparkles: Use Case

I’m building a mobile-first doc for myself, where I can:

  • See my daily to-do’s
  • Track recurring tasks (weekly, monthly, etc.)
  • Write notes or prayers
  • Get a little inspiration each day :dizzy:

The goal was to show one motivational quote per day, in a card view, that cycles through my curated list (currently 32 quotes).


:repeat_button: The Problem with RandomItem()

RandomItem() works great, but it updates anytime I do something within the doc (updates continuously). I wanted one phrase per day.


:white_check_mark: The Solution: A Cycling Formula Using Today()

I created a formula that returns the Nth quote for each day since a fixed date (e.g. Jan 1, 2020), looping through all available quotes.

Each quote has an ID column (not RowID — more on that below). Here’s the formula for the “Phrase of the Day”:

Frases.Filter(
  ID = Floor(
    Today().DateTimeValue() - Date(2020, 1, 1).DateTimeValue()
    - Floor((Today().DateTimeValue() - Date(2020, 1, 1).DateTimeValue()) / Frases.Count()) * Frases.Count()
  ) + 1
).First()

Yes, it’s a bit gnarly, but it’s just simulating MOD without %, which Coda doesn’t support. It gives you a stable, looping index from 1 to Frases.Count().


:tear_off_calendar: I Also Added Yesterday + Tomorrow

To let me sanity-check the cycle, I added:

// Frase de Ayer
Frases.Filter(
  ID = Floor(
    (Today().DateTimeValue() - Date(2020, 1, 1).DateTimeValue() - 1)
    - Floor((Today().DateTimeValue() - Date(2020, 1, 1).DateTimeValue() - 1) / Frases.Count()) * Frases.Count()
  ) + 1
).First()
// Frase de Mañana
Frases.Filter(
  ID = Floor(
    (Today().DateTimeValue() - Date(2020, 1, 1).DateTimeValue() + 1)
    - Floor((Today().DateTimeValue() - Date(2020, 1, 1).DateTimeValue() + 1) / Frases.Count()) * Frases.Count()
  ) + 1
).First()

:abacus: Why You Shouldn’t Use RowID

If you delete a row, RowID skips ahead and breaks the cycle. Instead, I created a new ID column with this formula:

Frases.Filter(CurrentValue.Created() <= thisRow.Created()).Count()

That gives you a stable, sequential number that tracks the order of creation, no gaps.

Hope this helps someone build a more grounded inspiration feed in their doc! Happy to share a sample if anyone’s curious.

Lau

3 Likes

hi @Laura_Clark1 , thanks for sharing!

Yes, it’s a bit gnarly, but it’s just simulating MOD without % , which Coda doesn’t support. It gives you a stable, looping index from 1 to Frases.Count() .

Did you have a look at Remainder()

have a wonderful day / evening, cheers, christiaan

3 Likes

Isn’t this the same as using thisTable.Find(thisRow)?
That formula will give you the line number, despite the rowId.

1 Like