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:
- Gets the
relative_path
of the post
- 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.