A Permalink is a unique URL for a page that doesnโ€™t change. This is useful to avoid broken links when moving pages around. I have always used the folder structure for URLs, but this started feeling restrictive after a while.

This document explains the process of introducing this concept in ๐ŸŒ My Website Generator.

Requirements

Places that will most likely require changes:

  • Generate a file for URL rewrites
  • Website startup code in main.py to make sure that the URL rewrites are applied
  • Checking for duplicate permalinks
  • get_relative_url in SourceFile (this also impacts the generated Sitemap)
  • URL rewrites in _change_markdown_link_pages_prefix in MarkdownSourceFile

get_relative_url in SourceFile

Returns the permalink if it exists, otherwise, it returns the relative URL based on the folder for backward compatibility.

Untested code:

    def get_permalink(self):
        with open(self.source_path, 'r') as f:
            input = f.read()
        
        metadata = re.match(r'---(.*?)---', input, flags=re.DOTALL | re.MULTILINE)
 
        parsed_metadata = yaml.safe_load(metadata)
        return parsed_metadata['permalink']

Website startup code

An example of what this would look like in server.js:

var permalinks = [
  {
    old: '/test',
    new: '/topics/programming/'
  }
]
permalinks.forEach((element) => {
  app.get(element.old, (req, res, next) => {
    req.url = element.new
    next()
  })
})

Generate a file for URL rewrites

This will be very similar to the current structure of migrated-urls.yaml.

A folder structure makes it very easy to avoid duplicates because itโ€™s not possible to store two files with the same path and filename. With permalinks, additional validation is required to prevent duplicates.