Refresh and toggle dataview/source

As some of you know I’m answering some posts in this forum related to dataview and dataviewjs queries. In this regard, I’ve been wanting to have a way to refresh the queries (if dataview decides not to do so itself), and I’ve also been playing around with wanting syntax highlight for both dataview query types.

With the help of buttons and templater I found a rather nifty setup which achieves both goals for me.

When I now write a response requiring either query type I insert the appropriate template from a hotkey, type in the line number of the starting line with the ```dataview, and start developing the query. If I now switch to either live preview or reading view I’ve got two buttons, which switches between either dataview and sql, or dataviewjs and javascript.

In reading view, this looks like the following just after insertion of the template, and insertion of line number 118 (using a multi cursor input):

Which in reading view looks like:

And now I can press either button to switch mode, or hit the To dataview again to force a refresh.

Template for DQL query
```button
name To SQL
type line(<% tp.file.cursor(1) %>) text
replace [<% tp.file.cursor(1) %>,<% tp.file.cursor(1) %>]
action ```sql
```
```button
name To dataview
type line(<% tp.file.cursor(1) %>) text
action ```dataview
replace [<% tp.file.cursor(1) %>,<% tp.file.cursor(1) %>]
```
```sql
<%*
  const queryType = await tp.system.suggester(t => t, ["list", "taskList", "table", "calendar"], "Query type")
  console.log(queryType)
  if ( queryType == "list" ) 
    tR += "LIST\n" + tp.file.cursor(2)
  else if ( queryType == "taskList" )
    tR += "TASK\n" + tp.file.cursor(2)
  else if ( queryType == "table" ) 
    tR += "TABLE " + tp.file.cursor(2) + "\n"
  else if ( queryType == "calendar" )
    tR += "CALENDAR\n" + tp.file.cursor(2)
  tR += "\nWHERE file.folder = this.file.folder AND file.name != this.file.name"
%>
```

I’ve attached some stuff I’m usually enter to keep my test script within the current folder, and excluding the summary note for that question. That part could (and should) of course be edited according to your liking.

Template for DataviewJS query
```button
name To javascript
type line(<% tp.file.cursor(1) %>) text
replace [<% tp.file.cursor(1) %>,<% tp.file.cursor(1) %>]
action ```javascript
```
```button
name To dataviewjs
type line(<% tp.file.cursor(1) %>) text
action ```dataviewjs
replace [<% tp.file.cursor(1) %>,<% tp.file.cursor(1) %>]
```
```javascript
const result = await dv.query(`
<% tp.file.cursor(2) %>
`)

if ( result.successful ) {
  const values = result.value.values
  <% tp.file.cursor(3) %>
<%*
  const queryType = await tp.system.suggester(t => t, ["list", "taskList", "table"], "Query type")
  console.log(queryType)
  if ( queryType == "list" ) 
    tR += "  dv.list(values)"
  else if ( queryType == "taskList" )
    tR += "  dv.taskList(values, false)"
  else if ( queryType == "table" ) 
    tR += "  dv.table(result.value.headers, result.value.values)"
%>
} else
  dv.paragraph("~~~~\n" + result.error + "\n~~~~")
```

I often find myself using DQL queries inside of a dataviewjs query, so therefore my template for this incorporates this, and also sets up the correct variation for including a little bit of error handling.

CSS to float buttons to the right
div:has(>.block-language-button) {
  display: inline-block;
  float: right;
}

div:has(>.block-language-button)+div.HyperMD-codeblock,
div:has(>.block-language-button)+div:has(.language-javascript), 
div:has(>.block-language-button)+div:has(.language-sql),
div:has(>.block-language-button)+div:has(.node-insert-event) {
  clear: both;
}

The following needs to be copied to a snippet inside vault/.obsidian/snippet, and enabled under Settings > Appearance (CSS snippets).

Note that it looks very nice in reading view, whilst in live preview it is kind of centered due to some strangeness related to widths of surrounding divs. I tried just a little to also make it nice there, and failed. I’m usually in either reading view or source mode, but these buttons do work also in live preview, they just don’t look that pretty.

A few notes on setup

The two first templates needs to be installed into your template folder, and I’ve named them dvQuery.md and dvjsResultQuery.md. To assign hotkeys do the following:

  • Go to Settings > Templater (Template Hotkeys)
  • Hit the “Add new hotkey for template” (twice)
  • Add the two templates into corresponding boxes
  • Hit the plus icon after either box. You’ll now see the Settings > Hotkeys configuration with the Templater insert commands focused
  • Select the plus icon next to either template, and hit a hotkey of your choice. I’ve opted for Cmd Ctrl s and Ctrl Cmd Shift S. Make sure the hotkeys are not used already by hovering over the key combination, and see that no error messages shows.

After installing the template, and the CSS snippets if you opt for that, you’re good to go after turning on line numbers at Settings > Editor > Show line number.


Caveat: This solution relies on changing the first line of the code block containing the queries, and it requires the correct line number. This also means that if you change text preceeding the code block, you need to update the line number in all six places in the button code. Otherwise it’ll happy replace another line of your code. You can undo to get back the line, but be forewarned.

Here is another screenshot from a recent answer, where I had both DQL queries and dataviewjs queries. The first shows the result, and the second is currently showing the source code nicely colored (which can be a great help to locate minor errors like missing quotes and braces and so on).