# Find and embed all slides (or headings + text) that have the same tag

**URL:** <https://forum.obsidian.md/t/find-and-embed-all-slides-or-headings-text-that-have-the-same-tag/104742>\
**Category:** Help\
**Tags:** tags, search, slides\
**Created:** [August 26, 2025, 3:14am UTC](https://forum.obsidian.md/t/find-and-embed-all-slides-or-headings-text-that-have-the-same-tag/104742 "2025-08-26T03:14:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![royalbruxa](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/r/9de0a6/32.png) [@royalbruxa](https://forum.obsidian.md/u/royalbruxa)\
**Post date:** [August 26, 2025, 3:14am UTC](https://forum.obsidian.md/t/find-and-embed-all-slides-or-headings-text-that-have-the-same-tag/104742/1 "2025-08-26T03:14:54Z")

</div>

### Problem setup

I have a [master set of slides in a note.](https://forum.obsidian.md/uploads/short-url/uJoherWXzx6lcKLYze2KXUwmlnh.md) Each slide needs to be presented to one of three audiences:

- Only Group 1,
- Only Group 2,
- Groups 1 & 2, or
- No group.

I am using tags in every slide to keep track of the assigned groups: `group1` `group2` etc.

### What I’m trying to do

I want to

- Create a new note where only `#group1` slides are embedded such that:
  - If I add/edit slides to the master set, they are reflected automatically in the child note.
  - The slides in the child note are in the same order as in the master set
  - The child note must be presentable ie I can click ‘Start presentation’ and present from it.

- Repeat the above for `#group2` only and a third note for both groups.
- Extend the search to all notes in the vault.

### Things I have tried

- Obsidian `query` feature does not embed an entire slide.
- Dataview cannot retrieve Headings + Text which a slide contains.
- The extension [Tagtracker](https://github.com/dosakkhayo/obsidian-tagtracker?tab=readme-ov-file) is tangential to my need - it finds all **notes** containing the search tag, not sections/slides. Additionally, it embeds the slides as one giant embed which cannot be presented a slide at a time.

I believe this may require some JS magic but that’s not my forte. Any help would be magnificent. Thank you!

---

<div class="post-metadata">

**Author:** ![JLDiaz](https://forum.obsidian.md/user_avatar/forum.obsidian.md/jldiaz/32/82411_2.png) [@JLDiaz](https://forum.obsidian.md/u/JLDiaz)\
**Post date:** [August 26, 2025, 11:31am UTC](https://forum.obsidian.md/t/find-and-embed-all-slides-or-headings-text-that-have-the-same-tag/104742/2 "2025-08-26T11:31:45Z")

</div>

Here’s why your initial attempts fell short, and how you can get around them:

- **Standard queries won’t work:** Obsidian’s native `query` and even standard `Dataview` can retrieve entire notes or list items, but they cannot process a note’s content at the level of individual “slides” separated by `---`. To do that, we have to access the note as a full string and process it with JavaScript.
- **Embeds are not the answer:** You’re also right that using embeds (`![[...]]`) will not work for a live presentation. The Obsidian presentation plugin relies on the `---` separator to treat each section as a separate slide. Embeds are simply displayed as a single block of content and are not recognized as individual slides.

The best solution is to use **DataviewJS** to generate a brand new note for each group presentation. This note will have the correct format and will be fully presentable. The only trade-off is that this isn’t a “live” solution—you’ll need to re-run the script to update the presentation notes whenever you make changes to your master slides.

Here is the complete script that automates this entire process for you. Just paste it into a new note and it will create your three presentations automatically.

```js
// Define the tags to filter the "master" notes.
const candidateMasterTags = ["#master"];
// Define the output configurations: tags and file names.
const targets = [
    [["#group1"], "Group 1 presentation.md"],
    [["#group2"], "Group 2 presentation.md"],
    [["#group1", "#group2"], "Group 1 & 2 presentation.md"]
];

// An async function to read the full content of a note from disk.
async function readSource(sourcePath) {
    const sourceFile = app.vault.getAbstractFileByPath(sourcePath);
    if (!sourceFile) {
        // Return an empty string if the file doesn't exist
        return "";
    }
    return await app.vault.cachedRead(sourceFile);
}

// A function to filter slides that contain ALL of the required tags.
function filterSlidesByTags(slides, requiredTags) {
    // Return a new list containing only the slides that include all required tags.
    return slides.filter(slide =>
        requiredTags.every(tag => slide.includes(tag))
    );
}

// --- Main script logic ---

// Get the notes that have any of the master tags.
const masters = dv.pages().filter(p =>
    p.file.tags.some(tag => candidateMasterTags.includes(tag))
);

// Get promises to read the content of all master notes.
const readPromises = masters.map(p => readSource(p.file.path));

// Wait for all files to be read and get their full content.
const allContents = await Promise.all(readPromises);

// Split each note's content into individual slides and create a flat list.
const allSlides = allContents.flatMap(content =>
    content.split("\n---\n")
);

// Iterate through each target configuration and generate a new presentation.
for (const [requiredSlideTags, targetFileName] of targets) {
    // Filter the slides to keep only those that have all required tags for the current target.
    const filteredSlides = filterSlidesByTags(allSlides, requiredSlideTags);

    // Join the filtered slides to create the new presentation content.
    const newPresentationContent = filteredSlides.join("\n---\n");

    // Get the file handle for the target path.
    const targetFile = app.vault.getAbstractFileByPath(targetFileName);

    if (targetFile) {
        // If the file exists, modify its content.
        await app.vault.modify(targetFile, newPresentationContent);
    } else {
        // If the file doesn't exist, create a new one.
        await app.vault.create(targetFileName, newPresentationContent);
    }

    // Display a message confirming the action.
    dv.el("p", `Presentation created at **${targetFileName}** with ${filteredSlides.length} slides.`);
}

```

* * *

### Instructions

1. **Tag Your Master Notes:** Add the `#master` tag to any note you want to include in your presentations. A good place to do this is in the note’s frontmatter.
2. **Create the Builder:** Create a new note titled `Presentation Builder` (or any other name you prefer). Paste the complete DataviewJS code block into this note.
3. **Run the Script:** Simply open the `Presentation Builder` note. The script will automatically run, find all notes tagged with `#master`, and create the new presentation files in your vault.
4. **Customize:** You can easily edit the output filenames and the required tags for each presentation in the `targets` list at the beginning of the script. The new presentations will be saved to the root of your vault by default.

---

<div class="post-metadata">

**Author:** ![royalbruxa](https://forum.obsidian.md/letter_avatar_proxy/v4/letter/r/9de0a6/32.png) [@royalbruxa](https://forum.obsidian.md/u/royalbruxa)\
**Post date:** [September 9, 2025, 7:10pm UTC](https://forum.obsidian.md/t/find-and-embed-all-slides-or-headings-text-that-have-the-same-tag/104742/3 "2025-09-09T19:10:28Z")

</div>

Thank you, this worked!

---

<div class="post-metadata">

**Author:** ![system](https://forum.obsidian.md/uploads/default/original/3X/b/e/bec35fbd23ab28909bb6bfe62cb32eb82dd34019.png) [@system](https://forum.obsidian.md/u/system)\
**Post date:** [October 7, 2025, 7:10pm UTC](https://forum.obsidian.md/t/find-and-embed-all-slides-or-headings-text-that-have-the-same-tag/104742/4 "2025-10-07T19:10:47Z")

</div>

Closed on October 7, 2025, 7:10pm UTC

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