kirito41dd / obsidian-hugo-publish

write blog in obsidian, pubulish to hugo site.
Other
37 stars 0 forks source link

Plugin (1.0.6) generates odd directory structure with too many levels(?) #6

Open fseesink opened 2 weeks ago

fseesink commented 2 weeks ago

First, thanks for making this plugin. As someone who uses Obsidian for note taking, I recently was tinkering with Hugo and thought, "Man if only I could write my posts in Obsidian and post them somehow." Eventually landed on this plugin and thought to give it a try. Only this appears to be creating a rather nested/overcomplicated directory structure.

Pictures are worth a thousand words, so let me show things this way. I installed the plug (1.0.6) in Obsidian (1.7.4). The vault has various files in it, but only one (info.md) is tagged with blog. That file has a single image (shocked.jpg), as I wanted to test both MD files and images, to see how this plugin modified things.

I created a directory on my desktop called hugosite. This is where I wanted the plugin to sync.

Here is the plugin configuration:

image

Here is the output generated:

image

What I expected to happen was that it would generate output something like this:

image

with info.md appropriately modified so the image path matched.

Not sure what the additional depths are for. But maybe I'm missing something.

kirito41dd commented 2 weeks ago

https://github.com/kirito41dd/obsidian-hugo-publish/blob/master/src/main.ts#L191

it depends on how you organize your image paths in obsidian

fseesink commented 2 weeks ago

Hmmm. Ok, so I guess I can see now where the extra path entries are coming from. But not sure why the plugin does this. It seems backwards.

To be clear, for this experiment, I have this particular Obsidian vault that I am using setup basically as a Hugo site. This screenshot will explain it, but in short, there are 3 root level directories:

The page being shown here is the single blog post named info that is tagged with blog. This is the only page that the plugin exports.

image

[NOTE: My original idea was to simply use Obsidian to directly edit the Hugo blog posts. It's possible to disable Wikilinks in Obsidian so that it generates normal MarkDown links. And by specifying that all new attachments should be stored in hugo/static, you can make it that as you write blog posts and drag/drop images into the post, those images will automatically be in the static directory.

Unfortunately, if you drag/drop an image into an Obsidian post, it generates a ![](imagefilename) link to the image, which is a relative path. This is fine within Obsidian, as Obsidian knows to look in static for the image file. But this causes trouble when generating the Hugo static website. So while you can get MarkDown style image links, due to the relative path saying "find this image in the same directory as the blog post", this falls down because when you try to run hugo to generate the static site, you end up with the same relative path in the final HTML, when in fact it needs to point to the root directory, as that is where all static assets are copied (i.e., what is basically in the public directory after you generate your site).]

Anyway, this just happens to be the particular vault setup I was working with. So this vault was configured as follows (explanation below):

image

