Displaying definitions from a live link

Would it be possible to display this definition live on the flashcard using a link? This is quite easy with an image but how about just that snippet of text which contains the definition?

Say you got a field called Word:

<div id="def"></div>
<script>
(async () => {
  const data = await fetch(
    `https://api.allorigins.win/get?url=${encodeURIComponent(
      "https://www.ldoceonline.com/dictionary/{{Word}}"
    )}`
  ).then((response) => {
    if (response.ok) return response.json();
    throw new Error("Network response was not ok.");
  });
  const dummy = document.createElement("div");
  dummy.innerHTML = data.contents;
  document.getElementById("def").innerText =
    dummy.querySelector(".DEF").innerText;
})();
</script>
4 Likes

Awesome! Thanks! Now I wonder if it would be possible to be able to display just definition 1, or just definition 2. Or to grab the definition for the verb entry of the word instead of the noun entry. I imagine you could put all definitions on there but it’s more complicated if you want just one or two specific definitions.

That’s something you can play around with. You just need to find the right CSS selector. The crucial part is fetching the HTML of the website (which doesn’t offer an API as far as I have seen). The dummy is basically document.documentElement, so you can query it for anything inside the site. You can also use querySelectorAll to get a list of elements and then iterate through that to filter out those definitions that meet your conditions.

For example, I have seen the website creates an <h1 class="pagetitle">word<h1> and then it gives each definition a different id, like word__1, word__2 and so on.

You can use that to select appropriate definitions:

(async () => {
  const data = await fetch(
    `https://api.allorigins.win/get?url=${encodeURIComponent(
      "https://www.ldoceonline.com/dictionary/{{Word}}"
    )}`
  ).then((response) => {
    if (response.ok) return response.json();
    throw new Error("Network response was not ok.");
  });
  const dummy = document.createElement("div");
  dummy.innerHTML = data.contents;
  const title = dummy.querySelector("h1.pagetitle").innerText.toLowerCase().replace(/\s/, "-");

  document.getElementById("def").innerHTML = Array.from(
    dummy.querySelectorAll(`.Sense[id^='${title}__'] > .DEF`),
    (el) => `<div class="definition">${el.innerText}</div>`
  ).join("");
})();

For a definition at a specific index, just replace .Sense[id^='${title}__'] in the selector with .Sense#${title}__2 (for example).

You can of yourse use a for loop to do more stuff with these definitions.

3 Likes

This is not the first time I see this kind of requests, and it’s actually pretty simple to do if you know how to load pages with JS, or you if know iframes; besides, I think it would be actually better to download once the wanted part of the page and add it to the note, instead of having a live preview, since that makes it offline compatible, faster (if you have a slow connection) and more reliable (if the page changes its url scheme, for example), so I was wondering if it wasn’t worth turning this functionality into an add-on: in the card template, you could tell I want this section of this page to be added to the card, depending on the value of these fields, and at the moment of the note creation, that is replaced with the actual content of the page, downloaded once.

Not all sites allow to be embedded in iframes tough, and even if they do, you cannot access the content directly due to Same-origin policy - Web security | MDN.

I see two advantages of fetching pages during review:

  • no storage cost
  • dictionaries and other databases are continually updated and you always get the most current version (offline data that cannot be updated triggers serious OCD for me haha)