Is putting the actual quotes into the metadata a reasonable approach to building a database of quotes?

I am new to dataview, and I am just trying to build a database of quotes.

Since I would like the entire text of the actual quote to be displayed in my dataview queries, I simply put the quote directly into the front matter, under the property “quote-text”. (I use a css snippet to get it to wrap.)

It works fine, with the 60 or so quotes I have put in so far.

My question is:

Is having hundreds and hundreds of empty notes with quotes in their metadata a reasonable approach?

Can it be scaled up performantly, to say, a few thousand quotes? Does having rather big values in fields bog down dataview?

Am I right in assuming that there is no way to do this with the text in the actual note, rather than the metadata, since dataview can only read frontmatter, inline fields and, apparently, also lists?

Is there a better way?

How would you do this?

(Pictures show a query, and the template I use. I have ratings as a list properties, in case I should want to include other people’s ratings in the future.)

Why not use inline fields? That’s what I do with mine, including the quote within my journals. This allows me to go back to the journal and see the quote in context (surrounding text might be related).
>Quote:: I sleep like a baby. I wake up screaming every morning around 3am. -- Tommy Cooper

I already have quite a few properties (and planning to add at least one more), that I want to use for searching, and that I want to create consistently, by using a template.

I would develop the system in such a way that a note could hold multiple quotes and it would still work. I personally have a lot of types of structured data that work in this way, and it’s a good trade-off generally, if you don’t mind a lot of yaml

sounds intriguing; could you elaborate?

I don’t know how I would go about creating yaml of this type, since I thought having the text in the metadata is the only way to display it in my queries.

Do your queries display the quotes?
Or is that not so important to you, or maybe you do it some other way, like by control hovering over a link?

here’s an example piece of yaml from my file on the film “Casablanca”:

  - name: Michael Curtiz
    role: director
  - name: Humphrey Bogart
    character: Rick Blaine
    role: actor
  - name: Ingrid Bergman
    character: Ilsa Lund
    role: actor
  - name: Paul Henried
    character: Victor Laszlo
    role: actor
  - name: Claude Rains
    character: Captain Louis Renault
    role: actor
  - name: Conrad Veidt
    character: Major Heinrich Strasser
    role: actor
  - name: Sydney Greenstreet
    character: Signor Ferrari
    role: actor
  - name: Peter Lorre
    character: Ugarte
    role: actor
  - name: Dooley Wilson
    character: Sam
    role: actor
  - name: Julius J. Epstein
    role: writer
  - name: Philip G. Epstein
    role: writer
  - name: Howard Koch
    role: writer
  - name: Murray Burnett
    role: source writer
  - name: Joan Alison
    role: source writer
  - name: Jack L. Warner
    role: executive producer
  - name: Arthur Edeson
    role: cinematographer
  - name: Max Steiner
    role: composer
  - name: Owen Marks
    role: film editor gives me a list of everyone who worked on it.

Meanwhile I have a [[Humphrey Bogart]] file with this in it:

