This is a plugin for Obsidian (https://obsidian.md).
Output and restructure your notes based on metadata!
Simply:
So from your random structure like this:
- root
- projects
- some active project
- note 1 i want to publish [*] -> tech blog
- another side topic that belongs here but not ready
- another active project
- pacal recepie to publish [*] -> recepies
- some private note
- areas
- photo stream
- collection of photos [*] -> photo blog
- archive
- old recepies
- soup recepie [*] -> recepies
- ...
Makes something like this:
- blogs (output folder anywhere on your drive)
- recepies
- pacal-recepie-to-publish.md
- soup-recepie.md
- ...
- tech
- note-1-i-want-to-publish.md
- another-archived-tech-blog-entry.md
- photo-blog
- collection-of-photos.md
- ...
... so that you can run your custom static site generators on a subset of your notes, like 11ty, Hugo, Jekyll...
Uses the powerful Obsidian Dataview plugin's language to find the files you want to export.
Shows the latest exported file status in the sidebar.
I use static generators (11ty) for my blogs, they are the outlets of my thoughts.
Some of the blog posts I am working on, are part of a bigger topic, and I wanted to keep them around to their respective PARA project folders (Building a Second Brain). I needed a folder-independent structure. One source of truth: wherever the file might be, independent from where it is into a structured output format.
The plugin uses a full fetched DataView query without the results type of course, as it's always a table.
Select all the notes that contain the tech
tag:
FROM #tech
Notes modified last week:
file.ctime > date(today) - dur(1 week)
Select all notes that have the publishDate
metadata key:
publishDate
Select all notes that have publishDate
or blog
among the metadata keys:
publishDate OR blog
It's a standard JS string literal, that gets the file metadata and some extras into it's context.
This is great for grouping your output files: you can create conditional sorting parameters, any folder structures you want.
The following is an example:
If file metadata is like this:
{
blog: 'diary',
publishDate: '...'
title: 'Another day at the office',
tags: ['running', 'some']
}
it will be extended with the following:
{
created: {
// moment style object with keys:
YYYY: '2023',
MM: '05',
...
date: '2023-05-14',
time: '17-54'
},
modified { ... } // date like above
fileName: 'Another Day At The Office'
// if there is a slug property set, uses that, if there is not, falls back to the normalized
// version of the title property, if again not present, falls back to the normalized version of the file name.
slug: 'another-day-at-the-office'
d: function (dateLikeParam){
// Use it like this: ${d(someDateMetaData).date} // will return the date value parsed and reformatted.
}
norm: function(string){
// Will remove any special characters from the string and replaces spaces and separators with dash (-) so it's url safe.
}
}
Want separate folders for different blogs?
${blog}/${created.date}-${slug}
Want to group different years into different folders?
${blog}/${created.YYYY}/${created.MM}-${created.DD}-${slug}
Want to keep the original filename and just dump everything in a flat structure?
${fileName}
Convert any field to a date:
${d(date_published).date}
Use a custom metadata field as formatted date in the output name:
${blog}/${d(date_published).date}-${slug}
For conditional placement of a file, you can use ternary operators
The following will put all values that have a same blogname/post/some-entry
meta value into the same folder, except if the file has an index
key, then it will go to blogname/indexslug
:
${blog}/${index?'':'posts/'}${slug}
If a document references images from your vault, it will be exported into an assets folder, relative to the markdown file! If obsidian shows it, it will be copied.
- assets/
- attachment1.jpg
- image.webp
- pic.gif
- markdown.md <- referenced in the content or even in metadata!
Also, the plugin parses the internal links that point to other notes. If the referenced obsidian file is exported in the process, the links will be re-pointed to the appropriate output file name.
If the link is to a non-exported note, it is removed (the text is left in).
If you want other files to be exported with your markdown, just add a copy
metadata parameter.
It eats any glob formatted regular expression you give it, using relative paths compared to where your markdown file is.
- Copy over
main.js
,styles.css
,manifest.json
to your vaultVaultFolder/.obsidian/plugins/obsidian-bulk-exporter/
. - Or just simlink it with
ln -s /path/to/your/dev/folder/ /path/to/your/vault/.obsidian/plugins/obsidian-bulk-exporter/
- Check out the code base anywhere (or directly into your
.obsidian/plugins/
folder) - You can link that folder into your vault's
.obsidian/plugins/obsidian-bulk-export
folder - run
pnpm run dev
. - recommended the hot-reload plugin for dev (this way when you modify anything it'll get auto re-loaded within Obsidian)
Open an Issue on github, or add a PR!
Marcus Olson for the Dataview plugin and the developer docs!
Till Friebe for the Diff Tool code
jspaint.app - for the marketing image.