goessner / microjam

A minimalistic Jamstack approach for creating GitHub-Pages hosted sites.
https://goessner.github.io/microjam/
MIT License
44 stars 5 forks source link

Relative paths are not dynamic between files #7

Open klawr opened 4 years ago

klawr commented 4 years ago

Given the following folder structure:

├── package.json
└── docs
     ├ DirectoryA
     │    ├ FileA.md
     │    └ FileA.html
     ├ theme
     │    ├ template.js
     │    └ style.css
     ├ index.md
     ├ index.html
     ├ navigation.md
     └ navigation.html

FileA and index can not use the same navigation, theme/template.js, theme/style.css, since their respective relative paths differ. A quick (and dirty) workaround is to move index into a directory to align the relative paths (so they can just use ../navigation.html, ../theme/template.js...), but this obviously is no good solution since it forces all files to be always on the same level.

klawr commented 4 years ago

The problem on the navigation part differs from the accessing of the files in theme. The problem of navigation is that the paths depend on the relative path of the source file. Therefore the reluri of the source file (think FileA.md), which is tracked in pages.json has to be added into all href properties in navigation before prepending it in the html... I am not sure if we want to do that.

goessner commented 4 years ago

This defect can be reproduced well. It should have been gone with Version 0.3.8, as it is resolved by using the html base element.

<head>
...
   <base href="../../../">  <!-- three levels below `docs` folder -->
...
</head>

Then every relative url is resolved with regard to that base location ... so in template.js

`...
<base href="${data.reldir}">
<title>${data.title}</title>
...`

place it in ´head` section somewhere before the occurence of the first relative url.

For minimalism and performance reasons (avoiding a look into subdirectories), subdirectories containing relevant markdown documents are assumed to be named *.md. So your folder tree above should read now

├── package.json
└── docs
     ├ DirectoryA.md
     │    ├ FileA.md
     │    └ FileA.html
     ├ theme
     │    ├ template.js
     │    └ style.css
     ├ index.md
     ├ index.html
     ├ navigation.md
     └ navigation.html

Please note the breaking change to rename use to uses in frontmatter sections !

klawr commented 4 years ago

Seems to be working. Closing this issue and opening related issue at #9

goessner commented 4 years ago

hmm ... I'm afraid it's not what we finally want, as document local links do not work now. Interesting discussion here ...

https://stackoverflow.com/questions/1889076/what-are-the-recommendations-for-html-base-tag/46539210#46539210

I think this solution might be more consistent and better:

  1. Skip <base> element.
  2. Every url in template.js is getting transformed (manually) via data.reldir.
  3. Links in data.content are relative to current document. This is, what users and possibly clientside javascripts expect.
  4. Injected document fragments can get transformed by frontmatter directive via
"uses": [ { "uri": "navigation.md", "reldir": "../" } ]

what do you think ?

klawr commented 4 years ago

I am not to sure about this but the Mechanismentechnik Page does use local links a lot in navigation and the FAQ has quite a few which are working fine (the page got updated to work with v0.3.8 yesterday).

I do not like the idea tinkering with every url in the document as I could imagine there are a few side effects.

goessner commented 4 years ago

Try to click [1] in your example "Die Grundfälle werden gebildet durch Gleichung (6.1)[1]. "

https://goessner.github.io/Mechanismentechnik/06_Getriebekinematik.md/Aufgabe_6.9.html

What do you suggest ?

btw: FAQ is in the root docs folder ...

klawr commented 4 years ago

I don't know how much control we have, regarding the parsing of markdown to html. That being said, if the [1] would translate to <a href="javascript:;" onclick="document.location.hash='1';">[1]</a>. instead of <a href="#1" data-href="#1">[1]</a> it would work even with <base>.

I placed all files of 00 into the root after v0.3.8 was released. Am opening an issue there: goessner/Mechanismentechnik#9

goessner commented 4 years ago

I think ...

So why should we translate urls in users own markdown files ?

klawr commented 4 years ago

I saw the deprecated link with img. Will be updated soon.

We do translate the users markdown files into html anyways. The user would not care if we translate [[1]](#1) into <a href="#1" data-href="#1">[1]</a> or <a href="javascript:;" onclick="document.location.hash='1';">[1]</a> in the html.

Alternatively we could drop <base>, which I guess would force us to translate every other url, or disable support for relative links in shared files and directories like navigation.md or imgs

goessner commented 4 years ago

It is otherwise round:

  1. If we keep <base> we need to translate urls in users markdown documents and leave urls in used files.
  2. If we drop <base> we don't need to translate urls in users markdown documents, but have to do that in used files.

I am clearly favor scenario 2, where translation is necessary only in cases, where markup is reused by documents distributed in different subdirectories only.

Can you please investigate, if embedding navigation bar markup in a <iframe> might help here out ?

klawr commented 4 years ago

The best solution I have found to do that is to:

  1. Create the html for navigation.md.
  2. Set <base target="_parent"> in that html, for the hyperlinks (in the nav) to be used for the iframes parent, not inside the iframe itself.
  3. Give the iframe and the body of the generated html the id nav. That one may be changed, but there are no collisions, since the iframe is a seperate html.
  4. Add e.g. <iframe id="nav" src="../navigation.html"> </iframe> to the respective HTML.

The styling of the navigation may look like:

main > #nav {
  grid-column: 1;
  position: sticky;
  width: 21em;
  top: 0rem;
  height: 100vh;
  border: 0;
  border-right: 1px solid;
  align-self: start;
}

And elements inside the navigation html can be styled like:

#nav span {
  pointer-events: none;
  cursor: default;
  color: lightgray;
}

The hyperlinks are relative to the respective file, so this should solve the problem and the link to the navigation.html for the iframe should be no problem using the reluri. The nav html element would fall away actually...

To set the base and give the body a different id than the default top (I suggest nav...) and maybe some default stylings (?) it may be worthwhile to add a new layout besides page, article, index, none... maybe navbar ?

goessner commented 4 years ago

... working example somewhere ... ?

klawr commented 4 years ago

Sent an Email to you to review this proposal.

goessner commented 4 years ago

Started with ver. 0.3.8 there are no constraints with layout names. Use any name, as long there is a corresponding template.

Need to update Release Notes.

goessner commented 4 years ago

What I like with this approach, is it's simplicity and the fact, that it's only affecting the corresponding template. Let's go with it for now.

Please be aware, that in example 5.9 Fig. 0 and the first internal link is broken ...

klawr commented 4 years ago

The proposal can be seen in action on the Mechanismentechnik-Page. I am working on an update for microjam, but I am still working on the implementation details.