TABLE Q.role as role
FROM #media
WHERE contains(,
WHERE contains(,

Which gives me a table of films he worked on and his role.
With this example you may be able to adapt the concepts to your use case.

Maybe you collect quotes by the same person in the same file, or you include the author in the metadata and collect quotes by month or arbitrarily…
Of course nothing stops you from doing a file per quote but it isn’t the only way.

thank you so much!
(will have to study this for a while, since I’m new to this)

1 Like

I wanted to put my take on this question, and that is in general I tend not to use the frontmatter for any of the “vital” data present in that note. Or put another way, I wouldn’t place the quote within the frontmatter if that’s the crucial part. I would only put actual metadata related to the quote in the frontmatter.

Along the same kind of reasoning, I’m placing my quotes in tasks throughout the documents, and if need be I can pull out any relevant metadata from the frontmatter. So given an example of some random book, I could possibly have a note like:

type: book
title: "My glorious book"
author: myself

Something about the book

- [q] I'm quoting myself

... more text ...

- [q] Another genius quote

Which with a little styling looks like:

And some various ways to extract these quotes:

## Pure quotes
WHERE file.folder = this.file.folder
  AND status = "q"

## Grouped by file with author
WHERE file.folder = this.file.folder
FLATTEN text + " (" + author + ")" as visual

## Quotes with links added to the text
WHERE file.folder = this.file.folder
  AND status = "q"
FLATTEN text + ", " + as visual

Which in my rather simple setup displays as:

Do note that the last example is kind of superfluous, since by nature all task queries link back to their origin, which is an advantage in my book.

The FLATTEN ... as visual trick can also be used to remove any inline fields defined in the task if one chooses that approach to add extra information to a particular quote without needing to display those fields. My train of thoughts is that in most cases, the metadata on the note is adequate for the quote in itself, but you could specify some extra if need be.

In summary I like this style of defining the quotes since it looks nice in the context where I define them, and it allows for easy retrieval in queries. And through the use of FLATTEN ... as visual I can change the output of the task to whatever I’d like and still keep the link back to where it was written. This can also be used to remove inline fields, if one wanted to use that for extra information related to the quotes.


As always, very useful @holroy! I think I may switch mine up to use your method, it is prettier, easier to remember, and works as well if not better!

Using the method @holroy suggested works great in my setup, but I have one thing missing. When I used quote:: to mark my quotes, I was then able to use the following dataviewjs code to randomly select a quote that I would include at the bottom of each note:

let quotes = [];
	.where(page => page.quote)
	.forEach(page => {
			.forEach(quote => {
					message: quote,
					page: page

let greeting = quotes[Math.floor(Math.random()*quotes.length)]
dv.span('> [!quote]'+'\n'+greeting.message + "\n" +

Now that my quotes are custom tasks using - [q] , I haven’t been able to figure out how to do the same thing (a random quote including a link to the page it came from). Any suggestions on how I could replicate that?

Hello holroy

I tried applying your suggestion to my situation (collating records of lessons I’ve learned through the day in my journal) but fell over at the first step. When I tried to apply your sample book entry, mine show as completed tasks (see photos). Is there something I need to do to fix that. Thanks Gen

PS I am using it on Android Mobile version, of that makes any difference.

You can change the checkbox to look like something different, for example, the quotation symbol holroy showed in his examples (which is what I did with mine). Here’s a post that talks about how to do that, and of course the important parts are thanks to holroy:
Alternative Checkboxes (Icon Bullets) - Copy and paste - Share & showcase - Obsidian Forum

Thanks, @jpfieber! I’ll look into it.

Here is something to get you started:


let quotes = dv.pages()
  .where(t => t.status == "q")

dv.taskList( dv.array(quotes.values[Math.floor(Math.random()*quotes.values.length)]), false)

And related to the CSS needed something like the following should do the trick for the [q] styling:

li[data-task="q"] > input:checked,
li[data-task="q"] > p > input:checked {
  --checkbox-marker-color: transparent;
  border: none;
  border-radius: 0;
  background-image: none;
  background-color: currentColor;
  pointer-events: none;
  -webkit-mask-size: var(--checkbox-icon);
  -webkit-mask-position: 50% 50%;

/* q - quote, remixicon: double-quotes-l */ 
li[data-task="q"] > input:checked,
li[data-task="q"] > p > input:checked {
  color: var(--text-faint);
  margin-left: -48px;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='M4.583 17.321C3.553 16.227 3 15 3 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311 1.804.167 3.226 1.648 3.226 3.489a3.5 3.5 0 0 1-3.5 3.5c-1.073 0-2.099-.49-2.748-1.179zm10 0C13.553 16.227 13 15 13 13.011c0-3.5 2.457-6.637 6.03-8.188l.893 1.378c-3.335 1.804-3.987 4.145-4.247 5.621.537-.278 1.24-.375 1.929-.311 1.804.167 3.226 1.648 3.226 3.489a3.5 3.5 0 0 1-3.5 3.5c-1.073 0-2.099-.49-2.748-1.179z'/%3E%3C/svg%3E");
Bonus tip: How to add a custom CSS snippet
  • Goto Settings > Appearance and scroll down to “CSS snippets” section, and hit the folder icon on the far right. This opens up a file explorer window, in the folder vault/.obsidian/snippets, which is were you want to save your css snippet
  • In this new window create a file, like myCss.css, where you copy the CSS into. Make sure this actually is a text file, and that the name ends in .css
  • Back in Obsidian, you should now see your myCss in the list of CSS snippets. If not, hit the refresh button
  • Final step is to click the enable button to the right of your file, and now your new CSS should be in effect
  • If you later on make changes in the CSS snippet file, the effect should be immediate. If not, try disabling and re-enabling the snippet, or in some strange cases, you would need to reload Obsidian. In 99% of the cases, the changes are immediate, though.
1 Like

Ah, wow!

This definitely seems like the more natural way to go about this.
Avoids this creation of endless open notes.

(So nice of you to supply this in depth desciption of the exact solution to what I was wondering about, sorry it took me so long to check back.)

Thanks, got it working! Here’s what I settled on:

let quotes = dv.pages()
  .where(t => t.status == "q")
thequote = quotes.values[Math.floor(Math.random()*quotes.values.length)]
dv.el("div",'<span class="emoji">❝</span>[' + thequote.text + '](' + thequote.path + ')\n',{cls:"quote"})

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