Hexo Change Permanent Link Format With Backward Compatibility
Recently I would like to simplify permanent link for each post. From:
/2021/03/21/migrateopsmanager.en/
To:
/migrateopsmanager.en/
Shorter URL is more concise and readable, as the date string makes no sense to users. But what's the meaning of URL backward compatibility?
Change Permanent Link Format Issue
According to the official document,
changing permalink format is pretty easy: just modify
:year/:month/:day/:title/
to :title/
would be
OK. However, the real problem is that all existing incoming links will
be invalid after this modification. Then the ranking of our site will be
affected which is unacceptable.
Unlike WordPress, it's hard to make a 301 redirect in Hexo. I worked out some possible solutions:
- Add a canonical link tag to
<head>
for each post - Generated two permalinks, making the old one redirects to the new one by the first solution
- Keep existing permalinks unchanged, use new format for new posts
To be safe, I choose the last one. So how to implement it?
New Post New Permalink Format Implementation
The algorithm is straightforward: if the post creation time is after
new_format_date
, post process the permalink and remove the
useless date string. We will try to write a fitler to implement it:
https://hexo.io/api/filter
Hexo passes data to filters in sequence and the filters then modify the data one after the other.
The first argument passed into each filter is
data
. Thedata
passed into the next filter can be modified by returning a new value. If nothing is returned, the data remains unmodified.
After reading documentation, we found a filter called # post-permalink which is used to determine the permalink of posts:
hexo.extend.filter.register('post_permalink', function(data){
// ...
});
The document doesn't explain the input parameter in detail. Actually,
different filters have different input data structures. Maybe we need to
read the source code. Specifically, for this filter, data
is the permalink string like this:
2021/03/21/migrateopsmanager.en/
.
Let's create a scripts
folder in the Hexo root folder
and write a script refinepermalink.js
:
var new_format_date = new Date('2021-05-01');
hexo.extend.filter.register('post_permalink', function(original_link){
var pivot = original_link.slice(0, -1).lastIndexOf("/")
var date_str = original_link.substring(0, pivot);
var date = new Date(date_str);
var title = original_link.substring(pivot + 1);
var result = original_link;
if (date > new_format_date)
{
result = title;
console.log(' ', date, '### Change permalink:', original_link, '-->', result);
}
return result;
});
The above implementation is self-explained. Execute
hexo g
and then we are done:
$ hexo g
INFO Start processing
2021-06-14T16:00:00.000Z ### Change permalink: 2021/06/15/changepermalinkformat/ --> changepermalinkformat/
2021-05-01T16:00:00.000Z ### Change permalink: 2021/05/02/sqlservercleanupqueries/ --> sqlservercleanupqueries/
2021-05-01T16:00:00.000Z ### Change permalink: 2021/05/02/sqlservercleanupqueries.en/ --> sqlservercleanupqueries.en/
INFO Files loaded in 1.99 s
...