````
---
players:
- "[[player1]]"
- '[[player 2]]'
- "[[player 3]]"
- "[[player 4]]"
adventure: Example Adventure
---
# 📜 Adventures in Templating - Adventure Hub
## 📚 Chapter Links
```dataviewjs
const currentFolder = dv.current().file.folder;
const adventureFolder = `${currentFolder}/Adventure`;
// Fetch pages from the "Adventure" folder
const pages = dv.pages(`"${adventureFolder}"`).sort(p => p.file.name);
// Output each note as an H4 link
pages.forEach(p => dv.header(4, p.file.link));
```
>[!success] Current Session:
> ```dataviewjs
> const pages = dv.pages('"Adventures/Example Adventure/Session Notes"')
> .sort(p => p.file.ctime, 'desc')
> .limit(1);
> if (pages.length) {
> dv.header(4, pages[0].file.link);
> }
>
>
> ```
![[example_quicknotes]]
## 👥 Player Characters
```dataviewjs
const players = dv.current().players;
if (!players || players.length === 0) {
dv.paragraph("No players found.");
} else {
const playerPages = players
.map(player => dv.page(player))
.filter(p => p);
dv.table(
["Player", "Species", "Class", "Level", "Max HP", "AC", "STR", "DEX", "CON", "INT", "WIS", "CHA"],
playerPages.map(p => [
p.file.link, p.Species, p.Class, p.level, p.hp, p.ac,
p.Strength, p.Dexterity, p.Constitution, p.Intelligence,
p.Wisdom, p.Charisma
])
);
}
```
## ⏳️ Takeaways
```dataviewjs
const folderPath = "Adventures/Example Adventure/Session Notes";
// Function to extract text between specific headers
const extractTakeaways = (content, startHeader, endHeader) => {
const startPattern = new RegExp(`^#+\\s*${startHeader}\\s*`, "im");
const endPattern = new RegExp(`^#+\\s*${endHeader}\\s*`, "im");
const startMatch = content.match(startPattern);
const endMatch = content.match(endPattern);
if (!startMatch) return null;
const startIndex = startMatch.index + startMatch[0].length;
const endIndex = endMatch ? endMatch.index : content.length;
return content.slice(startIndex, endIndex).replace(/^(#+.*|Notes last touched.*)$/gim, "").trim() || null;
};
// Collect notes, extract takeaways, sort them, and build the table
(async () => {
let tableData = await Promise.all(dv.pages(`"${folderPath}"`)
.map(async page => {
const content = await dv.io.load(page.file.path);
const takeaway = content ? extractTakeaways(content, "Takeaways", "Next Session") : null;
return takeaway ? [page.file.name, takeaway] : null;
}));
// Filter out any null entries
tableData = tableData.filter(row => row !== null);
// Sort the sessions by the session number extracted from the file name (assuming "Session XX - Date" format)
tableData.sort((a, b) => {
const sessionNumberA = parseInt(a[0].match(/Session (\d+)/)?.[1] || 0, 10);
const sessionNumberB = parseInt(b[0].match(/Session (\d+)/)?.[1] || 0, 10);
return sessionNumberB - sessionNumberA; // Sort in descending order
});
// Slice to get the latest 5 entries after sorting
tableData = tableData.slice(0, 5);
if (tableData.length > 0) dv.table(["Note", "Takeaway"], tableData);
})();
```