Filename and page.title do not have the same capitalization

If I have pages named CSS.md or Website Development.md, Jekyll sets as page.title respectively Css and Website development. How can I tell Jekyll to respect the original capitalization of the filename, without having to set the specific title in each file front matter?

Thanks a lot!

Best,
Tommi :exploding_head:

I did a little research into this, and I do not think you will get what you want out of the box. Perhaps someone else has some other ideas. I thought about using the permalink slugs, but I am unsure if that gets you much further than the approach I list here.

You can write Liquid code that gets the filename using paths and strip out the extraneous elements that are in the filename.

If you use any of these approaches, I recommend making the code reusable by putting it in a file located in your _includes folder. You can then import it into your layout(s) with the {% include %} tag.

If you are unfamiliar with using includes (which are super easy), here is a link to the docs:

Display a list of all posts with the filename as the title

{%- assign posts = site.posts -%}
{% for post in posts %}
    {%- assign paths = post.relative_path |  split: '/' | last | split: '.markdown' | first | split: '-' -%}
    {%- assign mytitle = "" -%}
    {% for path in paths offset: 3 %}
        {%- assign mytitle = mytitle | append: path | append: " " -%}
    {% endfor %}
    {% assign mytitle = mytitle | strip %}
    My title: {{mytitle}}
{% endfor %}

The first assign posts line creates an array of posts.

The for post in posts loop iterates through all the posts.

The assign paths code:

  1. Gets the relative_path of the post
  2. Assume the post’s relative_path looks like this: _posts/2022-01-24-This-is-a-Test.markdown. The split filters will create a new array that looks like this:

2022
01
24
This
is
a
Test

Note: You can add more filters, like | split: '.md' | first or just rename .markdown to .md. See the example with Pages later in this response to add more file types.

Since you build a new title from that array, the first assign mytitle line will create an empty string.

Since the first three rows of the array are the date elements, you do not want them in the final title. The for loop ignores those three rows of the array using the offset filter, so you only get the following values:

This
is
a
Test

As the for loop iterates through the array, the second assign mytitle line will build a string that matches your filename, which displays based on the case sensitivity of whatever you typed. It also appends a space between each word.

The last {% assign mytitle = mytitle | strip %} removes any extra spaces in the title.

In my example, the final mytitle variable is:

This is a Test

Display a list of pages

Pages often include HTML files as well, so here is an example that lists all the pages on your site and uses split to not only remove .markdown, but .html from the title. You can add as many as you want, and that method will work in the example of the post I shared earlier in this response.

Here is the code:

{%- assign pages = site.pages -%}
{% for page in pages %}
    {%- assign mytitle = "" -%}
    {%- assign paths = page.path |  split: '/' | last | split: '.markdown' | first  | split: '.html' | first | split: '-' -%}
    {% for path in paths %}
        {%- assign mytitle = mytitle | append: path | append: " " -%}
    {% endfor %}
    {% assign mytitle = mytitle | strip %}
    My title: {{mytitle}}
{% endfor %}

Display the title on a page

When displaying the title for a page, you can add a little extra code (again, I would put this code into the _includes folder and update the layout to import it.

{%- assign paths = page.path |  split: '/' | last | split: '.markdown' | first  | split: '.html' | first | split: '-' -%}
{% for path in paths %}
    {%- assign mytitle = mytitle | append: path | append: " " -%}
{% endfor %}
{% assign mytitle = mytitle | strip %}
My title: {{mytitle}}

Of course, you can modify that code for posts, just using post.relative_path instead of page.path.

Once again, I think this is probably the wrong thing to do because you are modifying the out-of-box functionality that Jekyll provides. It is a best practice to use the title in the YAML file.

I hope this helps.

1 Like

It sounds like you are looking for a new variable like:

{{ page.filename }}

This has been requested on Stack Overflow a decade ago.

I do not think this is the correct solution based on the op’s original request. The request is to display the filename as the title, respect capitalization, and not use the YAML front matter.

The SO post you refer to shows how to get the filename into the YAML front matter, but it does not solve the problem of removing things like the filename extension.

At the end of the day I think OP should simply put title into Front Matter like the rest of us. My intention was just to point out the issue came up a decade ago and there is still no easy solution.

Understood. Thanks for the additional detail and I completely agree that it’s best to just type a title.

Thanks a lot for your replies, @BillRaymond and @pippim!

It is a pity that a simple task such as preserving capitalization (not even changing it, just keeping it the same!) does not work.

I will adapt and keep it as it is.

No problem. I think the way Jekyll treats file names is as a fallback plan if there’s no YAML front matter.