Obsidian

Documentation Tool

Obsidian

Overview

Obsidian is a powerful personal knowledge base tool. Through Markdown-based note-taking and graph visualization, it visualizes connections between ideas and notes, functioning as an innovative note management system that serves as a "second brain."

Details

Obsidian was developed in 2020 by Shida Li (Licat) and Erica Xu (Silver), revolutionizing digital note management. Bidirectional linking allows natural relationship building between notes. Graph view enables visual understanding of knowledge connections and discovery of new insights. Built on Markdown and stored as local files, it guarantees data ownership and permanence. A rich community plugin ecosystem enables infinite customization. It supports knowledge management methodologies like Zettelkasten, GTD, and PARA Method. Canvas functionality enables visual mapping of ideas and presentation creation. Theme system allows complete customization of appearance and functionality. As of 2025, it is beloved by researchers, writers, engineers, students, and many other users, becoming the new standard for personal knowledge management. Cloud services like Obsidian Sync and Obsidian Publish enable multi-device synchronization and knowledge sharing. Plugin development API allows custom feature development in TypeScript, enabling advanced workflow automation.

Advantages and Disadvantages

Advantages

  • Bidirectional Links: Natural relationship building between notes and knowledge network formation
  • Graph View: Visual understanding of knowledge connections and structure for new discoveries
  • Local Files: Data ownership guarantee and vendor lock-in avoidance
  • Rich Plugins: Diverse functionality extensions and customization by community
  • Full Markdown Support: Standard notation writing and future-proofing
  • Offline Operation: Complete functionality without internet connection
  • Free Core Features: Basic functionality is free with commercial use allowed

Disadvantages

  • Learning Curve: Time required to master bidirectional linking and graph thinking
  • Desktop-centric: Mobile app has functionality limitations and usability challenges
  • Sync/Share Costs: Obsidian Sync is a paid service ($8/month)
  • Plugin Dependency: Advanced features require understanding and management of plugins
  • Performance: Graph display may become heavy with large amounts of notes (10,000+)
  • Collaboration: Real-time collaborative editing functionality is limited

Key Links

Usage Examples

Basic Note Creation

# Project Plan

## Overview
This is a plan document for a new project.

## Related Notes
- [[Requirements Definition]]
- [[Schedule]]
- [[Team Members]]

## Tasks
- [ ] Organize requirements
- [x] Create project overview
- [ ] Develop schedule

## Metadata
- Created: 2025-06-20
- Assignee: [[John Doe]]
- Status: #in-progress

## Links and References
We plan to adopt [[Agile]] methodology from [[Project Management Methods]].
Will also reference past [[Success Cases]].

#project #planning #2025

Utilizing Bidirectional Links

# Machine Learning

Machine learning is a field of [[Artificial Intelligence]] that uses [[Algorithms]] to learn [[Patterns]] from data.

## Main Methods
- [[Supervised Learning]]
  - [[Linear Regression]]
  - [[Decision Trees]]
  - [[Neural Networks]]
- [[Unsupervised Learning]]
  - [[Clustering]]
  - [[Principal Component Analysis]]
- [[Reinforcement Learning]]
  - [[Q-Learning]]
  - [[Policy Gradient Methods]]

## Application Areas
[[Machine Learning]] is utilized in the following fields:
- [[Natural Language Processing]] - [[Document Classification]], [[Sentiment Analysis]]
- [[Computer Vision]] - [[Image Recognition]], [[Object Detection]]
- [[Recommendation Systems]] - [[Collaborative Filtering]]

## Related Concepts
Understanding machine learning requires knowledge of [[Statistics]] and [[Mathematics]].
Particularly [[Linear Algebra]], [[Calculus]], and [[Probability Theory]] are essential.

![[Machine Learning Classification.png]]

## References
- [[Pattern Recognition and Machine Learning]] - By C. Bishop
- [[Machine Learning Fundamentals]] - Lecture Notes

#machine-learning #AI #data-science

Templates and Quick Actions

# Daily Review Template

## Date
{{date:YYYY-MM-DD}}

## Today's Reflection

### Completed Tasks
- [ ] Task 1
- [ ] Task 2
- [ ] Task 3

