I may have found a bug in permalinks or maybe not


#1

Hello, I have a quick question. I have a file in the root of my _site directory that is clients.html and in the yaml I have permalink: clients.html but when I build the site it treats the file as if it is in /clients/ it even serves both /clients/ and clients.html.

The confusing thing is that the _site directory has no subdirectory named clients or the related index.html so it is taking that flattened clients.html and still processing it as if it were to have its own folder but leaving the original. What am I doing wrong?


#2

in the top paragraph you say it is in the root of your _site directory - do you mean the root of your project? not the _site folder? is this the source?

when you say in your yaml you have permalink… - do you mean in the front matter of the clients.html file?

maybe you have 2 files in there - maybe one called clients.md?

is there a repo to look at?


#3

Sorry no repo to look at but I can answer you.

Here is our site structure.
├── _layout
├── _includes
├── _site (after build)
│ └── cooking
│-- └── index.html
│ └── cleaning
│ – └── index.html
│ └── clients.html
│ └── index.html
├── cooking
│ └── index.html
├── cleaning
│ └── index.html
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── readme.md
├── clients.html
└── index.html

Yes the front mater of clients.html in the root directory has the permalink mentioned above. Once I run bundle exec jekyll serve it will generate the _site folder as you see above properly leaving the clients.html file where it should be. When visiting 127.0.0.1:4000 It serves both /clients.html and /clients/ all the liquid code on the page is processed as if it were in one folder deep ( _site/clients/ ) but as you can see there is no clients folder


#4

in your config file do you have a permalink setting?

I can reproduce what you are seeing, it probably also works if you do /clients without the trailing slash or the .html part at the end.

I would guess this is just a webrick server thing (jekylls built in server), not so much of a bug. When you deploy it to production and use a different web server I think it will work differently - or at least work the way the web server in configured. Jekyll is building it to work the way you intend, just the server is allowing the additional url to work.


#5

No, our config has no permalink settings. yes the serving to clients clients/ and clients.html could be an issue with the webrick but the main problem is that jekyll still processes the file as if it is one folder deep. The main problem that concerns me when deploying to production or staging is that all the URLS are not pointing to the correct relative path. They point to …/ which would denote that the jekyll build thinks it has a folder of its own. I have already tested on another work station, and our linux server it it acts the same way in all of them


#6

not sure I understand - jekyll is just producing the static files, and when it does that there is no /clients/ directory, just the clients.html file like you would expect.

the main problem is that jekyll still processes the file as if it is one folder deep when you say this, what evidence in the folder structure is there? maybe I am misunderstanding the issue.

all the URLS are not pointing to the correct relative path. They point to ../ is there another example? how was the offending url created - like a full example of the html/liquid you use in the source.


#7

We have an include file named base.html that has this:
{% assign base = ‘.’ %}
{% assign depth = page.url | split: ‘/’ | size | minus: 1 %}
{% if depth <= 0 %}{% assign base = ‘.’ %}
{% elsif depth == 1 %}{% assign base = ‘…’ %}
{% elsif depth == 2 %}{% assign base = ‘…/…’ %}
{% elsif depth == 3 %}{% assign base = ‘…/…/…’ %}{% endif %}

In our clients.html (and all other pages) we have entries like this

{{ base }}/assets/img/img.png which in turn converts them to the proper relative URL for the site so …/…/assets/img/img.png this makes it so the site simply works no matter where it is placed if it is on our staging server sub.domain.com/folder1 or a branch of that sub.domain.com/branch/folder1 or even the production server domain.com it would work in all of them because it puts the proper relative link.

This include works like a charm everywhere in the site with clients.html being the one exception because jeyll processes its depth as having its own folder when it doesn’t.


#8

Solved. I realized that this was a flaw in my own logic since index.html wasn’t being counted as it is the index. I modified the script to this, and now it works when I add the related tag into the YAML
{% assign base = ‘.’ %}
{% assign depth = page.url | split: ‘/’ | size | minus: 1 %}
{% if page.tags == “root” %}{% assign base = ‘.’ %}
{% elsif depth <= 0 %}{% assign base = ‘.’ %}
{% elsif depth == 1 %}{% assign base = ‘…’ %}
{% elsif depth == 2 %}{% assign base = ‘…/…’ %}
{% elsif depth == 3 %}{% assign base = ‘…/…/…’ %}{% endif %}

edit modified the flow so it looks for tags first.


#9

I was playing around with it and sort of figured something like that. I have not used split much before, interesting use case.


#10

Yeah, it would be nice if jekyll could just do all of this naively. As it is right now, if you use the Jekyll defaults it breaks urls when the site build is placed in folders other than what is explicitly mentioned in the config file. This makes automatic deployment to different staging points for development pointless.

edit: spelling and grammar