Obsidian Life Planner Setup

Habits, Goals, Journals, Tasks, Reflection, & Many more.

In this article, I’m going to guide you through everything that you need or require in order to set up the Obsidian Demo Vault that was shown on this YouTube video.

Plugins Required

  • Journals Plugin: We’ll be using Journals Plugin in order to create daily notes, weekly notes, monthly notes and making it easier to create those notes.
  • DataView Plugin: We’ll be using DataView Plugin in order to do queries in our vault.
  • Templater Plugin: We’ll be using Templater Plugin in to add Templater functions such as automatically moving nodes, automatically adding dates, automatically adding titles etc.
  • Pixel Banner Plugin: We’ll be using Pixel banner Plugin in order to add a banner to our notes.
  • MetaBind Plugin: We’ll be using MetaBind Plugin in to create custom buttons to do different actions.
  • Tasks Plugin: We’ll be using Tasks Plugin in to better manage our tasks in Obsidian.

Custom CSS

If you watched my video, then I have a completely different appearance for the theme. This is possible with the help of the following CSS files. You will be able to get all of the codes or links to all of these CSS files at the end of this article. Refer there.

  • MCL multicolumn CSS. This CSS makes it possible to create multiple columns in Obsidian.
  • Daily note themes: This CSS keeps all of the titles centered.
  • Clean Embed CSS: It makes the embed in your notes more natural.
  • Properties on Hover: This CSS hides your Obsidian properties by default but when you hover over them, then they will be visible again.

Journal Plugin Setup

Date format for:

  • Daily Notes: YYYY/MMMM/YYYY-MM-DD
  • Weekly Notes: YYYY/MMMM/YYYY-[W]ww
  • Monthly Notes: YYYY/MMMM/YYYY-MMMM

Daily Note Template

This is the snippet that will create a daily note with the link to previous note, next note, this week’s note as well as this month note.

  • Linked daily Notes
# Daily Note
### Tuesday, January 01, 0002

###### << [[0001-12-31|Yesterday]] | [[0002-01-02|Tomorrow]] >> 📅 [[0002-January|Monthly Note]] | 📆 [[0002-W01|Weekly Note]]

---
![[0002-January#Monthly Goals |Monthly Note]]
  • Get Monthly Goals Embed
![[0002-January#Monthly Goals |Monthly Note]]

Weekly Note template

  • Linked weekly note This snippet will link your weekly note with other weekly notes, monthly notes as well as all of the daily notes in that particular week.
# Weekly Note
### 0002-W01
###### ⬅️ [[0001-W52|Last Week]] | 📅 [[0002-January|Monthly Note]] | [[0002-W02|Next Week]] ➡️  [[0001-12-30|S]] | [[0001-12-31|M]] | [[0002-01-01|T]] | [[0002-01-02|W]] | [[0002-01-03|T]] | [[0002-01-04|F]] | [[0002-01-05|S]]
  • Get daily reflections This DataView code will get the summary from all of your daily notes within that particular week.
TABLE WITHOUT ID
file.link as "Date", summary as "Summary"
FROM #daily
WHERE file.name >= "0001-12-30" AND file.name <= "0002-01-05"
SORT file.name ASC

Monthly Note Template

  • Linked Monthly Notes
# Monthly Note
### 0002-January
###### ⬅️ [[0001-December]] | [[0002-February]] ➡️ [[0002-W01|Week 1]] | [[0002-W02|Week 2]] | [[0002-W03|Week 3]] | [[0002-W04|Week 4]] | [[0002-W05|Week 5]]
  • Creating Monthly Goals This is a DataView.js code in order to create monthly goals and the goals will be tracked by using the daily nodes metadata. You can add a metadata in the daily nodes and that will be used in order to track the progress of these goals.
// Configuration for mesuring daily goals using Frontmatter or inline Metadata from Daily Notes
const goals = [
    {
        targetValue: 250,
        metricName: "Focusmate",
        metricLabel: "Focusmate sessions"
    },
    {
        targetValue: 1500,
        metricName: "Reading_time",
        metricLabel: "Minutes of Reading"
    },
    {
        targetValue: 1000,
        metricName: "Money",
        metricLabel: "$$$"
    }
    // Add more goals here as needed
];

const dateConfig = {
    startDate: "0002-01-01",
    endDate: "0002-01-31"
    //getting start date and end date from Montly note using moment.js and templater
};

// Helper Functions
function calculateTotal(dailyNotes, metricName) {
    let total = 0;
    for (let daily of dailyNotes) {
        // Check both frontmatter and inline fields
        const value = daily[metricName] || daily.file.frontmatter[metricName] || 0;
        total += typeof value === 'number' ? value : 0;
    }
    return total;
}

function getProgressMessage(total, target, label, progress) {
    if (progress >= 100) {
        return `You've reached your goal of ${target} ${label}! Current progress: ${total} ${label}`;
    }
    return `Current progress: ${total} out of ${target} ${label}`;
}

function createProgressBar(progress, message) {
    return `<div style="flex: 1; min-width: 200px; padding: 0 10px;">
        <p style="margin: 5px 0; font-size: 0.9em;">${message}</p>
        <progress value="${Math.min(progress, 100)}" max="100" style="width: 100%; height: 20px;"></progress>
        <div style="font-size: 0.9em; margin-top: 5px;">${Math.round(progress)}%</div>
    </div>`;
}

// Get all daily notes within date range
const dailyNotes = dv.pages("#daily")
    .filter(p => p.file.cday >= dv.date(dateConfig.startDate) && p.file.cday <= dv.date(dateConfig.endDate));

// Create HTML for all goals
let allGoalsHtml = '<div style="display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; align-items: start; margin: 20px 0;">';

for (const goal of goals) {
    // Filter notes for this specific metric
    const relevantNotes = dailyNotes.filter(p => p[goal.metricName] !== undefined || p.file.frontmatter[goal.metricName] !== undefined);
    
    // Calculate progress
    const total = calculateTotal(relevantNotes, goal.metricName);
    const progress = (total / goal.targetValue) * 100;
    
    // Create message and progress bar
    const message = getProgressMessage(total, goal.targetValue, goal.metricLabel, progress);
    allGoalsHtml += createProgressBar(progress, message);
}

allGoalsHtml += '</div>';

// Render all progress bars
dv.span(allGoalsHtml);
  • Monthly reflection This DataView code will pull all the summary data from your week notes and present it in a monthly note.
TABLE WITHOUT ID
file.link as "Week",
summary as "Summary"
FROM #week
WHERE file.name >= "0002-W01"
  AND file.name <= "0002-W05"
SORT file.name ASC

Project Template File

# # trading-in-the-zone-book-summary-2
Why:: 
Target::
Deadline:: 


## Tasks

Project Dashboard

This project dashboard will calculate the progress of your projects based on the number of tasks you have completed in that project against the total tasks.

TABLE WITHOUT ID file.link as "Project", 
  Why as "🪄Why", 
  Target as "🎯Target",
  Deadline as "Deadline",
  "<progress value='" + Progress + "' max='100'></progress> " + round(Progress) + "%" AS "Progress"
FROM #project and -#completed
FLATTEN (length(filter(file.tasks.completed, (t) => t = true))/length(file.tasks.total)*100) as "Progress"

Dashboard Code using Multi-column

---
`BUTTON[daily-note, weekly-note, monthly-note]` 🪴`BUTTON[light-mode, dark-mode]` 🪴`BUTTON[view-tasks]`

> [!multi-column]
> 
> ```dataviewjs
> let goals = dv.pages('"002 Journal/ Goals"');
> dv.table(["Goal", "Deadline", "Progress"],
>     goals.map(goal => [
>         `<span style="font-size: 1.2em;">${goal.file.link}</span>`,
>         goal.Deadline,
>         `<progress value="${goal.progress}" max="${goal.target}"></progress><br>${Math.round((goal.progress / goal.target) * 100)}% completed`
>     ])
> );
> dv.container.classList.add("cards-align-top");
> ```
> 
> ```dataviewjs
> const pages = dv.pages('"002 Journal"')
>   .where((p) => "Writing" in p || "Workout" in p || "Reading" in p)
>   .sort((p) => p.file.day, "desc")
>   .map((p) =>
>     Object.create({
>       link: p.file.link,
>       day: p.file.day,
>       Writing: p.Writing,
>       Workout: p.Workout,
>       Reading: p.Reading,
>     })
>   );
> function getStreak(validate) {
>   let count = 0;
>   for (const note of pages) {
>     if (validate(note)) count++;
>     else break;
>   }
>   return count;
> }
> function getRecord(validate) {
>   let record = 0;
>   let count = 0;
>   for (const note of pages) {
>     if (validate(note)) {
>       count++;
>       record = Math.max(record, count);
>     } else {
>       count = 0;
>     }
>   }
>   return record;
> }
> const done = "✅";
> const skip = "🟥";
> const fileRows = pages
>   .filter((p) => p.day >= moment().subtract(1, "w"))
>   .sort((p) => p.day)
>   .map((note) => [
>     note.link,
>     note.Writing ? done : skip,
>     note.Workout ? done : skip,
>     note.Reading ? done : skip,
>   ]);
> const writing = [
>   getStreak((note) => note.Writing),
>   getRecord((note) => note.Writing),
> ];
> const workout = [
>   getStreak((note) => note.Workout),
>   getRecord((note) => note.Workout),
> ];
> const reading = [
>   getStreak((note) => note.Reading),
>   getRecord((note) => note.Reading),
> ];
> dv.table(
>   ["Habits", "✍🏼", "💪🏼", "📖"],
>   [
>     ...fileRows,
>     ["‎"],
>     ["**Streak**", writing[0], workout[0], reading[0]],
>     ["**Record**", writing[1], workout[1], reading[1]],
>   ]
> );
> ```


---
- #### Projects #mcl/list-card 
    - [[College Research Project]]
    - [[VoiceInk app]]
    - [[project 3]]
- #### Learning & System
    - [[00 Home|Learning Goal 1]]
    - [[00 Home|Initiative 1]]
    - [[00 Home|Initiative 2]]
- #### Personal
    - **[[Goal Dashboard|Goals]]**
    - **[[Tasks Calendar|Calendar]]**
    - [[Project Dashboard]]

---
> [!multi-column]
> > [!summary] Recently Created
>>  ```dataview
> list
> from ""
> Sort file.ctime DESC
> limit 7
>
>> [!Todo] Recently Updated
>>  ```dataview
>> 	list
>> 	from ""
>> 	Sort file.mtime DESC
>> 	limit 7
>>```
---
---
Meta-bind buttons configured below. Don't remove them.
```meta-bind-button
label: Daily Note
icon: ""
hidden: true
class: ""
tooltip: ""
id: "daily-note"
style: primary
actions:
  - type: command
    command: journals:journal:calendar:open-day
style: destructive
label: Light Mode
id: light-mode
hidden: true
actions:
  - type: command
    command: theme:use-light
label: View Tasks
icon: ""
hidden: true
class: ""
tooltip: Open task Dashboard
id: view-tasks
style: primary
actions:
  - type: open
    link: "[[Task Dashboard]]"
    newTab: true
style: primary
label: Dark Mode
id: dark-mode
hidden: true
actions:
  - type: command
    command: theme:use-dark
label: Weekly Note
icon: ""
hidden: true
class: ""
tooltip: ""
id: weekly-note
style: destructive
actions:
  - type: command
    command: journals:journal:calendar:open-week
label: Monthly Note
icon: ""
hidden: true
class: ""
tooltip: Open Monthly Note
id: monthly-note
style: primary
actions: []


Habit Tracker using Checkbox and Streaks Measurement

const pages = dv.pages('"002 Journal"')
  .where((p) => "Writing" in p || "Workout" in p || "Reading" in p)
  .sort((p) => p.file.day, "desc")
  .map((p) =>
    Object.create({
      link: p.file.link,
      day: p.file.day,
      Writing: p.Writing,
      Workout: p.Workout,
      Reading: p.Reading,
    })
  );

function getStreak(validate) {
  let count = 0;
  for (const note of pages) {
    if (validate(note)) count++;
    else break;
  }
  return count;
}

function getRecord(validate) {
  let record = 0;
  let count = 0;
  for (const note of pages) {
    if (validate(note)) {
      count++;
      record = Math.max(record, count);
    } else {
      count = 0;
    }
  }
  return record;
}

const done = "✅";
const skip = "🟥";
const fileRows = pages
  .filter((p) => p.day >= moment().subtract(1, "w"))
  .sort((p) => p.day)
  .map((note) => [
    note.link,
    note.Writing ? done : skip,
    note.Workout ? done : skip,
    note.Reading ? done : skip,
  ]);

const writing = [
  getStreak((note) => note.Writing),
  getRecord((note) => note.Writing),
];

const workout = [
  getStreak((note) => note.Workout),
  getRecord((note) => note.Workout),
];

const reading = [
  getStreak((note) => note.Reading),
  getRecord((note) => note.Reading),
];

dv.table(
  ["Habits", "✍🏼", "💪🏼", "📖"],
  [
    ...fileRows,
    ["‎"],
    ["**Streak**", writing[0], workout[0], reading[0]],
    ["**Record**", writing[1], workout[1], reading[1]],
  ]
);

Important CSS Files

Note: If you are confused during the setup, you can watch the YouTube video or you can also get the demo vault and try it directly within the demo vault and copy the code from there instead of doing it all yourself. å