### What I Learned
- 

### Improvements Needed
- 

### Tomorrow's Plans
- [ ] Task 1
- [ ] Task 2

## Mood & Health
- Mood: 😊😐😞
- Health: 😊😐😞
- Energy Level: ⭐⭐⭐⭐⭐

## Notes & Ideas


## Links
- [[Yesterday's Review]]
- [[Tomorrow's Plan]]
- [[Weekly Review]]

#daily-note #reflection #{{date:YYYY-MM-DD}}

Basic Plugin Development Example

// main.ts - Basic structure of Obsidian plugin
import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian';

// Plugin settings interface
interface ExampleSettings {
    dateFormat: string;
    defaultTemplate: string;
    enableNotifications: boolean;
}

// Default settings
const DEFAULT_SETTINGS: ExampleSettings = {
    dateFormat: 'YYYY-MM-DD',
    defaultTemplate: '',
    enableNotifications: true
}

// Main plugin class
export default class ExamplePlugin extends Plugin {
    settings: ExampleSettings;

    async onload() {
        await this.loadSettings();

        // Add ribbon icon
        const ribbonIconEl = this.addRibbonIcon('dice', 'Sample Plugin', (evt: MouseEvent) => {
            new Notice('Hello, Obsidian!');
        });

        // Add status bar item
        const statusBarItemEl = this.addStatusBarItem();
        statusBarItemEl.setText('Status Bar Text');

        // Add command
        this.addCommand({
            id: 'open-sample-modal-simple',
            name: 'Open sample modal (simple)',
            callback: () => {
                new SampleModal(this.app).open();
            }
        });

        // Add editor command
        this.addCommand({
            id: 'sample-editor-command',
            name: 'Sample editor command',
            editorCallback: (editor: Editor, view: MarkdownView) => {
                const cursor = editor.getCursor();
                const line = editor.getLine(cursor.line);
                editor.replaceRange("**" + line + "**", 
                    { line: cursor.line, ch: 0 }, 
                    { line: cursor.line, ch: line.length }
                );
            }
        });

        // Add settings tab
        this.addSettingTab(new ExampleSettingTab(this.app, this));

        // Register markdown post processor
        this.registerMarkdownPostProcessor((element, context) => {
            const codeblocks = element.findAll('code');
            for (let codeblock of codeblocks) {
                const text = codeblock.innerText.trim();
                if (text.startsWith('TODO:')) {
                    codeblock.addClass('todo-highlight');
                }
            }
        });

        // Register markdown code block processor
        this.registerMarkdownCodeBlockProcessor('chart', (source, el, ctx) => {
            const chartContainer = el.createDiv({ cls: 'chart-container' });
            chartContainer.createEl('p', { text: 'Chart: ' + source });
        });
    }

    onunload() {
        // Cleanup process
    }

    async loadSettings() {
        this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
    }

    async saveSettings() {
        await this.saveData(this.settings);
    }
}

// Sample modal
class SampleModal extends Modal {
    constructor(app: App) {
        super(app);
    }

    onOpen() {
        const { contentEl } = this;
        contentEl.setText('Hello, Modal!');
        
        const button = contentEl.createEl('button', { text: 'Close' });
        button.addEventListener('click', () => {
            this.close();
        });
    }

    onClose() {
        const { contentEl } = this;
        contentEl.empty();
    }
}

// Settings tab
class ExampleSettingTab extends PluginSettingTab {
    plugin: ExamplePlugin;

    constructor(app: App, plugin: ExamplePlugin) {
        super(app, plugin);
        this.plugin = plugin;
    }

    display(): void {
        const { containerEl } = this;
        containerEl.empty();

        containerEl.createEl('h2', { text: 'Example Plugin Settings' });

        new Setting(containerEl)
            .setName('Date format')
            .setDesc('Format for dates in templates')
            .addText(text => text
                .setPlaceholder('YYYY-MM-DD')
                .setValue(this.plugin.settings.dateFormat)
                .onChange(async (value) => {
                    this.plugin.settings.dateFormat = value;
                    await this.plugin.saveSettings();
                }));

        new Setting(containerEl)
            .setName('Enable notifications')
            .setDesc('Show notification messages')
            .addToggle(toggle => toggle
                .setValue(this.plugin.settings.enableNotifications)
                .onChange(async (value) => {
                    this.plugin.settings.enableNotifications = value;
                    await this.plugin.saveSettings();
                }));

        new Setting(containerEl)
            .setName('Default template')
            .setDesc('Default template for new notes')
            .addTextArea(text => text
                .setPlaceholder('Enter template content...')
                .setValue(this.plugin.settings.defaultTemplate)
                .onChange(async (value) => {
                    this.plugin.settings.defaultTemplate = value;
                    await this.plugin.saveSettings();
                }));
    }
}

Custom Theme Creation

/* theme.css - Obsidian custom theme */

/* Main color palette */
.theme-dark {
    --background-primary: #1a1a1a;
    --background-secondary: #242424;
    --background-modifier-border: #404040;
    --text-normal: #e0e0e0;
    --text-muted: #a0a0a0;
    --text-accent: #7c3aed;
    --text-accent-hover: #8b5cf6;
}

.theme-light {
    --background-primary: #ffffff;
    --background-secondary: #f8f9fa;
    --background-modifier-border: #e5e7eb;
    --text-normal: #1f2937;
    --text-muted: #6b7280;
    --text-accent: #7c3aed;
    --text-accent-hover: #8b5cf6;
}

/* Editor customization */
.markdown-source-view.mod-cm6 .cm-editor {
    font-family: 'JetBrains Mono', monospace;
    font-size: 14px;
    line-height: 1.6;
}

/* Heading styles */
.HyperMD-header-1 {
    font-size: 2em;
    font-weight: bold;
    color: var(--text-accent);
    border-bottom: 2px solid var(--text-accent);
    padding-bottom: 0.3em;
    margin-bottom: 1em;
}

.HyperMD-header-2 {
    font-size: 1.5em;
    font-weight: bold;
    color: var(--text-normal);
    margin-top: 1.5em;
    margin-bottom: 0.5em;
}

/* Link styles */
.internal-link {
    color: var(--text-accent);
    text-decoration: none;
    border-bottom: 1px dotted var(--text-accent);
    transition: all 0.2s ease;
}

.internal-link:hover {
    color: var(--text-accent-hover);
    border-bottom: 1px solid var(--text-accent-hover);
}

/* Tag styles */
.tag {
    background-color: var(--background-secondary);
    border: 1px solid var(--background-modifier-border);
    border-radius: 12px;
    padding: 2px 8px;
    font-size: 0.8em;
    color: var(--text-muted);
    transition: all 0.2s ease;
}

.tag:hover {
    background-color: var(--text-accent);
    color: var(--background-primary);
}

/* Code block customization */
.markdown-source-view.mod-cm6 .cm-line .HyperMD-codeblock {
    background-color: var(--background-secondary);
    border-radius: 4px;
    border: 1px solid var(--background-modifier-border);
}

/* Graph view customization */
.graph-view.color-circle,
.graph-view.color-fill {
    color: var(--text-accent);
}

.graph-view.color-line {
    color: var(--background-modifier-border);
}

/* Sidebar customization */
.nav-folder-title {
    font-weight: 500;
    color: var(--text-normal);
}

.nav-file-title {
    color: var(--text-muted);
    transition: color 0.2s ease;
}

.nav-file-title:hover {
    color: var(--text-normal);
}

/* Custom plugin styles */
.todo-highlight {
    background-color: #fef3c7;
    color: #92400e;
    padding: 2px 4px;
    border-radius: 3px;
    font-weight: 500;
}

.chart-container {
    border: 1px solid var(--background-modifier-border);
    border-radius: 8px;
    padding: 16px;
    margin: 16px 0;
    background-color: var(--background-secondary);
}

Advanced Workflow Configuration

# Obsidian Workflow Configuration

## Plugin Setup

### Essential Plugins
1. **Dataview** - Data queries and report generation
2. **Templater** - Advanced template functionality
3. **Calendar** - Daily notes and calendar view
4. **Advanced Tables** - Improved table editing
5. **Tag Wrangler** - Tag management and renaming

### Productivity Enhancement Plugins
1. **QuickAdd** - Quick actions and macros
2. **Hotkeys++** - Advanced hotkey configuration
3. **Note Refactor** - Note splitting and merging
4. **Sliding Panes** - Efficient screen management with Andy Mode
5. **Workspaces** - Workspace saving and restoration

## Dataview Query Examples

### Recent Task List
```dataview
TASK
FROM #tasks
WHERE !completed
SORT created DESC
LIMIT 10

Project Progress Report

TABLE 
    file.link AS "Project",
    status AS "Status",
    progress AS "Progress",
    deadline AS "Deadline"
FROM #project
WHERE status != "completed"
SORT deadline ASC

Monthly Learning Log

LIST
FROM #learning
WHERE date(created) >= date(2025-06-01) AND date(created) <= date(2025-06-30)
SORT created DESC

Templater Configuration Examples

Daily Note Template

---
tags: [daily, <% tp.date.now("YYYY-MM-DD") %>]
created: <% tp.date.now("YYYY-MM-DD HH:mm") %>
---

# <% tp.date.now("MMMM Do, YYYY (dddd)") %>

## Today's Schedule
<% tp.web.daily_weather() %>

## Reflection
### Completed
- 

### Learned
- 

### Tomorrow's Tasks
- [ ] 

## Notes
- 

---
[[<% tp.date.now("YYYY-MM-DD", -1) %>]] ← Yesterday | Tomorrow → [[<% tp.date.now("YYYY-MM-DD", 1) %>]]

Meeting Note Template

---
tags: [meeting, <% tp.system.prompt("Project name") %>]
attendees: <% tp.system.prompt("Attendees") %>
date: <% tp.date.now("YYYY-MM-DD") %>
---

# Meeting: <% tp.system.prompt("Meeting title") %>

## Basic Information
- **Date & Time**: <% tp.date.now("YYYY-MM-DD HH:mm") %>
- **Attendees**: <% tp.system.prompt("Enter attendees separated by commas") %>
- **Location**: <% tp.system.prompt("Location") %>

## Agenda
1. 

## Discussion


## Decisions
- [ ] 

## Action Items
- [ ] 【AssigneeTask description (deadline)

## Next Meeting
- Date & Time: 
- Agenda: 

---
Related: [[Project Management]]

### Automation and Workflow
```bash
# Obsidian vault backup automation
#!/bin/bash

# Configuration
VAULT_PATH="/path/to/obsidian/vault"
BACKUP_PATH="/path/to/backup/location"
DATE=$(date +%Y%m%d_%H%M%S)

# Create backup directory
mkdir -p "$BACKUP_PATH/obsidian_backup_$DATE"

# Copy files (including .obsidian folder)
rsync -av --exclude='.trash' "$VAULT_PATH/" "$BACKUP_PATH/obsidian_backup_$DATE/"

# Delete backups older than 7 days
find "$BACKUP_PATH" -name "obsidian_backup_*" -type d -mtime +7 -exec rm -rf {} +

echo "Backup completed: obsidian_backup_$DATE"

Git Integration Management

# Git management for Obsidian vault
cd /path/to/obsidian/vault

# Daily automatic commit
#!/bin/bash
DATE=$(date +"%Y-%m-%d %H:%M:%S")

# Stage changes
git add .

# Commit (only if there are changes)
if ! git diff --cached --quiet; then
    git commit -m "Daily update: $DATE"
    echo "Changes committed: $DATE"
else
    echo "No changes to commit: $DATE"
fi

# Push to remote (optional)
# git push origin main

Advanced Data Processing

# Research Paper Management System

## Paper Database Query
```dataview
TABLE 
    title as "Title",
    authors as "Authors", 
    year as "Year",
    status as "Status",
    rating as "Rating",
    tags as "Topics"
FROM #paper
WHERE status != "archived"
SORT year DESC

Reading Progress Tracker

TASK
FROM #paper
WHERE contains(text, "[ ]") OR contains(text, "[x]")
GROUP BY file.link
SORT file.name ASC

Citation Network

LIST 
    join(file.outlinks, ", ") as "Citations"
FROM #paper
WHERE file.outlinks
SORT length(file.outlinks) DESC

Knowledge Graph Analysis

TABLE 
    length(file.inlinks) as "Incoming Links",
    length(file.outlinks) as "Outgoing Links",
    length(file.tags) as "Tags"
FROM ""
WHERE file.name != "README"
SORT length(file.inlinks) DESC
LIMIT 20

### Canvas and Visual Thinking
```markdown
# Canvas-based Project Planning

## Mind Mapping Structure
- Central idea in the center
- Branch out to main themes
- Use colors for different categories
- Add images and icons for visual appeal
- Connect related concepts with arrows

## Project Timeline Canvas
- Horizontal timeline across the canvas
- Milestones as colored nodes
- Dependencies shown with connecting lines
- Risk factors highlighted in red
- Resource allocation in dedicated sections

## Research Board Layout
- Literature review section
- Methodology cards
- Findings and insights area
- Future work possibilities
- Cross-references between all elements

Plugin Integration Workflow

// Advanced plugin interaction example
import { Plugin, TFile, Notice } from 'obsidian';

export default class WorkflowPlugin extends Plugin {
    async onload() {
        // Integration with Dataview plugin
        this.addCommand({
            id: 'generate-weekly-report',
            name: 'Generate Weekly Report',
            callback: async () => {
                await this.generateWeeklyReport();
            }
        });

        // Integration with Templater
        this.addCommand({
            id: 'create-project-structure',
            name: 'Create Project Structure',
            callback: async () => {
                await this.createProjectStructure();
            }
        });
    }

    async generateWeeklyReport() {
        const weekStart = moment().startOf('week').format('YYYY-MM-DD');
        const weekEnd = moment().endOf('week').format('YYYY-MM-DD');
        
        const reportContent = `# Weekly Report (${weekStart} to ${weekEnd})

## Completed Tasks
\`\`\`dataview
TASK
FROM #task
WHERE completed AND date(completion) >= date(${weekStart}) AND date(completion) <= date(${weekEnd})
\`\`\`

## New Notes Created
\`\`\`dataview
LIST
FROM ""
WHERE date(file.ctime) >= date(${weekStart}) AND date(file.ctime) <= date(${weekEnd})
\`\`\`

## Key Insights
<!-- Add your weekly insights here -->

## Next Week's Focus
<!-- Plan for the coming week -->
`;

        const fileName = "Weekly Report " + weekStart + ".md";
        await this.app.vault.create(fileName, reportContent);
        new Notice('Weekly report generated successfully!');
    }

    async createProjectStructure() {
        const projectName = await this.promptForProjectName();
        if (!projectName) return;

        const folders = [
            "Projects/" + projectName,
            "Projects/" + projectName + "/Notes",
            "Projects/" + projectName + "/Tasks",
            "Projects/" + projectName + "/Resources"
        ];

        for (const folder of folders) {
            await this.createFolderIfNotExists(folder);
        }

        // Create index file
        const indexContent = `# ${projectName}

## Overview
<!-- Project description -->

## Goals
- [ ] Goal 1
- [ ] Goal 2

## Resources
- [[Projects/${projectName}/Resources/Research]]
- [[Projects/${projectName}/Resources/References]]

## Tasks
\`\`\`dataview
TASK
FROM "Projects/${projectName}/Tasks"
WHERE !completed
\`\`\`

## Notes
\`\`\`dataview
LIST
FROM "Projects/${projectName}/Notes"
\`\`\`
`;

        await this.app.vault.create("Projects/" + projectName + "/Index.md", indexContent);
        new Notice("Project structure created for: " + projectName);
    }

    async promptForProjectName(): Promise<string | null> {
        return new Promise((resolve) => {
            const modal = new ProjectNameModal(this.app, resolve);
            modal.open();
        });
    }

    async createFolderIfNotExists(folderPath: string) {
        const folder = this.app.vault.getAbstractFileByPath(folderPath);
        if (!folder) {
            await this.app.vault.createFolder(folderPath);
        }
    }
}