README file from
GithubFile Bundles
An HTML page and the assets it loads, a note and the images pasted into it, a scanned invoice and the note describing it — these are one thing to you and several files to Obsidian. Move the main file and the rest stay behind. Delete it and they are orphaned. This plugin lets a file declare which files and folders belong with it, and then treats them as one bundle: what happens to the main file happens to the whole thing.
Demo vault
The documentation is a demo vault. Every feature has a note that explains what it does, with a worked example you can search yourself.
Start reading here — it is plain markdown, so it works on GitHub with nothing installed.
A copy of the vault ships with every release. You can access it via any of the following:
- Running the File Bundles: Open demo vault command.
- Downloading
file-bundles-demo-vault.zipfrom the Releases. It unzips into a singlefile-bundles-demo-vault-<version>folder. - Browsing its source in
demo-vault/in this repository.
What it does
The dependency is declared, not inferred from a naming convention. Every existing plugin in this space recognizes a bundle by where a file sits or what it is called — a note and its same-named attachment folder, a sidecar named after the file beside it. That works until the two things you want bundled do not share a name or a folder. Here you say which files belong together, in the main file's own frontmatter, and nothing depends on what they are called.
It is not limited to notes. An HTML file, a PDF or an image can be the main file of a bundle. Those cannot carry frontmatter, so they get a small sidecar note that declares the bundle on their behalf — the declaration is marked by the frontmatter key, never by the file name, so that note is an ordinary note you can also write in.
A bundle is locked by default. Its dependents are hidden in the File Explorer, leaving only the main file, and moving, renaming or deleting the main file carries them along. Unlock it and the pieces go back to being independent files. The hiding is display only: the dependents stay in your vault index and stay resolvable as link targets, which is what separates a locked bundle from an excluded folder.
A file that two bundles both declare is never deleted with one of them.
Declaring a bundle
A markdown file declares its own bundle inline:
---
file-bundles:
files:
- "[[./assets/diagram.png]]"
- "[[/shared/logo.png]]"
folders:
- ./assets
---
A file that cannot carry frontmatter gets a sidecar note that names it:
---
file-bundles:
main: "[[./report.html]]"
files:
- "[[./report-styles.css]]"
folders:
- ./report-images
---
main- The file the bundle is built around. Omit it and the declaring note is itself the main file.
files- Links to the files that travel with it, as wikilinks or as markdown links.
folders- Folders that travel with it, as paths — or as a link to a folder note, meaning that note's folder.
Every path is explicitly relative (./assets) or explicitly rooted (/shared/brand). A sidecar can live anywhere, so a bare assets would be ambiguous between the declaring file and the vault root, and this plugin would rather reject it than guess.
The vault itself is never a member. A bundle is a file plus what travels with it, so an entry that names the whole vault — /, or ./ written in a note at the top of the vault — is rejected, as is one that climbs above it. Everything else is taken at its word, trailing slash and all: /shared/brand/ means the folder shared/brand.
The two forms mean different things when the main file moves: a relative member is anchored to the main file and travels with it, while a rooted member states a home of its own and stays put. That is what makes a shared logo shareable.
The main file and the note that declares the bundle are always members. You never list them.
Usage
Four commands, and the locking and deleting ones on the File Explorer's context menu for any file a bundle claims:
- File Bundles: Show the bundle the active file belongs to
- reports what travels with the file you are looking at, whether it is a main file, the note declaring one, or one of the dependents.
- File Bundles: Lock or unlock the bundle the active file belongs to
- unlocking reveals the dependents and stops anything propagating; locking again restores both. Your note is never edited either way.
- File Bundles: Delete the bundle the active file belongs to
- deletes the main file and everything the declaration names, except anything another bundle also claims.
- File Bundles: Duplicate the bundle the active file belongs to
- copies the main file, the note declaring it, and every dependent anchored to it with
./, then writes the copy's own declaration so the duplicate names its own files. A rooted/…member is shared rather than copied — it states a home of its own, so both bundles point at it. Use this rather than Obsidian's own Make a copy, which copies the main file alone and leaves the copy claiming the original's dependents.
- copies the main file, the note declaring it, and every dependent anchored to it with
Moving and renaming need no command: a bundle follows its main file wherever you drag it.
Installation
The plugin is available in the official Community Plugins repository.
Beta versions
To install the latest beta release of this plugin (regardless if it is available in the official Community Plugins repository or not), follow these steps:
- Ensure you have the BRAT plugin installed and enabled.
- Click Install via BRAT.
- An Obsidian pop-up window should appear. In the window, click the
Add pluginbutton once and wait a few seconds for the plugin to install.
Debugging
By default, debug messages for this plugin are hidden.
To show them, run the following command in the DevTools Console:
window.DEBUG.enable('file-bundles');
For more details, refer to the documentation.
Changelog
All notable changes to this project will be documented in the CHANGELOG.
Contributing
Contributions are welcome — see CONTRIBUTING to get set up.
Support
My other Obsidian resources
See my other Obsidian resources.