Track every assignment in Obsidian.
One note per assignment and one Base give you a list of what’s due this week, what’s overdue and how many days until each exam. About 20 minutes to set up, no plugins.
What you’ll build
A planner only helps if you look at it. This setup puts the week on one Home page you can check in a minute:
- One note per assignment, with the class, due date, status and how much it counts.
- One Base, Obsidian’s built-in database view, with two lists: due this week, and overdue.
- Exam countdowns, and class pages that list their own assignments automatically.
You need Obsidian 1.9 or later with the Bases core plugin turned on (Settings → Core plugins). Everything below was tested in Obsidian 1.14 with no community plugins.
Step 1: One note per assignment
Make a folder called Assignments. Each assignment gets its own note, with its properties at the top:
---
type: assignment
class: "[[Biology 101]]"
kind: Lab report
due: 2026-10-16
status: In progress
weight: 10
---classlinks to the class note. Type[[and pick it from the list; step 4 depends on this link.- Write dates as YYYY-MM-DD. Set the property type to Date (click the icon beside the name) and you get a date picker.
- Keep the statuses short: Not started, In progress, Submitted, Graded.
weightis the percent of the final grade, from the syllabus. It shows which work deserves your best hours.
Save the block as Templates/Assignment.md and turn on the Templates core plugin, so each new assignment takes seconds.
Step 2: Due this week, and overdue
A Base is a few lines of YAML. To try one, type ```base on its own line in any note, paste the code, and finish with ```. To reuse it on other pages, save the same code as a file called Assignments.base in your vault.
filters:
and:
- type == "assignment"
- '!file.inFolder("Templates")'
formulas:
when: if(status == "Submitted" || status == "Graded", "✅ Turned in", if(!due, "No date", if(date(due) < today(), "🔴 Overdue", if(date(due) == today(), "⏰ Today", if((date(due) - today()).days.round(0) <= 2, "🔥 Soon", "Later")))))
days_left: if(due, (date(due) - today()).days.round(0), "")
properties:
file.name:
displayName: Assignment
note.class:
displayName: Class
formula.when:
displayName: When
formula.days_left:
displayName: Days left
views:
- type: table
name: Due this week
filters:
and:
- status != "Submitted"
- status != "Graded"
- if(due, (date(due) - today()).days <= 7, false)
order:
- file.name
- class
- due
- formula.when
- weight
sort:
- property: due
direction: ASC
- type: table
name: Overdue
filters:
and:
- status != "Submitted"
- status != "Graded"
- if(due, date(due) < today(), false)
order:
- file.name
- class
- due
- formula.days_left
sort:
- property: due
direction: ASC- Due this week lists unfinished work due in the next seven days. Overdue work counts too (its days left are below zero), so nothing slips off the bottom.
- The
whenformula labels each row: Overdue, Today, Soon (two days or less) or Later. Eachif()handles one case and passes the rest to the next. .round(0)keeps day counts whole. Across a daylight-saving change, a seven-day gap can come out as 6.96 days.'!file.inFolder("Templates")'keeps your template out of the lists. Keep the single quotes: in YAML, a value that starts with!means something else.
Step 3: Exam countdowns
Give each exam a note with type: exam, its class, an exam_on date and the topics. This Base counts down to each one:
filters:
and:
- type == "exam"
- '!file.inFolder("Templates")'
formulas:
countdown: if(!exam_on, "", if(date(exam_on) < today(), "Done", if(date(exam_on) == today(), "⏰ Today", "in " + (date(exam_on) - today()).days.round(0).toString() + " days")))
properties:
file.name:
displayName: Exam
note.exam_on:
displayName: Exam on
formula.countdown:
displayName: Countdown
views:
- type: table
name: Upcoming
filters:
and:
- if(exam_on, date(exam_on) >= today(), false)
order:
- file.name
- class
- exam_on
- formula.countdown
- topics
sort:
- property: exam_on
direction: ASCThe countdown formula joins text with +, and .toString() turns the number of days into text, so a row reads “in 9 days”. Seeing that number every day makes it much harder for an exam to sneak up on you.
Step 4: Class pages that list their own work
Add one more view to Assignments.base, under views::
- type: table
name: This class
filters:
and:
- file.hasLink(this.file)
order:
- file.name
- due
- formula.when
- weight
sort:
- property: due
direction: ASCThen give each class a note that embeds it:
---
type: class
code: BIO 101
schedule: Mon and Wed, 10:00
instructor: Dr. Okafor
---
## Assignments
![[Assignments.base#This class]]Inside an embed, this.file is the note doing the embedding, and file.hasLink(this.file) keeps only the assignments whose properties link to it. So Biology 101’s page lists only Biology 101’s work. Put the embed in your class template once and every class page fills itself in. The same trick works for exams and lecture notes.
Step 5: One Home page for the week
Make a note called Home and embed the views by name:
## Due this week
![[Assignments.base#Due this week]]
## Overdue
![[Assignments.base#Overdue]]
## Exams coming up
![[Exams.base#Upcoming]]The part after # must match the view’s name exactly. Pin Home in a tab (right-click the tab, then Pin) and check it once a day.
A rhythm that keeps the list true
A list is only as good as its last update. Three small habits keep it honest:
- When you get an assignment, make its note right away, with the due date from the syllabus or course page.
- When you hand it in, set its status to Submitted. It drops off both lists.
- Once a week, look ten days ahead and block time for the heavy items.
For exams, write a few questions at the end of each lecture note and answer them from memory before the test. Testing yourself is one of the most researched study methods there is.
Mistakes that cost us time
- Your template shows up as homework. The
!file.inFolder("Templates")filter fixes it. - Dates that won’t sort. “Oct 16” is text. Use 2026-10-16, or the Date property type.
- A class page that stays empty. The
classlink must match the class note’s name; pick it from the[[suggestions. - A view that won’t embed. The name after
#must match exactly:Due this week, notDue This Week. - Finished work hanging around. Set the status the moment you hand it in.
Keep going.
How to Build a Simple CRM in Obsidian (No Plugins)
Track clients, follow-ups and invoices with one note per client and a single Base. Copy-paste code, no plugins.
Read the guide Bases recipesObsidian Bases Examples: 10 Copy-Paste Recipes
Ten tested recipes: due this week, days since, late invoices with totals, weighted pipeline, renewals, per-note embeds and the gotchas.
Read the guide Small office ITSmall Office IT Documentation in Obsidian: What to Record
What a small office should write down about its IT, what never to store, and a simple setup in Obsidian.
Read the guide Building with AIA Spec Template for AI Coding Tools (Claude Code, Cursor)
A one-page spec template for Claude Code, Cursor and other AI coding tools, a plan-first prompt, and where Obsidian fits.
Read the guide Daily planningA Calm Daily Planner in Obsidian: Tasks by Energy and Time
A brain-dump inbox, tasks sorted by energy and minutes, up to three focus tasks, and bills two weeks ahead, on one Today page.
Read the guide Game mastersObsidian for Game Masters: Run a Tabletop RPG Campaign
Session prep in 30 minutes, secrets and clues until they’re revealed, NPCs listed on their places, and faction clocks. Any system.
Read the guide Real estate agentsReal Estate CRM in Obsidian: Follow-ups and Contract Deadlines
Follow-ups due, past clients to check on, and every contract deadline in the next seven days, in a private vault. No plugins.
Read the guide