grav
grav copied to clipboard
Page links should be able to be configured to have trailing slash
I noticed that the source of Page.php, line 1881 to 1883, will trim the trailing slash off a URL.
I believe I have a use case where it should not trim the trailing slash, and I would like to be able to configure it not to do this.
I have a use case where, rather than exclusively using markdown for the pages, I have some existing HTML+JS content that want to move underneath a subdirectory of user/pages
. I want to be able to serve the images from within the page directory without needing to edit the HTML and revise the image references.
The trouble I'm having is that the lack of a trailing slash breaks the image references.
To give a simple example, I have the following files:
/user/pages/05.test/default.md
/user/pages/05.test/Art/cat.jpg
and within the default.md I have some embedded HTML which has <img src="Art/Cat.jpg"/>
.
Using the web-based config, I set the "test" page as "Routable", (also, I change some other settings so that grav doesn't force Art
to be lowercase art
, which also breaks the links).
After doing that, when running Grav on a localhost server, I can access the cat image at the URL localhost:8000/test/Art/cat.jpg
. But when I click the link to my test page, Grav directs to localhost:8000/test
(without a trailing slash) and the image does not appear because the <img src="Art/Cat.jpg"/>
tag incorrectly resolves to localhost:8000/Art/cat.jpg
If I manually edit the URL to have a trailing slash, localhost:8000/test/
, then I get the page with the correct cat image, resolved as localhost:8000/test/Art/cat.jpg
. The trailing slash is necessary for the relative image path to resolve as being underneath the "test" directory.
If the URL for the test page was something like localhost:8000/test/default.md
then the image would also resolve correctly, but grav does not serve my default.md when I try to navigate to that URL.
I tried to force grav to append the trailing slash using another setting in the config UI, "Append URL Extension", but that did not work. I assume what is going on on the code side when I do that is that it gets successfully appended (in line 1879 of Page.php) and then immediately trimmed in the next line of code.
Since test
is a directory and not a file, it seems semantically correct to append a trailing slash to it, otherwise all of the relative links resolve to be one directory too high as I have shown here. Therefore I'm not sure why it wouldn't have the trailing slash by default. But it seems like this should be something that is at least configurable and that grav should not try to fight me when I try to make it append the slash.
I have looked at some related issues, e.g. #1873 seems most relevant, though that one seems to be about the root site URL and not the page URL's. In that issue, @rhukster responded that it was answered in a discourse post, but the answer that I found in there was just:
You would have to disable the Redirect trailing slash option, and then at the end of all your URL links, add a \ manually
But I don't think this makes sense in context of my problem, because it's the page links that grav generates for me (that appear in the top nav bar) which are causing the problem, and so I don't have any control over them apart from the "Append URL extension" setting which as I mentioned does not solve my issue.
Adding trailing slash wouldn't help as the URL is never going to be the same as the folder in the installation.
I'm not sure what you mean, but I have already established that adding a trailing slash does help with the problem. Adding the trailing slash manually to the URL, when browsing to the page, completely solves the problem.
I mean that if you have page stored into:
/user/pages/05.test/default.md
/user/pages/05.test/Art/cat.jpg
Images can only be accessed by <img src="/user/pages/05.test/Art/Cat.jpg"/>
There are two pretty ways to fix this, one is to use <base>
header tag to set the current lookup for all relative URLs, another way is to use a plugin which fixes the location of the images on rendered content.
I do see what you are trying to do here, now that I have read again your message with some thought.
@mahagr Thanks for your tip about the <base>
tag. I was not aware of that mechanism for changing the base URL that all relative URL's are relative to. So I was able to work around the problem by adding the following line to my default.md
:
<base href="/test/"/>
You were incorrect when you said:
Images can only be accessed by
<img src="/user/pages/05.test/Art/Cat.jpg"/>
In fact, as mentioned previously I was able to access the images at an absolute path of http://myserver.com/test/Art/cat.jpg
, so the relative path of this URL would depend on what the current URL in the title bar is:
winndow.location | Relative Path to Image |
---|---|
myserver.com/test |
test/Art/Cat.jpg |
myserver.com/test/ |
Art/Cat.jpg |
myserver.com/test , using <base href="/test/"> |
Art/Cat.jpg |
(again, I should note that grav does not serve up the test/Art directory by default, you need to enable routing on the subdirectory. If you don't make it routable, then you are right -- the image would only be able to be accessed from /user/pages/05.test/Art/Cat.jpg
, and at that point I think it would be Apache or whatever web server you use, serving it directly out of that directory rather than it being served via grav's routing code.)
Having to use the <base href="/test/">
seems less than perfect, because in my opinion the content within the directory should be "portable", meaning I should be able to copy it to a new page directory with a different name and still have it work. Generally speaking it seems like a bad idea when some content within a directory needs to know the name of the directory containing it. So adding <base href="/test/">
breaks this portability and means that there's something that you need to remember to change any time you rename the parent directory or copy the content to a new page directory.
So, having the option for in grav to tell it to use the very important trailing slash still seems like it would be the best solution here, but I have a workaround with the <base>
tag now.
Grav has the ability to redirect all URLs to drop the trailing slash but it doesn't have the ability to to do the opposite - redirect all URLs to add/use the trailing slash.
It has been noted that whether a URL has a trailing slash or not does not affect SEO (https://discourse.getgrav.org/t/trailing-slash-at-end-of-urls/5459/6). So it would seem that having a trailing slash or not is more likely a matter of personal preference. However, I would like to point out a usage difference:
- If the URL has a trailing slash, then you can just add
<img src="picture.jpg">
or<a href="download.pdf">
and it would just work. - If you use Markdown

then it generates a link to<img src="/user/pages/...">
which is a different "folder" than the web page itself - possibly changing the analytics reporting of that page and its assets.
Currently, if someone were to want to use trailing slashes (again, it is a personal preference) then they would have to set redirects at the web server level, and also change twig templates to properly add a slash on page.canonical
etc to make sure metadata and other such stuff is returned correctly.
Yes, one can use redirect_default_route: true
, or as suggested above, to use <base>
, but you'd have to set the default route or base to have a trailing slash on every page. And even then, it does not seem to resolve page.canonical
since it just reroutes the page (see https://github.com/getgrav/grav/issues/2735).
Is it possible for Grav to just have a system/site-wide switch to ask the user to-trailing-slash-or-not-to-trailing-slash ? The default can be as current - no trailing slash. But at least those who do like it that way can then easily add their favourite URL indicator to differentiate between a folder and a file?
Or perhaps it is Grav's preference not to have trailing slashes (which is fine), but then maybe it should be noted in documentation that Grav recommends not having trailing slashes, and if users are keen to do so, they should look to URL rewriting in their server software (or whatever) which is beyond Grav's documentation/support.