> [!column|flex no-title] >> [!menu-dark-red|ttl-c] [[Obsidian TTRPG Tutorials]] / [[Plugin Tutorials]] / [[Dataview]] / [[Dataview - Obsidian Publish]] > [!column|4 no-title] >> [!menu-green-1|ttl-c] [[Getting Started]] > >> [!menu-green-2|ttl-c] [[Plugin Tutorials]] > >> [!menu-green-3|ttl-c] [[Community Supported Games]] > >> [!menu-green-4|ttl-c] [[Obsidian TTRPG Tutorials/Templates/Templates\|Templates]] > [!column|3 no-title] >> [!patreon|ttl-c] [Patreon](https://www.patreon.com/JPlunkett) ([Starter Vault](https://www.patreon.com/posts/obsidian-patreon-96801399)) > >> [!discord|ttl-c] [Obsidian TTRPG Community Discord](https://discord.gg/CdM9UCJdwU) > >> [!discord|ttl-c] [Obsidian Official Discord](https://discord.gg/8AF29UBUCa) Obsidian Publish is almost amazing. It's a fantastic cheap way to publish your notes for your players. There is a problem though... it does not support plugins 🫤 This is particularly problematic with Dataview, because Dataview is amazing and lots of us use it, but Dataview notes simply do not work in Publish sites which leaves your page with an ugly chunk of code instead of the table you see when using Obsidian natively. Well that issue has now been solved by [Joschua](https://joschua.io/blog/). He's made a fantastic tutorial that steps through the process over at his blog: [Dataview Plugin on Obsidian Publish](https://joschua.io/posts/2023/09/01/obsidian-publish-dataview/) I highly recommend you take the time to read through his tutorial as I don't do it justice. ![](https://youtu.be/c440B2aOPJ8) ### Normal Dataview Queries in Publish This is what a Dataview Query normally looks like when published. ```dataview TABLE WITHOUT ID link(file.name) AS "Character Name", Player, Class, Race, level, Role from "1. The Party/Deadly Depth Inn" where (Role = "Player") where (Status = "Active") ``` ### Dataview Query Using This Process This is what the same Dataview Query looks like when Published using [this process](https://joschua.io/posts/2023/09/01/obsidian-publish-dataview/). ![[Player List]] ### Required Plugins For this process to work you will need the following plugins installed: - [Dataview](obsidian://show-plugin?id=dataview) - [Templater](obsidian://show-plugin?id=templater-obsidian) - Make sure you set a hotkey for: `Templater: Open Insert Template Model` - Make sure you set the Template Folder Location in the [Templater](obsidian://show-plugin?id=templater-obsidian) settings. - [Editor Syntax Highlight](obsidian://show-plugin?id=cm-editor-syntax-highlight-obsidian) - Optional: Handy for working with code/syntax in Obsidian. ### The Publish Template At a very high level, we are basically going to create a Template that is triggered with [Templater](obsidian://show-plugin?id=templater-obsidian) (not to be confused with the Core Template Plugin, that will not work in this situation). That template is going to create/override some notes that will exist specifically to house the dataview table. The query will initially create the dataview query in these notes; but then replace the results of the query with a Markdown version of the table. It then triggers the Publish process and publishes the notes. Every time you publish in this way, the query is re-created, and thus refreshed, before being replaced with a new Markdown table that contains the latest results. Create a new note in your Template Folder. I have named my template: `Update Publish Files` Copy the code below into this note. ```` <%* const dv = app.plugins.plugins["dataview"].api; const openPublishPanel = app.commands.commands["publish:view-changes"].callback; // Add as many filenames and queries as you'd like! const fileAndQuery = new Map([ [ "Recently edited", 'TABLE WITHOUT ID file.link AS Note, dateformat(file.mtime, "ff") AS Modified FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.mtime desc LIMIT 7', ], [ "Recent new files", 'TABLE WITHOUT ID file.link AS Note, dateformat(file.ctime, "DD") AS Added FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.ctime desc LIMIT 7', ], ]); await fileAndQuery.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `%% #Ignore update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); openPublishPanel(); %> ```` Next you need to modify this note to meet your own personal requirements. #### Recently Edited This section of the code will create a note that displays a table with 7x most recently modified notes. This is great so people can see any changes that have been made to your site. ```` [ "Recently edited", 'TABLE WITHOUT ID file.link AS Note, dateformat(file.mtime, "ff") AS Modified FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.mtime desc LIMIT 7', ], ```` Breaking this down. `Recently edited` - this is the name of the note. The next section is the Dataview query. `TABLE WITHOUT ID file.link AS Note, dateformat(file.mtime, "ff") AS Modified FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.mtime desc LIMIT 7` To make this work for your own vault you need to update the FROM statement to match the folder that you are publishing. `FROM "Obsidian TTRPG Tutorials"` The `-#Ignore` is used to ensure that the `Recent new files` and `Recently edited` notes will not be included in the results of the Dataview queries. Since they will always be edited with each Publish, there is not reason to include them in the results. To help you visualise this. This is what the query would look like as a normal Dataview query in your note. ```` ```dataview TABLE WITHOUT ID file.link AS Note, dateformat(file.mtime, "ff") AS Modified FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.mtime desc LIMIT 7 ``` ```` #### Recent New Files This section of the code will create a note that displays a table with 7x most recently created notes. This is great so people can see any new notes that have been added to your site. ```` [ "Recent new files", 'TABLE WITHOUT ID file.link AS Note, dateformat(file.ctime, "DD") AS Added FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.ctime desc LIMIT 7', ], ```` Breaking this down. `Recent new files` - this is the name of the note. You can change this if you like. The next section is the Dataview query. `TABLE WITHOUT ID file.link AS Note, dateformat(file.ctime, "DD") AS Added FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.ctime desc LIMIT 7` To make this work for your own vault you need to update the FROM statement to match the folder that you are publishing. `FROM "Obsidian TTRPG Tutorials"` The `-#Ignore` is used to ensure that the `Recent new files` and `Recently edited` notes will not be included in the results of the Dataview queries. Since they will always be edited with each Publish, there is not reason to include them in the results. To help you visualise this. This is what the query would look like as a normal Dataview query in your note. ```` ```dataview TABLE WITHOUT ID file.link AS Note, dateformat(file.ctime, "DD") AS Added FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.ctime desc LIMIT 7 ``` ```` #### Player List Example Here is the example I used in the video tutorial. This is a specific example designed to work with the Player Notes in my vault. ```` [ "Player List", 'TABLE WITHOUT ID link(file.name) AS "Character Name", Player, Class, Race, level, Role from "1. The Party/Deadly Depth Inn" where (Role = "Player") where (Status = "Active")', ], ```` Here is what the Template would look like with this code added. ```` <%* const dv = app.plugins.plugins["dataview"].api; const openPublishPanel = app.commands.commands["publish:view-changes"].callback; // Add as many filenames and queries as you'd like! const fileAndQuery = new Map([ [ "Recently edited", 'TABLE WITHOUT ID file.link AS Note, dateformat(file.mtime, "ff") AS Modified FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.mtime desc LIMIT 7', ], [ "Player List", 'TABLE WITHOUT ID link(file.name) AS "Character Name", Player, Class, Race, level, Role from "1. The Party/Deadly Depth Inn" where (Role = "Player") where (Status = "Active")', ], [ "Recent new files", 'TABLE WITHOUT ID file.link AS Note, dateformat(file.ctime, "DD") AS Added FROM "Obsidian TTRPG Tutorials" AND -#Ignore WHERE publish = true SORT file.ctime desc LIMIT 7', ], ]); await fileAndQuery.forEach(async (query, filename) => { if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename); new Notice(`Created ${filename}.`); } const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `%% #Ignore update via "Update Publish Files" template %% \n\n${queryOutput.value}`; try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); openPublishPanel(); %> ````