```` ## {{Player Name}} ```dataviewjs const character = dv.page("People/Player Characters/Active/Player 1"); if (character) { const species = character.Species || "N/A"; const className = character.Class || "N/A"; const subclass = character.Subclass || "N/A"; const hpMax = character.hp || "N/A"; const hpCurrent = character.current_hp || "N/A"; const skillProfs = character["Skill Proficiencies"] || []; const stProfs = character["ST Proficiencies"] || []; const proficiencyBonus = Number(character["Proficiency Bonus"]) || 0; const wisdom = character.wisdom || 10; // default to 10 if not found, for safety const combinedProfs = [...skillProfs, ...stProfs]; const keyItems = character["key_items"] || []; const spells = character.spells || []; // Helper function to extract the display name from a link const getDisplayName = (link) => { if (typeof link === "string" && link.includes("|")) { return link.split("|")[1].replace("]]", "").trim(); } if (typeof link === "object" && link.path) { return link.path.split("/").pop().replace(".md", "").trim(); } return link.toString().trim(); // Fallback in case it's a plain string }; // Extract display names for Species, Class, and Subclass const speciesName = getDisplayName(species); const classNameDisplay = getDisplayName(className); const subclassName = getDisplayName(subclass); // Preprocess the links const speciesLink = species && species.path ? `<a href="${species.path}" class="internal-link">${speciesName}</a>` : speciesName; const classLink = className && className.path ? `<a href="${className.path}" class="internal-link">${classNameDisplay}</a>` : classNameDisplay; const subclassLink = subclass && subclass.path ? `<a href="${subclass.path}" class="internal-link">${subclassName}</a>` : subclassName; // Create an object to hold table data const infoTableData = { species: speciesLink, class: classLink, subclass: subclassLink, proficiencies: combinedProfs.join(", ") || "None", stproficiencies: stProfs.join(", ") || "None" }; // Build the table including the new Passive Perception column const infoTable = ` <table style="width: 100%; border-collapse: collapse;"> <thead> <tr> <th style="border: 1px solid #ccc; padding: 5px;">Species</th> <th style="border: 1px solid #ccc; padding: 5px;">Class</th> <th style="border: 1px solid #ccc; padding: 5px;">Subclass</th> <th style="border: 1px solid #ccc; padding: 5px;">Proficiencies</th> <th style="border: 1px solid #ccc; padding: 5px;">Saving Throws</th> </tr> </thead> <tbody> <tr> <td style="border: 1px solid #ccc; padding: 5px;">${infoTableData.species}</td> <td style="border: 1px solid #ccc; padding: 5px;">${infoTableData.class}</td> <td style="border: 1px solid #ccc; padding: 5px;">${infoTableData.subclass}</td> <td style="border: 1px solid #ccc; padding: 5px;">${infoTableData.proficiencies}</td> <td style="border: 1px solid #ccc; padding: 5px;">${infoTableData.stproficiencies}</td> </tr> </tbody> </table> `; dv.el("div", "").innerHTML = infoTable; // Key Items if (keyItems.length > 0) { const keyItemsFormatted = keyItems.map(item => { // If item is an object with a path, it's a link if (typeof item === 'object' && item.path) { const itemName = item.path.split('/').pop().replace('.md', ''); return `<a href="/${item.path}" class="internal-link">${itemName}</a>`; } // If item is a string and contains a wiki-link pattern [[...]] if (typeof item === 'string' && item.includes('[[') && item.includes(']]')) { // Extract the inner part of the link: [[something]] or [[something|display]] const inner = item.replace(/\[\[|\]\]/g, ''); let [itemPath, itemName] = inner.split('|'); if (!itemName) itemName = itemPath; // If no display name, use the path itself return `<a href="/${itemPath}" class="internal-link">${itemName.trim()}</a>`; } // Otherwise, just return the plain text item return item.toString(); }); dv.el("div", "").innerHTML = `<p><strong>Key Items:</strong> ${keyItemsFormatted.join(", ")}</p>`; } else { dv.el("div", "").innerHTML = `<p><strong>Key Items:</strong> None</p>`; } dv.el("hr", ""); // Spells if (spells.length > 0) { const spellTableData = spells.map(spell => { const spellPage = dv.page(spell.path); let spellName = spellPage ? spellPage.file.name.replace(".md", "") : spell.path; if (typeof spell === 'string' && spell.includes('|')) { const splitSpell = spell.split('|'); spellName = splitSpell[1].replace(']]', ''); } const spellLink = `<a href="/Compendium/Spells/${spellName}.md" class="internal-link">${spellName}</a>`; return { name: spellLink, level: spellPage ? spellPage.level : "N/A", casting_time: spellPage ? spellPage.casting_time : "N/A", range: spellPage ? spellPage.range : "N/A", save: spellPage?.save?.trim() || "-" }; }).sort((a, b) => a.level - b.level); const spellTable = ` <h3>Spells</h3> <table style="width: 100%; border-collapse: collapse;"> <thead> <tr> <th style="border: 1px solid #ccc; padding: 5px;">Spell</th> <th style="border: 1px solid #ccc; padding: 5px;">Level</th> <th style="border: 1px solid #ccc; padding: 5px;">Casting Time</th> <th style="border: 1px solid #ccc; padding: 5px;">Range</th> <th style="border: 1px solid #ccc; padding: 5px;">Saving Throw</th> </tr> </thead> <tbody> ${spellTableData.map(spell => ` <tr> <td style="border: 1px solid #ccc; padding: 5px;">${spell.name}</td> <td style="border: 1px solid #ccc; padding: 5px;">${spell.level}</td> <td style="border: 1px solid #ccc; padding: 5px;">${spell.casting_time}</td> <td style="border: 1px solid #ccc; padding: 5px;">${spell.range}</td> <td style="border: 1px solid #ccc; padding: 5px;">${spell.save}</td> </tr> `).join("")} </tbody> </table> `; dv.el("div", "").innerHTML = spellTable; } else { dv.el("div", "").innerHTML = ``; } } ```