A configuration-driven, multi-vault query and dashboard system for Obsidian that transforms static Dataview queries into interactive, real-time dashboards.
- Configuration-Driven: Define your catalog structure once, use it everywhere
- Portable Across Vaults: Ship with sensible defaults, customize per vault
- Real-Time Updates: Dashboards refresh automatically as your vault changes
- Multiple Presets: Bundled configurations for Pulp Fiction, General Library, and Manuscripts
- Customizable Schemas: Add/remove fields and configure component visibility
- Mobile-Ready: Responsive design works on iOS, Android, and desktop
Copy the entire plugin folder to your Obsidian vault:
<vault>/.obsidian/plugins/cartographer/
Then enable it in Settings → Community plugins.
Open Settings → Datacore and select a preset:
- Pulp Fiction (default): Horror pulp fiction catalog with 13 fields and editorial workflow
- General Library: Book collection tracker with reading status
- Manuscripts: Writing project tracker with submission workflow
- Custom: Start from scratch with your own schema
Use the ribbon icon or commands:
Datacore: Open Status Dashboard- See items grouped by statusDatacore: Open Works Table- Browse all items in sortable table
This plugin is built with a clean, layered architecture:
- Data Access Layer (
hooks/useDataLoading.ts): Load and parse markdown files from vault with real-time subscriptions - Query Layer (
queries/queryFunctions.ts): Pure functions for filtering, sorting, grouping, and aggregating - State Management: Filter state, sort state, pagination
- View Layer (
components/): Obsidian ItemView components for rendering - Settings Layer (
config/settingsManager.ts): Persistent configuration management
src/
├── main.ts # Plugin entry point
├── index.ts # Public API exports
├── types/
│ ├── settings.ts # DatacoreSettings, CatalogSchema
│ ├── dynamicWork.ts # CatalogItem, state types
│ └── types.ts # Utility functions
├── config/
│ ├── presets.ts # PULP_FICTION, GENERAL_LIBRARY, MANUSCRIPTS presets
│ └── settingsManager.ts # SettingsManager + settings UI tab
├── hooks/
│ └── useDataLoading.ts # File loading, vault subscriptions, filtering
├── queries/
│ └── queryFunctions.ts # 20+ query utility functions
├── components/
│ ├── DatacoreComponentView.ts # Base ItemView class
│ ├── StatusDashboardView.ts # Status summary component
│ └── WorksTableView.ts # Works table component
└── styles/
└── components.css # Component-specific styles (imported into main)
##Development
npm installnpm run buildnpm run devnpm run lint- Entry Point:
main.ts- Plugin class and command registration - Build Output:
main.js- Bundled JavaScript (created by esbuild) - Manifest:
manifest.json- Plugin metadata - Styles:
styles.css- All plugin styling
Access Settings → Datacore to:
- Select a preset configuration
- Set the catalog directory path (relative to vault root)
- Enable/disable individual dashboard components
- Configure UI options (items per page, compact mode, etc.)
- Path:
works/ - 13 Fields: title, authors, year, catalog-status, word-count, publications, bp-candidate, bp-approved, date-reviewed, date-approved, date-cataloged, keywords, content-warnings
- Status Workflow: raw → reviewed → approved → published
- Dashboards: Status Summary, Works Table, Publication Dashboard, Author Card, Backstage Pass Pipeline
- Path:
library/ - 6 Fields: title, author, genre, status, year, rating
- Status Workflow: unread → reading → completed
- Dashboards: Status Summary, Works Table, Author Card
- Path:
manuscripts/ - 9 Fields: title, author, genre, status, word-count, draft-date, query-date, agent, publisher
- Status Workflow: draft → revising → querying → published
- Dashboards: Status Summary, Works Table, Manuscript Pipeline
- Path:
catalog/ - Fields: Minimal (title only)
- Start from scratch and add your own fields
Shows item counts grouped by a status field.
┌─────────────────────────────┐
│ Status Summary │
├──────────────┬──────────────┤
│ Status │ Count │
├──────────────┼──────────────┤
│ raw │ 5 │
│ reviewed │ 8 │
│ approved │ 2 │
└──────────────┴──────────────┘
Interactive table with sorting and pagination.
- Sortable columns
- Pagination controls
- Respects field visibility settings
- Mobile-responsive
Shows all works in a specific publication (wikilink array field).
Shows all works by a specific author with statistics.
Custom workflow showing items at different stages (e.g., candidate → approved → in-pipeline).
Export for use in other scripts or custom components:
import {
filterByField,
filterByText,
filterByRange,
sortByField,
groupByField,
countByField,
getUniqueValues,
getNumericStats,
paginate,
} from 'cartographer';See src/queries/queryFunctions.ts for full API documentation.
Full TypeScript support with exported types:
import type {
DatacoreSettings,
CatalogSchema,
SchemaField,
CatalogItem,
FilterState,
SortState,
CatalogStatistics,
} from 'cartographer';The plugin includes responsive CSS for:
- iOS (Safari in Obsidian app)
- Android (Obsidian app)
- Desktop (Chrome, Edge, Safari)
All components gracefully degrade on small screens:
- Tables switch to card view on mobile
- Filter bar stacks vertically
- Pagination handled automatically
- Client-side filtering: Instant responses, no server calls
- Memoized operations: Expensive computations cached
- Lazy loading: Components load on-demand
- Real-time subscriptions: Minimal overhead for vault changes
- Pagination: Handle large catalogs efficiently
Catalog items use standard Obsidian markdown with YAML frontmatter:
---
title: "The Shadow in the Attic"
authors: ["Lovecraft, Howard Phillips"]
year: 1922
catalog-status: "approved"
word-count: 3500
bp-candidate: true
publications: ["[[Weird Tales Vol 5 No 1]]"]
---
# The Shadow in the Attic
Story content and description...Extend DatacoreComponentView:
import {
DatacoreComponentView,
loadCatalogItems
} from 'cartographer';
export class MyCustomView extends DatacoreComponentView {
async loadData() {
this.items = await loadCatalogItems(this.app, this.settings);
}
async renderComponent() {
// Render your custom UI
}
}Add custom fields in settings:
- Define field in schema
- Parse with
parseFieldValue()utility - Display with
formatFieldValue()utility
0-BSD License - See LICENSE file for details
Status: Phase 6 Implementation
Version: 0.1.0
Last Updated: 2026-01-01