Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
fseesink opened this issue Nov 2, 2024 · 11 comments
Closed

Comments

@fseesink
Copy link

fseesink commented Nov 2, 2024

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
Copy link
Owner

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
Copy link
Author

fseesink commented Nov 4, 2024

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:

  • hugo (a directory created using hugo new site hugo, so it contains your typical hugo site structure)
  • Journal (intended to store daily notes)
  • Templates (for storing Obsidian templates, like the one used to populate front matter on each blog post page)

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,

  • site dir says "Hugo site root dir, absolute path". And tinkering, I found that, yes, it had to be an absolute path alright, which is why, in the end, I pointed it at /Users/frank/Desktop/hugosite. This is the directory where I wanted the exported blog posts to go.
  • blog dir says "All blog copy to this dir, relative path to site", which is why I set it to simply "content", as in a typical Hugo site, you put your posts in the content subdirectory. So I expected Obsidian pages which had a blog tag to be exported to /Users/frank/Desktop/hugosite/content/.
  • And static dir says "All static (like image) copy to static/${static dir}, like static/ob, relative path to site/static", which I took to mean exactly that as well. Hence why I set it to "." (because I could not leave it blank as I found out), so it would store static files like images in that exact location and not something below it. Again, I expected static assets used by the Obsidian pages which had a blog tag to be exported to /Users/frank/Desktop/hugosite/static/.

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
Copy link
Author

fseesink commented Nov 4, 2024

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

  • static for holding all the images
  • Templates to hold the Obsidian template I would use for each blog post (to add the appropriate Hugo frontmatter/etc. including setting the tags to blog)
    • one file, Blog post.md which is the template I would apply to a blog post (I set a hotkey to do this)

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

  • "Folder to create new notes in" == '' (blank)
  • "Attachment folder path" == "static"

I then configured the plugin with

  • site dir == /Users/frank/Desktop/hugosite
  • blog dir == content/blog (as my goal was to export the Obsidian notes to that subdirectory
  • static dir == .

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:

  • A setting to limit the scope that it searches for Obsidian notes with the blog tag (i.e., specify the directory within the Vault under which to search for and export/sync the Hugo content). This would allow for having things like Obsidian templates which contain the preset frontmatter LIKE the blog tag so that users can quickly populate a new blog post and begin writing, while not having those templates be exported to the Hugo site.
  • A modification of the static dir setting so that if blank it copies simply to ${site dir}/static/, with the links set accordingly. Basically that the final path for static content is ${site dir}/static/${static dir}. Because currently that's not what it's doing.

@kirito41dd
Copy link
Owner

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

@kirito41dd
Copy link
Owner

@fseesink
Copy link
Author

fseesink commented Nov 5, 2024

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
Copy link
Owner

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
Copy link
Author

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.

Footnotes

  1. Remove || setting.static_dir.length == 0 from the line.

@kirito41dd
Copy link
Owner

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

@kirito41dd
Copy link
Owner

@fseesink
Copy link
Author

Updated plugin and tested with my setup above.

First, it DOES now allow you to leave static dir empty. So thanks for that!

However, it still generates one too many levels of directories for the static content. From this file structure in Obsidian (where the Templates folder holds a template file that I hoped to use to pre-populate each blog post with the Hugo frontmatter/etc.):
image

The output I see is as follows:
image

I would think it should just be outputting static/shocked.jpg, not static/static/shocked.jpg.

And would still love to see one extra setting to limit the scope that it searches for Obsidian notes. But I realize that's a little more work.

(Side note: Because of all this, I actually went looking into TypeScript, though I simply haven't had time to learn it well enough yet, or I'd send a PR. One day... )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants