跳转至

mkdocs-document-dates

English | 简体中文


A new generation MkDocs plugin for displaying exact creation time, last update time, authors, email of documents

render

Features

  • Always displays exact meta information of the document and works in any environment (no Git, Git environments, Docker containers, all CI/CD build systems, etc.)
  • Support list display of recently updated documents (in descending order of update time)
  • Support for manually specifying time and author in Front Matter
  • Support for multiple time formats (date, datetime, timeago)
  • Support for multiple author modes (avatar, text, hidden)
  • Support for manually configuring author's name, link, avatar, email, etc.
  • Flexible display position (top or bottom)
  • Elegant styling (fully customizable)
  • Smart Tooltip Hover Tips
  • Multi-language support, localization support, intelligent recognition of user language, automatic adaptation
  • Cross-platform support (Windows, macOS, Linux)
  • Ultimate build efficiency: O(1), no need to set the env var !ENV to distinguish runs

    Build Speed Comparison: 100 md: 1000 md: Time Complexity:
    git-revision-date-localized > 3 s > 30 s O(n)
    document-dates < 0.1 s < 0.15 s O(1)

Installation

pip install mkdocs-document-dates

Configuration

Just add the plugin to your mkdocs.yml:

plugins:
  - document-dates

Or, full configuration:

plugins:
  - document-dates:
      position: top            # Display position: top(after title) bottom(end of document)
      type: date               # Date type: date datetime timeago, default: date
      exclude:                 # List of excluded files
        - temp.md                  # Example: exclude the specified file
        - blog/*                   # Example: exclude all files in blog folder, including subfolders
      date_format: '%Y-%m-%d'  # Date format strings (e.g., %Y-%m-%d, %b %d, %Y)
      time_format: '%H:%M:%S'  # Time format strings (valid only if type=datetime)
      show_author: true        # Author display mode: true(avatar) text(text) false(hidden)

Specify Datetime

Priority: The plugin will automatically get the exact time information of the document in the following order, and will automatically cache the creation time

%%{init: {'theme': 'default', 'themeVariables': {'fontSize': '12px'}}}%%
flowchart LR
    A(Front Matter)
    B(Cached File)
    C(Git Timestamp)
    D(File Timestamp)
    A -.Creation time.-> B -.-> C -.-> D
    A -.Last updated.-> C

Customization: can be specified manually in Front Matter using the following fields

  • Creation time: created, date
  • Last updated: modified, updated
---
created: 2023-01-01
modified: 2025-02-23
---

Specify Author

Priority: The plugin will automatically get the author information of the document in the following order, and will automatically parse the email and then do the linking

%%{init: {'theme': 'default', 'themeVariables': {'fontSize': '12px'}}}%%
flowchart LR
    A(Front Matter)
    B(Git Author)
    C(site_author)
    D(PC Username)
    A -.-> B -.-> C -.-> D

Customization

Can be configured in Front Matter in the following ways:

1) Configure a simple author: via field name

---
name: any-name
email: e-name@gmail.com
---

2) Configure one or more authors: via field authors

---
authors:
  - jaywhj
  - dawang
  - sunny
---

Enhanced author configuration

For a better user experience, you can add full configuration for all authors. To do so, create an authors.yml file in the docs/ folder using the format below:

docs/authors.yml
authors:
  jaywhj:
    name: Aaron Wang
    avatar: https://xxx.com/avatar.jpg
    url: https://jaywhj.netlify.app/
    email: junewhj@qq.com
    description: Minimalism
  user2:
    name: xxx
    avatar: assets/avatar.png
    url: https://xxx.com
    email: xxx@gmail.com
    description: xxx

When the author name in Front Matter, Git Author, site_author(mkdocs.yml) matches the key in authors, the full author information of the key will be automatically loaded

Git-Author aggregation

Git-Author support account aggregation, i.e. multiple different email accounts for the same person can be aggregated to show the same author, which can be configured by providing a .mailmap file in the repository root directory, see gitmailmap for more details

The following example aggregates a gmail account into a qq account and displays it uniformly as Aaron:

.mailmap
Aaron <junewhj@qq.com> <aaron@gmail.com>

Specify Avatar

Priority: The plugin will automatically loads the author avatar in the following order

%%{init: {'theme': 'default', 'themeVariables': {'fontSize': '12px'}}}%%
flowchart LR
    A(Front Matter)
    B(GitHub Avatar)
    C(Character Avatar)
    A -.-> B -.-> C

Customization:

Customizable via avatar field in Enhanced author configuration (supports URL paths and local file paths)

Others

Parsing the repo_url property in mkdocs.yml for autoloading

Automatically generated based on the author's name with the following rules:
1. Extract initials: English takes the combination of initials, other languages take the first character
2. Generate dynamic background color: Generate HSL color based on the hash of the name

Set Plugin Style

Plugin styles such as icons, themes, colors, fonts, animations, dividing line, etc. can be quickly set through the pre-set portals, you just need to find the file below and uncomment it:

Category: Location:
Style & Theme docs/assets/document_dates/user.config.css
Properties & Functions docs/assets/document_dates/user.config.js

customization

Add Localization Language

The plugin's tooltip and timeago have built-in multi-language support, and the locale is automatically detected, so you don't need to configure it manually. If any language is missing, you can add it for them:

tooltip

Built-in locales: en zh zh_TW es fr de ar ja ko ru nl pt

Addition Method (choose one):

  • In user.config.js, refer to Part 3 to add it by registering yourself
  • Submit a PR for Inclusion

timeago

When type: timeago is set, the timeago.js library is enabled for dynamic time rendering. The built-in locales in timeago.min.js only include en zh. If you need to load other languages, you can configure it as described below (choose one):

  • In user.config.js, refer to Part 2 to add it by registering yourself
  • In mkdocs.yml, configure the full version of timeago.full.min.js to reload all locales
    extra_javascript:
      - assets/document_dates/core/timeago.full.min.js
    

Use Template Variables

You can access the meta-info of a document in a template using the following variables:

  • page.meta.document_dates_created
  • page.meta.document_dates_modified
  • page.meta.document_dates_authors
  • config.extra.recently_updated_docs

Usage examples:

  • Example 1: Set the correct lastmod for your site's sitemap.xml so that search engines can better handle SEO and thus increase your site's exposure (download sitemap.xml and override this path: docs/overrides/sitemap.xml)
  • Example 2: Using the template to re-customize the plugin, you have full control over the rendering logic and the plugin is only responsible for providing the data (download the template source-file.html and override this path: docs/overrides/partials/source-file.html, then freely customize the template code)

Add Recently Updated Module

You can get the recently updated document data (in descending order of update time) in any template via the variable config.extra.recently_updated_docs, then customize the rendering logic yourself

Or refer to the following example and use the preset template directly:

Add to sidebar navigation

1) Configure the switch recently-updated in mkdocs.yml:

- document-dates:
    ...
    recently-updated:
      limit: 10        # Limit the number of docs displayed
      exclude:         # Exclude documents you don't want to show
        - index.md

2) Download nav.html and override this path docs/overrides/partials/nav.html

Add to any location in any document

1) Configure the switch recently-updated in mkdocs.yml:

- document-dates:
    ...
    recently-updated:
      limit: 10        # Limit the number of docs displayed
      exclude:         # Exclude documents you don't want to show
        - index.md

2) Insert this line anywhere in your document:

<!-- RECENTLY_UPDATED_DOCS -->

recently-updated

If you only want to use the "Recently Updated Module", you can also install the separate plugin mkdocs-recently-updated-docs

Other Tips

  1. Git's git checkout, git clone, etc. will "rebuild the file", which results in the loss of the original timestamp of the branch/file that was cloned or checked out
    • This is due to Git's internal principle, which is content-addressable storage, not direct storage, so when you checkout, clone, merge, rebase, etc., Git will extract the corresponding blob from the object database (or packfile) and write it to disk as the workspace file, i.e. "rebuild file", resulting in the loss of the original timestamp
  2. In order to always get the exact creation time, a separate file is used to store the original creation time of the document, located in the docs folder (hidden by default), please don't remove it:
    • docs/.dates_cache.jsonl, cache file
    • docs/.gitattributes, merge mechanism for cache file
  3. The Git Hooks mechanism is used to automatically trigger the storing of the cache (on each git commit), and the cached file is automatically committed along with it, in addition, the installation of Git Hooks is automatically triggered when the plugin is installed, without any manual intervention
    • Make sure you run git commit from a terminal, not directly from integration tools like VSCode, which has bugs when integrating Git hooks
  4. When running in Docker, you need to set the HOME environment variable first, because installing Git Hooks requires a writable user configuration directory. For example, add the following configuration to your docker-compose.yml:
    environment:
      - HOME=/docs
    working_dir: /docs
    volumes:
      - ./mkdocs:/docs
    

Development Stories

A dispensable, insignificant little plug-in, friends who have time can take a look ^_^

  • Origin:
    • Because git-revision-date-localized, a great project. When I used it at the end of 2024, I found that I couldn't use it locally because my mkdocs documentation was not included in git management, I don't understand why not read the file timestamp, but to use the git timestamp, and the file timestamp is exact, then raised an issue to the author, but didn't get a reply for about a week (the author had a reply later, nice guy, I guess he was busy at the time), and then I thought, there is nothing to do during the Chinese New Year, and now AI is so hot, why not with the help of the AI try it out for myself, it was born, born in February 2025
  • Iteration:
    • After development, I understood why not use file timestamp, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information. There are many solutions:
    • Method 1: Use the last git commit time as the last update time and the first git commit time as the creation time, git-revision-date-localized does this. (This way, there will be a margin of error and dependency on git)
    • Method 2: Cache the original time in advance, and then read the cache subsequently (The time is exact and no dependency on any environment). The cache can be in Front Matter of the source document or in a separate file, I chose the latter. Storing in Front Matter makes sense and is easier, but this will modify the source content of the document, although it doesn't have any impact on the body, but I still want to ensure the originality of the data!
  • Difficulty:
    1. When to read and store original time? This is just a plugin for mkdocs, with very limited access and permissions, mkdocs provides only build and serve, so in case a user commits directly without executing build or serve (e.g., when using a CI/CD build system), then you won't be able to retrieve the time information of the file, not to mention caching it!
      • Straight to the bottom line: Git Hooks can be used to trigger custom scripts when specific git actions occur, such as every time a commit occurs
    2. How to install Git Hooks automatically? When and how are they triggered? Installing packages from PyPI via pip doesn't have a standard post-install hook mechanism
      • Workaround: After analyzing the flow of pip installing packages from PyPI, I found that when compiling and installing through the source package (sdist), setuptools will be called to handle it, so we can find a way to implant the installation script in the process of setuptools, i.e., we can add a custom script in setup.py
    3. How to design a cross-platform hook? To execute a python script, we need to explicitly specify the python interpreter, and the user's python environment varies depending on the operating system, the way python is installed, and the configuration, so how can we ensure that it works properly in all environments?
      • Solution: I considered using a shell script, but since I'd have to call back to python eventually, it's easier to use a python script. We can detect the user's python environment when the hook is installed, and then dynamically set the hook's shebang line to set the correct python interpreter
    4. How can I ensure that a single cache file does not conflict when collaborating with multi-person?
      • Workaround: use JSONL (JSON Lines) instead of JSON, and with the merge strategy merge=union
    5. How to reduce build time when there are a lot of documents ( >1000 )? Every time you fetch a git information, it's usually a file I/O operation, and if there are a lot of files, it can slow down the build considerably, which is intolerable for users (e.g., to improve preview speed, git-revision-date-localized can only disable itself locally by adding the environment variable enabled: !ENV)
      • Solution: Reduce or fix the number of I/Os + Use caching + Replace less efficient system functions
  • Improve:
    • Since it's a newly developed plugin, it will be designed in the direction of excellent products, and the pursuit of the ultimate ease of use, simplicity, personalization, intelligence
      • Ease of use: no complex configuration, only 2-3 commonly used configuration items, in addition to providing the reference template for personalized configurations
      • Simplicity: no unnecessary configuration, no Git dependencies, no CI/CD configuration dependencies, no other package dependencies
      • Personalization: fully customizable and full control over the rendering logic, the plugin is only responsible for providing the data
      • Intelligence: Intelligent parsing of document time, author, avatar, intelligent recognition of the user's language and automatic adaptation, in addition, there are auto-install Git Hooks, auto-cache, auto-commit
      • Compatibility: works well on older operating systems and browsers, such as WIN7, MacOS 10.11, iOS 12, Chrome 63.0.3239
  • The Last Secret:
    • Programming is a hobby, and I'm a marketer of 8 years (Feel free to leave a comment)

Comments Section