参拝記録をデジタル管理|Obsidian×DataviewJSで御朱印データベース化と検索術

技術

はじめに

御朱印帳は、神社や寺院を参拝した証としていただける大切な記録です。
その一枚一枚には参拝した日の思い出や、その土地の歴史や雰囲気が宿っています。

ただ、旅を重ねて御朱印を集めていくと「いつ・どこで・どんな御朱印をいただいたか」を後から探すのが意外と大変です。御朱印帳が複数冊になっていくと、さらに管理が難しくなります。

そこで僕は Obsidian × DataviewJS を使って「御朱印データベース」を作りました。
ObsidianはMarkdownベースでローカルに保存でき、拡張性も高い。そしてDataviewJSを組み合わせれば、検索や絞り込み、カード型のギャラリー表示まで可能です。


デジタル管理のメリット

紙の御朱印帳はもちろん大切に使い続けていますが、デジタル化にもたくさんのメリットがあります。

  • 検索ができる:寺社名や参拝日、ご祭神などを一発検索
  • エピソードを残せる:御朱印と一緒に参拝の記録をメモ
  • 冊数が増えても一元管理:御朱印帳が何冊あっても一覧で確認できる
  • バックアップが効く:万一の紛失リスクをカバー
  • スマホとPCでシームレスに使える:Obsidian Syncを使えば、旅先でスマホから御朱印を記録し、後でPCで整形・ギャラリー表示して楽しむ運用が可能

御朱印は参拝の証であり、決してスタンプラリーではありません。
その大切な記録をより豊かに残すための補助として、デジタル化は非常に有効だと感じています。


Obsidianとは?

Obsidian は、Markdown形式のノートをベースにした知識管理アプリです。

特徴は大きく4つあります。

  • ローカル保存が基本
    ノートはすべて自分のPCやスマホにMarkdownファイルとして保存されます。クラウドサービスに依存しないので、安心して長期的に使えるのが魅力です。
  • クラウド同期(Obsidian Sync)も可能
    有料機能の「Obsidian Sync」を使えば、PCとスマホの両方でノートを同期できます。
    旅先でスマホから御朱印を記録して、帰宅後にPCで整形するといった使い方も簡単にできます。DropboxやiCloudなど外部クラウドと連携する方法もあり、自分のスタイルに合わせて選べます。
  • リンクとグラフビュー
    ノート同士を簡単にリンクでき、参拝記録と旅のメモを関連付けて整理できます。さらにグラフビューで関係性を可視化できるのも大きな強みです。
  • プラグインによる拡張性
    DataviewやTemplaterなどを導入すれば、ノートをデータベースとして扱ったり、自動化したりできます。今回紹介する御朱印データベースも、この拡張機能を活かして実現しています。

紙の御朱印帳が「参拝の証」を残すのに対して、Obsidianは「参拝の記録」を整理して未来に活かすための道具。両方を組み合わせることで、より豊かな参拝体験が得られます。


プロパティ設計

御朱印ごとに1ノートを作り、プロパティに情報を入れています。

主な項目は以下の通りです。

  • 寺社名
  • 種類(神社 / 寺院)
  • 種別(通常 / 限定)
  • 参拝日
  • 御朱印帳名(物理の御朱印帳と対応)
  • ご祭神・ご本尊
  • 都道府県 / 市区町村
  • タグ
  • バナー画像(御朱印の写真など)

例:

寺社名: 出雲大社
種類: 神社
種別: 通常
参拝日: 2025-09-07
都道府県: 島根県
市区町村: 出雲市
御朱印帳名: 伊勢神宮2025
ご祭神・ご本尊: 大国主大神
banner: ![[出雲大社-20250907.jpg]]
tags: 御朱印, 神社
作成日時: 2025-09-07 22:00
imageNameKey: 出雲大社

使っているプラグイン

御朱印データベースを快適に運用するために導入しているプラグインを紹介します。

  • Dataview
    ノートのプロパティを一覧化・検索できるプラグイン。今回のシステムの中心。
  • Templater
    新しい御朱印ノートを作成するときに「参拝日」「寺社名」などを自動で挿入。記録漏れ防止にもなる。
  • Awesome Image
    ノート内の画像表示を拡張。御朱印や社殿の写真を見やすく整理。
  • Simple Banner
    ノート冒頭に御朱印や社殿の写真をバナーとして表示。アルバム的な見栄えに。
  • Paste Image Rename
    スマホやPCで撮った画像を貼り付ける際に自動でリネーム。「出雲大社-20250907.jpg」のように規則化して管理できる。
  • File Explorer++
    ファイルエクスプローラーを強化。参拝記録が増えてもノートを並べ替え・管理しやすい。

この組み合わせによって「御朱印を記録する → 写真を貼る → 名前を整理 → ギャラリーで眺める」という流れがスムーズに回るようになりました。


DataviewJSで「御朱印ギャラリー」を作る

Dataviewのテーブル表示でも便利ですが、DataviewJSを使うとよりリッチなUIが作れます。
僕は検索ボックスやセレクトメニューを付け、Webアプリのように扱えるギャラリーを構築しました。

以下、実際に使っているコード全文を公開します。

```dataviewjs
/***** 設定 *****/
const SRC = '#御朱印';
const MIN_COL = 240;

/***** util *****/
const toMs  = v => { try { return dv.date(v)?.toMillis?.() ?? 0; } catch { return 0; } };
const fmt   = v => { try { return dv.date(v)?.toFormat("yyyy-LL-dd") ?? ""; } catch { return String(v ?? ""); } };
const norm  = s => (s ?? "").toString().toLowerCase().normalize("NFKC").trim();
const extractPath = (b) => {
  if (!b) return null;
  if (Array.isArray(b)) b = b[0];
  if (typeof b === 'object') return b.path ?? b.file?.path ?? null;
  if (typeof b === 'string') {
    const m = b.trim().match(/!\[\[([^|\]]+)/);
    return m ? m[1].trim() : b.trim();
  }
  return null;
};
const toSrc = (path, source) => {
  if (!path) return null;
  if (/^https?:\/\//i.test(path)) return path;
  const f = app.metadataCache.getFirstLinkpathDest(path, source);
  return f ? app.vault.getResourcePath(f) : null;
};

/***** データ取得 *****/
let all = dv.pages(SRC).array()
  .filter(p => !!toSrc(extractPath(p.banner), p.file.path));

/***** コントロールUI *****/
const panel = dv.container.createDiv();
Object.assign(panel.style, { marginBottom: '10px', display: 'flex', gap: '8px', flexWrap: 'wrap' });

const q = panel.createEl('input', { type: 'search', placeholder: 'キーワード(寺社名/タイトル/ご祭神・ご本尊)' });
Object.assign(q.style, { padding: '6px 8px', minWidth: '18rem' });

const typeSel = panel.createEl('select');
['(すべて)','神社','寺院'].forEach(v => {
  const o = typeSel.createEl('option', { text: v });
  o.value = v === '(すべて)' ? '' : v;
});
Object.assign(typeSel.style, { padding: '6px 8px' });

const kindSel = panel.createEl('select'); // ← 追加: 種別(通常/限定)
['(すべて)','通常','限定'].forEach(v => {
  const o = kindSel.createEl('option', { text: v });
  o.value = v === '(すべて)' ? '' : v;
});
Object.assign(kindSel.style, { padding: '6px 8px' });

const prefSel = panel.createEl('select');
(() => {
  const prefs = Array.from(new Set(all.map(p => p["都道府県"]).filter(Boolean))).sort();
  prefSel.createEl('option', { text: '(すべて)', value: '' });
  prefs.forEach(v => prefSel.createEl('option', { text: v, value: v }));
})();
Object.assign(prefSel.style, { padding: '6px 8px' });

const from = panel.createEl('input', { type: 'date' });
const to   = panel.createEl('input', { type: 'date' });
Object.assign(from.style, { padding: '6px 8px' });
Object.assign(to.style,   { padding: '6px 8px'  });

const resetBtn = panel.createEl('button', { text: 'リセット' });
Object.assign(resetBtn.style, { padding: '6px 10px' });

/***** ギャラリー(コンテナ) *****/
const root = dv.container.createDiv();
Object.assign(root.style, {
  display: 'grid',
  gridTemplateColumns: `repeat(auto-fill, minmax(${MIN_COL}px, 1fr))`,
  gap: '12px'
});

/***** カード描画関数(省略:前回と同じ cardFor() を使う) *****/
function cardFor(p, parent) {
  const card = parent.createDiv();
  Object.assign(card.style, {
    display: 'flex', flexDirection: 'column',
    background: getComputedStyle(document.body).getPropertyValue('--background-primary') || '#fff',
    border: `1px solid ${getComputedStyle(document.body).getPropertyValue('--background-modifier-border') || '#ddd'}`,
    borderRadius: '8px', boxShadow: 'var(--shadow-s)', overflow: 'hidden'
  });

  const thumb = card.createDiv();
  const imgSrc = toSrc(extractPath(p.banner), p.file.path);
  if (imgSrc) {
    const img = thumb.createEl('img', { attr: { src: imgSrc, alt: p["寺社名"] ?? p.file.name } });
    Object.assign(img.style, { width: '100%', height: 'auto', display: 'block', objectFit: 'contain', background: '#f8f8f8' });
  }

  const meta = card.createDiv();
  Object.assign(meta.style, { marginTop: 'auto', padding: '8px 10px', display: 'flex', flexDirection: 'column', lineHeight: '1.2' });

  const nameEl = meta.createEl('strong', { text: p["寺社名"] ?? "" });
  nameEl.style.margin = '2px 0';

  const titleEl = meta.createEl('span', { text: p.file.name });
  Object.assign(titleEl.style, { margin: '2px 0', color: 'var(--text-muted)', fontSize: '0.9em' });

  if (p["参拝日"]) {
    const d = meta.createEl('span', { text: fmt(p["参拝日"]) });
    Object.assign(d.style, { margin: '2px 0 6px 0', color: 'var(--text-muted)', fontSize: '0.85em' });
  }

  // タグ用コンテナを先に作る
  const tags = meta.createDiv();
  Object.assign(tags.style, {
    display: 'flex',
    flexWrap: 'wrap',
    gap: '4px',
    margin: '2px 0'
  });
  
  // 種類(神社/寺院 タグ風・色分け)
  if (p["種類"]) {
    const t = tags.createEl('span', { text: p["種類"] });
    Object.assign(t.style, {
      display: 'inline-block',
      minWidth: 'fit-content',
      maxWidth: 'max-content',
      whiteSpace: 'nowrap',
      padding: '2px 6px',
      borderRadius: '4px',
      fontSize: '0.8em'
    });
    const v = String(p["種類"]).trim();
    if (v === '神社') {
      t.style.background = '#e0f0ff';
      t.style.color = '#0050b3';
      t.style.border = '1px solid #99c2ff';
    } else if (v === '寺院') {
      t.style.background = '#e6ffed';
      t.style.color = '#006d3c';
      t.style.border = '1px solid #9ae6b4';
    } else {
      t.style.background = '#eee';
      t.style.color = '#333';
      t.style.border = '1px solid #ddd';
    }
  }

  // 種別(通常/限定 タグ風・色分け)
  if (p["種別"]) {
    const k = tags.createEl('span', { text: p["種別"] });
    Object.assign(k.style, {
      display: 'inline-block',
      minWidth: 'fit-content',
      maxWidth: 'max-content',
      whiteSpace: 'nowrap',
      padding: '2px 6px',
      borderRadius: '4px',
      fontSize: '0.75em'
    });
    const v = String(p["種別"]).trim();
    if (v === '限定') {
      k.style.background = '#ffe2ea';
      k.style.color = '#b0003a';
      k.style.border = '1px solid #f5a5bb';
    } else {
      k.style.background = '#eee';
      k.style.color = '#333';
      k.style.border = '1px solid #ddd';
    }
  }

  const place = [p["都道府県"], p["市区町村"]].filter(Boolean).join(' ');
  if (place) {
    const plc = meta.createEl('span', { text: place });
    Object.assign(plc.style, { margin: '2px 0', fontSize: '0.9em' });
  }

  const a = meta.createEl('a', { text: 'ノートを開く' });
  a.classList.add('internal-link'); a.setAttr('href', p.file.path); a.setAttr('data-href', p.file.path);
  Object.assign(a.style, { marginTop: '6px', fontSize: '0.9em', textDecoration: 'none', color: 'var(--text-accent)' });
}

/***** レンダリング *****/
function render() {
  const qv   = norm(q.value);
  const tv   = typeSel.value || '';
  const kv   = kindSel.value || ''; // ← 種別
  const pv   = prefSel.value || '';
  const fromMs = from.value ? new Date(from.value).getTime() : null;
  const toMsV  = to.value   ? (new Date(to.value).getTime() + 24*60*60*1000 - 1) : null;

  let rows = all.filter(p => {
    if (qv) {
      const hay = [norm(p["寺社名"]), norm(p.file.name), norm(p["ご祭神・ご本尊"])].join(' ');
      if (!hay.includes(qv)) return false;
    }
    if (tv && p["種類"] !== tv) return false;
    if (kv && p["種別"] !== kv) return false; // ← 種別フィルタ
    if (pv && p["都道府県"] !== pv) return false;

    const ms = toMs(p["参拝日"]);
    if (fromMs && (ms === 0 || ms < fromMs)) return false;
    if (toMsV  && (ms === 0 || ms > toMsV )) return false;

    return true;
  });

  rows.sort((a,b) => toMs(b["参拝日"]) - toMs(a["参拝日"]));

  root.empty();
  rows.forEach(p => cardFor(p, root));
}

let timer;
[q, typeSel, kindSel, prefSel, from, to].forEach(el => el.addEventListener('input', () => {
  clearTimeout(timer); timer = setTimeout(render, 120);
}));
resetBtn.addEventListener('click', () => {
  q.value = ''; typeSel.value = ''; kindSel.value = ''; prefSel.value = ''; from.value = ''; to.value = ''; render();
});

render();

このコードで実現できる機能は次の通りです。

  • キーワード検索(寺社名 / タイトル / ご祭神)
  • 種類(神社 / 寺院)の切り替え
  • 種別(通常 / 限定)のフィルタ
  • 都道府県別の抽出
  • 参拝日の範囲指定
  • 画像つきカード型の一覧表示

Obsidian Syncを活用した運用事例

Obsidianの強みは「ローカルに保存できる安心感」と「クラウド同期できる柔軟さ」の両立です。
特に有料機能の Obsidian Sync を活用すると、PCとスマホの両方で同じ御朱印データベースを扱えるようになります。
旅をしながら参拝記録を残す僕にとっては、この同期が非常に便利でした。

旅先での使い方

  • 神社や寺院を参拝 → 御朱印をいただく
  • その場でスマホのObsidianを開き、新しいノートをテンプレートから作成
  • 「参拝日」「寺社名」「種別(通常/限定)」などをサクッと入力し、御朱印の写真を貼り付ける
  • このとき Microsoft Lens を使って撮影すると、紙面が自動補正され、影や傾きが抑えられて綺麗な画像が保存できます
  • 保存した画像は Paste Image Rename プラグインで自動的に「出雲大社-20250907.jpg」のような名前に変換される

これで参拝直後に基本情報と写真を確実に記録できます。

帰宅後・PCでの使い方

  • スマホで作ったノートが、Obsidian Sync経由で自動的にPCに同期されている
  • PCで開き、詳細なメモやご祭神、参拝時のエピソードを追記
  • DataviewJSのギャラリーに反映され、直近の参拝がすぐに一覧に並ぶ
  • 大画面で写真を確認したり、限定御朱印だけを抽出して「また参拝したい神社リスト」を作る

運用して感じたこと

  • 「旅先でスマホ → 帰宅後にPC」という自然な流れができる
  • 記録がリアルタイムに積み重なっていくので、参拝日記としての一貫性が保たれる
  • 紙の御朱印帳の重みと、デジタル管理の検索性や整理のしやすさが両立できる

まとめ

御朱印帳は、参拝した証を残す大切な宝物です。墨の香りや紙の質感、手渡された瞬間の重みは、デジタルには代えられません。

一方で、旅を続けて数多くの御朱印を集めていくと、「いつ」「どこで」「どんな御朱印をいただいたのか」を記録・整理するのが難しくなります。そこで登場するのが Obsidian × DataviewJS です。

この仕組みを導入すると、御朱印帳は単なる記録から一気に「検索可能な参拝データベース」へ進化します。

  • 御朱印を写真付きでカード化して振り返れる
  • 「限定御朱印だけ」や「特定の都道府県だけ」を一瞬で抽出できる
  • 参拝日やご祭神まで整理して、後から知識ベースとして活用できる

そして大切なのは、御朱印は参拝の証であり、決してスタンプラリーではないということ。
紙の御朱印帳で感じる重みと、デジタルで得られる検索性や整理のしやすさ。両者は競合するのではなく、お互いを補完し合う存在です。

さらにObsidianの Sync機能 を利用すれば、PCでもスマホでも同じ御朱印データベースにアクセスできます。旅先で参拝したその場で写真を取り込み、すぐにノートを作成して記録することが可能です。移動中にスマホで追加した記録を、後でPCで整形してギャラリーで眺め直す、そんな運用も自然にできます。

結果として「参拝したその瞬間から、記録し、振り返り、また次の参拝に活かす」という循環が生まれます。
それは単なるログではなく、自分自身の参拝史を積み重ねていく作業そのもの。

紙とデジタルを組み合わせれば、御朱印はただ集めるだけのものではなく、人生の旅路を豊かに彩るストーリーとなります。
もし御朱印を集めているなら、この方法をぜひ一度試してみてください。きっとあなたの御朱印帳が、新しい形で息づき始めるはずです。

コメント

タイトルとURLをコピーしました