with new notes being created in hugo/content (where I'd typically want to put new blog posts), and although the screenshot doesn't show this properly since it continues to show "attachments" (I think this is a bug in Obsidian), the "Attachment folder path" is, in fact, set to hugo/static. And besides having set it, I KNOW this to be the case, because after dragging/dropping images into various blog posts, I would find those image files in hugo/static. And there is no attachments directory anywhere. (That name is simply what it shown by default in Obsidian when you first config a vault.)

So what it looks like the plugin is doing is concatenating the Obsidian directory path settings after the plugin settings, is that it? But why? Why is that even needed? There is still something in this that is escaping me.

When I looked at the plugin settings,

But instead of this, the export plugin tacks on the Obsidian config paths for "Folder to create new notes in" and "Attachment folder path", respectively, before doing so. I don't get that. What if I wanted new Obsidian notes created somewhere else entirely in my directory structure (which is entirely reasonable for an Obsidian vault)? Maybe I want new notes created in another subtree that has nothing to do with my Hugo blog posts. Or if I set my attachment folder to be somewhere else entirely? Why is that part of the exported path. Shouldn't exported blog posts simply be dropped into ${site dir}/${blog dir} and any static content they reference be dropped into ${site dir}/static/${static dir}?

fseesink commented 2 weeks ago

Tinkered more with this, but just can't seem to make it work well.

I tried setting up a new Obsidian Vault where I put notes (ergo blog posts) at the root level. The only directories I had in the vault were

I then configured Obsidian as before to save any files dragged/dropped into notes to be put into static, and to use MarkDown links vs. WikiLinks. So Obsidian had

I then configured the plugin with

With this config, I again tested by creating a single new note I simply called "info". This created a file at the root of the vault called info.md as expected. I hit my hotkey, and the template I used was applied. Then I dragged/dropped the shocked.jpg image into the post like I would if adding images to a post. And Obsidian appropriately added this file to the static directory and set the MarkDown link as ![](shocked.jpg). So at this point my Vault looked like this:

image

However, even so, when I clicked the hugo sync button, what I got inside /Users/frank/Desktop/hugosite was this:

image

It took me a minute to realize why. The plugin saw that the template contained the tag blog, so it naturally added that with its directory to the export. So there's no way to leverage Obsidian templates this way.

But it's more the fact that the image file wasn't simply dropped into /Users/frank/Desktop/hugosite/static/, but instead had yet another subdirectory static created first. That just seems incorrect.


{rant} Anyway, beyond this, I think I am just bumping up against a reality I can't get around. That is, I had hoped to find a simple/smooth/intuitive way to use Obsidian to be able to write blog posts, complete with images. But in the end, Obsidian relies on relative paths, while Hugo relies on absolute paths.

That is, inside Obsidian, WikiLinks or MarkDown links are all relative. They don't specify a preceding "/". This is because Obsidian does everything relative to the Vault directory. In fact, if I try to ADD a "/" to make the MarkDown link an absolute path, the image no longer shows in the note.

Unfortunately, Hugo goes through each MarkDown file and takes any content files that are referenced by MarkDown image links and copies them all to the root directory of public, which is where Hugo builds the static site. This is true whether those referenced files are all in static at the root level of the Hugo site or even if they are in the same directory or elsewhere under content. I've tried various ways.

But Hugo does NOT adjust the links, resulting in the final site links having relative paths which don't accurately reflect where those files are located when hosted.

Frankly, it's been an annoying process. Mind you this isn't the fault of this plugin. I'm simply documenting what I've been finding out in general regarding trying to use Obsidian with Hugo. {/rant}


As for this plugin, if I could make some feature requests, I would love to see 2 things:

kirito41dd commented 2 weeks ago

open "use wiki link" in setting, plugin will auto convert it. you can put your .md and images anywhere in obsidison.

kirito41dd commented 2 weeks ago

FYI: https://github.com/kirito41dd/obsidian-hugo-publish/blob/master/src/util.ts#L104

fseesink commented 2 weeks ago

Good to know I don't have to tweak Obsidian to use MarkDown links (not that I mind). Thanks for that.

Now regarding the other bits, I went looking at the code (TypeScript's not really my forte, so bear with me). And in settings.ts I see lines 87-92:

export const check_setting = (setting: HugoPublishSettings): boolean => {
    if (setting.blog_dir.length == 0 || setting.static_dir.length == 0) {
        return false
    }
    return true;
}

Is it really necessary for setting.static_dir to contain a value? I mean if it's left blank, one would expect images to simply be copied into ${site dir}/static/. But as it is now, you can't leave that setting blank, as the plugin kicks back "Error: Please provide config first!". This is why I simply put a ".". But for some reason, that's being expanded so that the image is being stored in ${site dir}/static/static/ instead. That seems... weird to me.


As for my feature request to limit the scope that the plugin searched for, what I meant was something like another settings string field where a user specifies, much as they do for blog dir, some folder within the Obsidian vault to limit the export to. Then you'd take that string and store it like you do the other settings, and you'd pass it in the call in main.ts to what looks like the function in utils.ts called get_all_blog_md (adding that as an other parameter, of course), and then adjusting that function. Possibly after the line

const files = app.vault.getMarkdownFiles();

adding a few lines to filter that down by stripping out any files that don't start with whatever string was passed in.

I'd write this up and do a pull request, but again, TypeScript not really a forte. Figured it was faster to describe here as you know this code better. I guess the toughest challenge is finding if there's a function that lets you get a drop-down list of possible folders within the vault, much as the Obsidian settings themselves do for things like the "Files and links" section of the settings.

[UPDATE: Looks like maybe it'd be the Vault.getAllFolders() method maybe in some form? Not sure how that presents. I just know what it looks like when I click in the Obsidian settings field to set something like "Folder to create new notes in", where it shows a drop-down list.]

Point being that if the plugin could be pointed at some subfolder within the Vault, it would let folks still be able to make use of Obsidian templates, for example, as mentioned earlier.

Anyway, just some thoughts.

Again, much appreciate that you built this plugin. It's so close to what I'm after.

kirito41dd commented 2 weeks ago

TypeScript's not really my forte too. I agree with you that "static_url" can be empty. The current settings panel is ugly because I can't write the front end. Welcome PR.

fseesink commented 3 days ago

I thought the fix might have be as simple as editing the if statement above in settings.ts lines 87-92 to remove the 2nd check [^1]. That is, it would read as follows:

export const check_setting = (setting: HugoPublishSettings): boolean => {
    if (setting.blog_dir.length == 0) {
        return false
    }
    return true;
}

This way, if someone doesn't put anything in the static dir field, the end result is that things are stored where they should be. But I can't verify this without setting up a dev environ to test this. What I was able to do was navigate down into my vault under /path/to/vault/.obsidian/plugins/hugo-publish/ and manually edited the main.js file to do the above. And it DID allow me to save the config with the static dir field empty.

However, I still end up with the static files under static/static. So feels like there's one too many "static"s in there somewhere.

[^1]: Remove || setting.static_dir.length == 0 from the line.

kirito41dd commented 2 days ago

Yes. I plan to release a new version this week. I will include this change