What a simple table that pulls information from YAML looks like:

```dataviewjs
const container = this.container;

const allPages = dv.pages('"2. Areas/Сериалы и фильмы/7. Сериалы"')
    .where(p => p.Жанр && p.Рейтинг)
    .sort(p => -Number(p.Рейтинг));

// --- UI block: Filter + Search ---
const controls = document.createElement("div");
controls.style.display = "flex";
controls.style.gap = "1rem";
controls.style.marginBottom = "1rem";

// Filter by genres
const genres = [...new Set(allPages.flatMap(p => Array.isArray(p.Жанр) ? p.Жанр : [p.Жанр]))];
const genreSelect = document.createElement("select");

const allOption = document.createElement("option");
allOption.value = "all";
allOption.textContent = "All genres";
genreSelect.appendChild(allOption);

for (let genre of genres.sort()) {
  const option = document.createElement("option");
  option.value = genre;
  option.textContent = genre;
  genreSelect.appendChild(option);
}
controls.appendChild(genreSelect);

// Search field
const searchInput = document.createElement("input");
searchInput.type = "text";
searchInput.placeholder = "🔍 Search by title...";
searchInput.style.flex = "1";
controls.appendChild(searchInput);

container.appendChild(controls);

// --- Table ---
const table = document.createElement("table");
table.className = "dataview table-view-table";

const header = table.insertRow();
["🎬 Cover", "🎞 Title", "🎭 Genre", "⭐ Rating", "🧠 Insight"].forEach(text => {
  const th = document.createElement("th");
  th.textContent = text;
  header.appendChild(th);
});

function renderTable(filterGenre = "all", searchTerm = "") {
  table.querySelectorAll("tr:not(:first-child)").forEach(row => row.remove());

  const filteredPages = allPages.filter(p => {
    const genreMatch = filterGenre === "all" || (Array.isArray(p.Жанр) ? p.Жанр.includes(filterGenre) : p.Жанр === filterGenre);
    const searchMatch = !searchTerm || p.file.name.toLowerCase().includes(searchTerm.toLowerCase());
    return genreMatch && searchMatch;
  });

  for (let p of filteredPages) {
    const row = table.insertRow();

    const cellCover = row.insertCell();
    cellCover.innerHTML = p.Постер
      ? `<img src="${p.Постер}" width="100" style="border-radius: 8px;">`
      : "—";

    const cellTitle = row.insertCell();
    const link = document.createElement("a");
    link.href = p.file.path;
    link.textContent = p.file.name;
    link.className = "internal-link";
    cellTitle.appendChild(link);

    const cellGenre = row.insertCell();
    cellGenre.textContent = Array.isArray(p.Жанр) ? p.Жанр.join(", ") : p.Жанр;

    const cellRating = row.insertCell();
    cellRating.textContent = p.Рейтинг + "/10";

    const cellInsight = row.insertCell();
    cellInsight.textContent = p.Инсайт || "–";
  }
}

// --- Listeners ---
genreSelect.onchange = () => renderTable(genreSelect.value, searchInput.value);
searchInput.oninput = () => renderTable(genreSelect.value, searchInput.value);

// First render
renderTable();
container.appendChild(table);```

const allPages = dv.pages(‘“2. Areas/Сериалы и фильмы/7. Сериалы”’) — replace with your own path where your notes with YAML are stored Move the last three apostrophe characters to a new line


🧠 An explanation for those who want to understand this code more deeply:

📁 1. Loading the notes from the right folder

const allPages = dv.pages('"2. Areas/Сериалы и фильмы/7. Сериалы"')
    .where(p => p.Жанр && p.Рейтинг)
    .sort(p => -Number(p.Рейтинг));
  • Here all the notes from the “Shows” folder are loaded.

  • Only those that have Жанр (Genre) and Рейтинг (Rating) are selected.

  • Sorted by descending rating — the top ones are at the top.

📌 Replace the path with your own folder if your structure is different.


const genres = [...new Set(allPages.flatMap(...))];
  • All the unique genres are gathered (e.g.: Drama, Comedy, Anime).

  • A dropdown list is created — you can filter only “Sci-Fi” or only “Anime”.

searchInput.placeholder = "🔍 Search by title...";
  • The search field filters by the note name (usually that’s the show’s title).

  • It works in real time — convenient!


📋 3. The table: what each row looks like

["🎬 Cover", "🎞 Title", "🎭 Genre", "⭐ Rating", "🧠 Insight"]

Each row is one show, where the following is displayed:

ColumnWhat it shows
🎬 CoverThe image from the Постер (Poster) field (if any)
🎞 TitleThe show’s title, as a link to the note
🎭 GenreOne or several genres
⭐ RatingA score on a 10-point scale (Рейтинг)
🧠 InsightYour thought, takeaway or quote from the show

🧠 4. Filtering and rendering

function renderTable(filterGenre = "all", searchTerm = "") { ... }
  • Removes the old table rows and redraws only those that match the selected genre or the entered text.

  • This makes the table live: it reacts to the user’s actions.


🔁 5. Event listeners

genreSelect.onchange = () => renderTable(...)
searchInput.oninput = () => renderTable(...)
  • When you change the genre or type into the search — the table updates.

  • It all happens live, without a reload.


✅ What you need in YAML

For this code to work, make sure these fields are specified in your show notes:

Постер: https://link-to-image.jpg
Жанр: [Sci-Fi, Drama]
Рейтинг: 8.7
Инсайт: An inspiring look at the technology of the future.

🔥 The result

You get a cool catalogue:

  • everything is nicely styled;

  • you can filter by mood (genre);

  • you can quickly find and rewatch;

  • you can share it with friends or subscribers.