[[DataView]] is a great plugin but it, like other plugins, will not work with [[Obsidian Publish]]. However, there is a work around. I first found this work around on [this blog](https://joschua.io/posts/2023/09/01/obsidian-publish-dataview/) (there's a helpful expansion on this [published repository](https://obsidianttrpgtutorials.com/Obsidian+TTRPG+Tutorials/Plugin+Tutorials/Dataview/Dataview+-+Obsidian+Publish) as well). I use this technique for my [[book shelf]] and [[literature]] hubs. Because I publish my notes, I try to limit the use of DataView elsewhere, but it's too powerful to be avoided everywhere! For this solution, you will need the community plugins DataView and [[Templater]]. We will create a template that will run [[JavaScript]] code to replace the existing notes with new notes that contain the output of our DataView query. Advanced users may review the Obsidian docs (see especially the section [Vault](https://docs.obsidian.md/Plugins/Vault)) for other ways of interacting with files. > [!Warning] > This process replaces the existing note(s) entirely, so any changes made to the note after running this will be blown away when you re-run it! Let me introduce a simple script here with the main logic before we put it all together. This code first accesses the DataView API, defines a file to overwrite, defines a DataView query, and then writes the result of the query to the specified file. ```javascript // Access DataView plugin API const dv = app.plugins.plugins["dataview"].api; // Define file to be overwritten const filename = "Bookshelf"; const tFile = tp.file.find_tfile(filename); // Define query as normal DataView query const query = ` TABLE WITHOUT ID "![|60](" + cover + ")" as Cover, link(file.link, title) as Title, last-read as "Last Read" FROM "lit/books" WHERE last-read SORT last-read DESC` // Get query results await dv.queryMarkdown(query); // write query output to file await app.vault.modify(tFile, queryOutput.value); ``` > [!Tip] > Get the query working in a simple DataView query in the note first before trying to write the full script in a Templater template. We can extend this code to support multiple queries in multiple files. Note we use `Map()` which creates an ordered dictionary in JavaScript. ```JavaScript // Define all files and queries const fileAndQuery = new Map([ [ "Bookshelf", bookshelf_query ], [ "Literature" literature_query ], ]) await fileAndQuery.forEach(async (query, filename) => { // Create new file if not exists if (!tp.file.find_tfile(filename)) { await tp.file.create_new("", filename); new Notice(`Created ${filename}.`); } // Get file and contents const tFile = tp.file.find_tfile(filename); const queryOutput = await dv.queryMarkdown(query); const fileContent = `%% update via "Update Publish Files" template %% \n\n${queryOutput.value}`; // Update file with query results try { await app.vault.modify(tFile, fileContent); new Notice(`Updated ${tFile.basename}.`); } catch (error) { new Notice("⚠️ ERROR updating! Check console. Skipped file: " + filename , 0); } }); } ``` Finally, we can open the Obsidian Publish panel whenever we run this by appending ```JavaScript app.commands.commands["publish:view-changes"].callback; ``` For my literature hub, I actually need to run multiple queries and I'd like them to be organized under headings. That will require extending this method slightly further. See the [[update publish files]] template for full code.