Make randomized item from a dataview query permanent within a note

Behavior

For this example, I’m making a meal planner. I’m attempting to make a weekly note template that queries my recipes to randomly select one for each meal on a sunday:

I am able to write a query that selects a random recipe. But I cannot make that selection remain. On page reload the query reruns and the selection changes.

Attempt

dv.list(dv.pages('"Health/Nutrition/Recipes"').file.link
	.sort(() => Math.random() - 0.5)
	.limit(1))

Problem

The previous dataviewjs query executes at each reload of the page. I want the query to be run once after the template is applied to a new page so that the recipe for that meal is established and doesn’t change again on page reload.

If you change after to when you’ve solved your problem. The trick is simply to run the query as part of the template, or alternatively to have a dedicated template which executes the query and inserts the result instead of the query itself.

To achieve this there are two changes which needs to be done, and that is to let your template have access to Dataview, and let it return markdown instead of the usual html. Here is a simple example:

<%* 
const dv = this.app.plugins.plugins["dataview"].api

tR += dv.markdownList(dv.pages('"Health/Nutrition/Recipes"')
    .file.link
	.sort(() => Math.random() - 0.5)
	.limit(1))
%>

This is assuming you’re using Templater as your template engine, and not the core template engine.

1 Like

that works great! thanks so much!!

three questions (last two aren’t as important)

  1. I want the same randomly generated recipe link to be displayed in multiple parts of my weekly note (for sunday lunch, for monday lunch, etc). How do I have the randomly generated recipe link appear in multiple areas of the document?
  2. what does “tR” represent? (just for my understanding)
  3. (this is minor, no worries if it’s not possible) the code you’ve provided generates “wikilinks” instead of “markdown links” despite my obsidian settings having a preference for “markdown links”. Is there a way to enforce this preference with the provided code? (justification: my assumption is that it’ll be easier to migrate to another markdown editor if that ever needs to be done. I also find the “markdown links” slightly easier to read)

(how do i persist/reference a randomly generated link)

I can create another post if that’s better practice, let me know

tR is the output of the javascript block, so when you add stuff to it, you’ll output that particular bit. I don’t think you can change the output format of the link, unless you start messing with the text yourself.

To use it in several places in the same template store it in a variable, and then reuse that. Change to something like the following:

<%* 
const dv = this.app.plugins.plugins["dataview"].api

const foodLink = dv.markdownList(dv.pages('"Health/Nutrition/Recipes"')
    .file.link
	.sort(() => Math.random() - 0.5)
	.limit(1))

tR += foodLink
%>

... More of your template ...

<% foodLink %>

PS: As long as you’re just asking closely related followup questions, I think it’s OK to continue the thread. If you’re not the OP and have related or somewhat similar questions, most often it’s better to start a new thread. That is unless the proposed solution doesn’t really answer the question asked.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.