Ashok Gautham Jadatharan

Habit tracking in Logseq

I had to move away from Obsidian to Logseq because I learnt I couldn't keep work notes on it without paying an annual subscription fee.(source) Obsidian was the first tool I actually stuck with for a while - so it was a bit of a bummer. But Logseq seems perfectly reasonable as a replacement. While the UX still lacks a little polish, it is just as powerful and has better outlining support.

Goal: Old obsidian setup

I used to add YAML metadata to my daily journals using templates, MetaEdit and Dataview. My dataview query was as follows

TABLE 
    file.name AS "File", 
    choice(wake_up_early, "✔", "❌") AS "Wake up Early",
    choice(plan_day, "✔", "❌") as "Plan Day",
    choice(exercise, "✔", "❌") as "Exercise",
    choice(productive, "✔", "❌") as "Productive Day"
FROM "Journal"
WHERE file.name != "Tracker"
SORT file.name DESC

Moving to Logseq

Step 1: Create a property list in your daily journal page

- ## Trackers  
  -  type:: tracker
     wake-up-early:: true
     exercise:: false
     day-plan:: true
     productive:: true

Do this for journal pages. If you please you might also add it to a journal template.(learn how)

Step 2: Create the tracker query

Create a page called Tracker, and type < query into it. It should give you a drop-down with the word query that you can select to create an advanced query. Between the auto-inserted #+BEGIN_QUERY and #+END_QUERY, paste the following

{
 :title [:b "HabitTracker"]

 :query [
  :find
  (pull ?b [:db/id :block/properties {:block/page [:block/original-name]} :block/content])
  :where
  [?b :block/page ?p]
  [?p :page/journal? true]
  [?b :block/properties ?props]
  [(get ?props :type) ?type]
  [(= "tracker" ?type)]
 ]

 :result-transform
 (fn [rows]
   (map
    (fn [row]
      (-> 
          (assoc row :block/content (get-in row [:block/page :block/original-name]))
          (update-in [:block/properties :exercise] (fn [b] (if b "✔️" "❌")))
          (update-in [:block/properties :wake-up-early] (fn [b] (if b "✔️" "❌")))
          (update-in [:block/properties :day-plan] (fn [b] (if b "✔️" "❌")))
          (update-in [:block/properties :productive] (fn [b] (if b "✔️" "❌")))))
    rows))}

Let us break this query down into small parts.

This would give you an table that looks like screenshot.

#logseq #self-development