microjam icon indicating copy to clipboard operation
microjam copied to clipboard

Relative paths are not dynamic between files

Open klawr opened this issue 5 years ago • 16 comments

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 avatar Jun 19 '20 15:06 klawr

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.

klawr avatar Jun 19 '20 16:06 klawr

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 !

goessner avatar Jun 22 '20 10:06 goessner

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

klawr avatar Jun 22 '20 13:06 klawr

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 ?

goessner avatar Jun 23 '20 04:06 goessner

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.

klawr avatar Jun 23 '20 07:06 klawr

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 ...

goessner avatar Jun 23 '20 20:06 goessner

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

klawr avatar Jun 23 '20 21:06 klawr

I think ...

  • Users writing markdown files simply should rely on being able to use urls relative to their current document. So your link
[[1]](#1)

works as is. Images located in a docs/img folder are referenced from a sub folder via ../img/image.png.

  • Designers/Programmers building template.js use ${data.reldir} with urls in there.

  • Referencing a navigation file occures with knowledge of its location ... see above.

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

goessner avatar Jun 23 '20 21:06 goessner

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

klawr avatar Jun 23 '20 21:06 klawr

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 ?

goessner avatar Jun 24 '20 06:06 goessner

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 ?

klawr avatar Jul 04 '20 12:07 klawr

... working example somewhere ... ?

goessner avatar Jul 05 '20 16:07 goessner

Sent an Email to you to review this proposal.

klawr avatar Jul 05 '20 16:07 klawr

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 avatar Jul 05 '20 16:07 goessner

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 ...

goessner avatar Jul 05 '20 17:07 goessner

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.

klawr avatar Jul 06 '20 18:07 klawr