````
---
Doc Lock: false
Adventure:
Location:
session:
session_date:
day:
month:
year:
---
# 🏔 `= this.Adventure + " - Session " + this.session`
**`= this.location`***
```dataviewjs
const dayField = dv.current().day;
const monthField = dv.current().month;
const yearField = dv.current().year;
if (!dayField || !monthField || !yearField) {
dv.el("em", "In-game date not set yet.");
} else {
const days = Array.isArray(dayField) ? dayField : [dayField];
const months = Array.isArray(monthField) ? monthField : [monthField];
const years = Array.isArray(yearField) ? yearField : [yearField];
const finalYear = years.length > 0 ? years[0] : "????";
function getDaySuffix(d) {
if (d % 100 >= 11 && d % 100 <= 13) return d + "th";
switch (d % 10) {
case 1: return d + "st";
case 2: return d + "nd";
case 3: return d + "rd";
default: return d + "th";
}
}
function formatOneDayMonth(dayNum, monthStr) {
return `${getDaySuffix(dayNum)} day of ${monthStr}`;
}
function joinWithAnd(list) {
if (list.length === 0) return "";
if (list.length === 1) return list[0];
if (list.length === 2) return list.join(" and ");
// For 3 or more, do commas plus final "and"
return list.slice(0, -1).join(", ") + ", and " + list[list.length - 1];
}
let daysAndMonthsStr = "";
if (days.length === months.length && days.length > 1) {
const pairs = [];
for (let i = 0; i < days.length; i++) {
pairs.push(formatOneDayMonth(days[i], months[i]));
}
daysAndMonthsStr = joinWithAnd(pairs);
} else if (days.length > 1 && months.length === 1) {
const dayStrings = days.map(d => getDaySuffix(d));
const joinedDays = joinWithAnd(dayStrings);
daysAndMonthsStr = `${joinedDays} day${days.length > 1 ? "s" : ""} of ${months[0]}`;
} else if (days.length === 1 && months.length > 1) {
const pieces = months.map(m => formatOneDayMonth(days[0], m));
daysAndMonthsStr = joinWithAnd(pieces);
} else if (days.length === 1 && months.length === 1) {
daysAndMonthsStr = formatOneDayMonth(days[0], months[0]);
} else {
daysAndMonthsStr = "Mixed or mismatched days/months (update the code logic).";
}
const finalString = `${daysAndMonthsStr}, ${finalYear} in the Age of Dominion`;
const container = dv.el("p", "");
container.innerHTML = `<em>${finalString}</em>`;
}
```
---
`BUTTON[previous,current,next,new]`
```meta-bind-button
label: NEW SESSION!
icon: ""
hidden: true
class: ""
tooltip: Create a new session note
id: new
style: primary
actions:
- type: templaterCreateNote
templateFile: "Extras/Templates/(exampleadventure)session 1.md" # Ensure this is the correct path to your template
folderPath: "Adventures/ADVENTURE FOLDER/SESSION NOTES FOLDER"
fileName: ""
openNote: true
```
---
```meta-bind-button
label: Previous Session
icon: ""
hidden: true
class: meta-bind-button
tooltip: "Go to the previous session note"
id: previous
style: default
actions:
- type: inlineJS
code: |
const folderPath = "Adventures/ADVENTURE FOLDER/SESSION NOTES FOLDER";
const currentTitle = app.workspace.activeLeaf.view.file.basename;
const filePattern = /Session (\d+)/;
const match = currentTitle.match(filePattern);
if (match && match[1]) {
const sessionNumber = parseInt(match[1]) - 1;
const previousSessionTitle = `Session ${sessionNumber}`;
const files = app.vault.getAbstractFileByPath(folderPath)?.children || [];
const previousNote = files.find(file => file.basename.startsWith(previousSessionTitle));
if (previousNote) {
app.workspace.activeLeaf.openFile(previousNote);
} else {
alert("Previous session does not exist.");
}
}
```
```meta-bind-button
label: Next Session
icon: ""
hidden: true
class: meta-bind-button
tooltip: "Go to the next session note"
id: next
style: default
actions:
- type: inlineJS
code: |
const folderPath = "Adventures/ADVENTURE FOLDER/SESSION NOTES FOLDER";
const currentTitle = app.workspace.activeLeaf.view.file.basename;
const filePattern = /Session (\d+)/;
const match = currentTitle.match(filePattern);
if (match && match[1]) {
const sessionNumber = parseInt(match[1]) + 1;
const nextSessionTitle = `Session ${sessionNumber}`;
const files = app.vault.getAbstractFileByPath(folderPath)?.children || [];
const nextNote = files.find(file => file.basename.startsWith(nextSessionTitle));
if (nextNote) {
app.workspace.activeLeaf.openFile(nextNote);
} else {
alert("Next session does not exist.");
}
}
```
```meta-bind-button
label: Current Session
icon: ""
hidden: true
class: meta-bind-button
tooltip: "Go to the most recent session note"
id: current
style: destructive
actions:
- type: inlineJS
code: |
const folderPath = "Adventures/ADVENTURE FOLDER/SESSION NOTES FOLDER";
// Get all notes in the folder and filter for those matching "Session X" format
const files = app.vault.getAbstractFileByPath(folderPath)?.children || [];
const sessionFiles = files
.filter(file => file.basename.match(/Session \d+/))
.sort((a, b) => {
// Sort by session number in descending order
const aNum = parseInt(a.basename.match(/Session (\d+)/)[1]);
const bNum = parseInt(b.basename.match(/Session (\d+)/)[1]);
return bNum - aNum;
});
if (sessionFiles.length > 0) {
// Open the most recent session
app.workspace.activeLeaf.openFile(sessionFiles[0]);
} else {
alert("No sessions found.");
}
```
>[!abstract]- Previously on...
>
## 🛠️ Prep
---
---
## 📝 Session Notes
---
### ☑️ Summary
##### Takeaways
##### Next Session
<%*
// ------------------------
// Session Template with Modal Form Date Entry
// ------------------------
// 1. Define the folder path and scan for existing session notes
const folderPath = "Adventures/ADVENTURE FOLDER/SESSION NOTES FOLDER"; // Adjust if needed
const folder = app.vault.getAbstractFileByPath(folderPath);
const files = folder ? folder.children.filter(f => f.extension === "md") : [];
const filePattern = /Session (\d+) - (\d{1,2})\.(\d{1,2})\.(\d{2})/; // Matches "Session X - mm.dd.yy"
let maxSessionNumber = 0;
let latestSessionDate = null;
files.forEach(file => {
const match = file.name.match(filePattern);
if (match) {
const sessionNumber = parseInt(match[1]);
const month = match[2];
const day = match[3];
const year = `20${match[4]}`; // Convert yy to full year
if (sessionNumber > maxSessionNumber) {
maxSessionNumber = sessionNumber;
latestSessionDate = new Date(`${year}-${month}-${day}`);
}
}
});
// 2. Determine a suggested date: if a previous session exists, add 7 days; otherwise, today + 7.
let suggestedDate = "";
if (latestSessionDate) {
const nextDate = new Date(latestSessionDate);
nextDate.setDate(nextDate.getDate() + 7);
suggestedDate = `${nextDate.getMonth() + 1}.${nextDate.getDate()}.${String(nextDate.getFullYear()).slice(-2)}`;
} else {
const today = new Date();
today.setDate(today.getDate() + 7);
suggestedDate = `${today.getMonth() + 1}.${today.getDate()}.${String(today.getFullYear()).slice(-2)}`;
}
// 3. Calculate the next session number
const nextSessionNumber = maxSessionNumber + 1;
// 4. Open the modal form for date entry (ID "next-session-date" with field "date")
const modalForm = app.plugins.plugins.modalforms.api;
const sessionResult = await modalForm.openForm("next-session-date");
if (!sessionResult) {
new Notice("Form cancelled.");
return;
}
// Retrieve the date as a string; if empty, use the suggested date.
// Also, if the input appears in ISO format (YYYY-MM-DD), convert it.
let sessionDateInput = String(sessionResult.date || "").trim();
if (!sessionDateInput) {
sessionDateInput = suggestedDate;
} else if (sessionDateInput.includes("-")) {
let parts = sessionDateInput.split("-");
let year = parseInt(parts[0]);
let month = parseInt(parts[1]); // Month is 1-indexed in the input.
let day = parseInt(parts[2]);
// Create the date using local time.
let d = new Date(year, month - 1, day);
sessionDateInput = `${d.getMonth() + 1}.${d.getDate()}.${d.getFullYear().toString().slice(-2)}`;
}
let sessionDate = sessionDateInput; // Now in the format M.D.YY
// 5. Rename the active note to "Session X - M.D.YY"
const newTitle = `Session ${nextSessionNumber} - ${sessionDate}`;
await tp.file.rename(newTitle);
// 6. Once all templates are executed, update the frontmatter and run extraction/insertion code.
tp.hooks.on_all_templates_executed(async () => {
const file = app.workspace.getActiveFile();
if (!file) {
new Notice("No active file found.");
return;
}
// Update frontmatter with session number and date
await app.fileManager.processFrontMatter(file, (frontmatter) => {
frontmatter["session"] = nextSessionNumber;
frontmatter["session_date"] = sessionDate;
});
// --- Begin Extraction and Insertion Code ---
let previousNote = null;
let previousNoteContent = "";
if (nextSessionNumber > 1) {
const previousSessionNumber = nextSessionNumber - 1;
const previousNotePattern = new RegExp(`^Session ${previousSessionNumber} - `);
previousNote = files.find(f => previousNotePattern.test(f.name));
if (previousNote) {
previousNoteContent = await app.vault.read(previousNote);
// Get previous note's frontmatter (day, month, year) if available.
const prevFrontmatter = app.metadataCache.getFileCache(previousNote)?.frontmatter || {};
const prevDay = prevFrontmatter.day || "";
const prevMonth = prevFrontmatter.month || "";
const prevYear = prevFrontmatter.year || "";
await app.fileManager.processFrontMatter(file, (frontmatter) => {
frontmatter.day = prevDay;
frontmatter.month = prevMonth;
frontmatter.year = prevYear;
});
} // End of if (previousNote)
} // End of if (nextSessionNumber > 1)
await new Promise(r => setTimeout(r, 250));
}); // <-- Ensure this closing bracket matches `tp.hooks.on_all_templates_executed`
%>