mkdocs-document-dates 3.1.5__tar.gz → 3.1.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mkdocs_document_dates-3.1.6/MANIFEST.in +2 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/PKG-INFO +34 -14
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/README.md +33 -13
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/cache_manager.py +69 -76
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/hooks_installer.py +2 -14
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/plugin.py +72 -120
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/config/user.config.css +6 -6
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/core/core.css +8 -7
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/PKG-INFO +34 -14
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/SOURCES.txt +1 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/setup.py +2 -4
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/LICENSE +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/__init__.py +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/hooks/pre-commit +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/config/user.config.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/core/core.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/core/timeago-load.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/core/timeago.full.min.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/core/timeago.min.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/ar.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/de.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/en.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/es.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/fr.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/ja.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/ko.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/ru.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/zh.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/languages/zh_TW.json +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/backdrop.css +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/light.css +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/material.css +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/popper.min.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/scale.css +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/shift-away.css +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/tippy.css +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/static/tippy/tippy.umd.min.js +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/dependency_links.txt +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/entry_points.txt +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/requires.txt +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/top_level.txt +0 -0
- {mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mkdocs-document-dates
|
3
|
-
Version: 3.1.
|
3
|
+
Version: 3.1.6
|
4
4
|
Summary: An easy-to-use, lightweight MkDocs plugin for displaying the exact creation time, last modification time and author info of markdown documents.
|
5
5
|
Home-page: https://github.com/jaywhj/mkdocs-document-dates
|
6
6
|
Author: Aaron Wang
|
@@ -38,14 +38,11 @@ An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark>
|
|
38
38
|
- Always display exact meta-info of the document for any environment (no-Git, Git, all CI/CD build systems, etc)
|
39
39
|
- Support for manually specifying time and author in `Front Matter`
|
40
40
|
- Support for multiple time formats (date, datetime, timeago)
|
41
|
-
- Support for document exclusion mode
|
42
41
|
- Flexible display position (top or bottom)
|
43
42
|
- Elegant styling (fully customizable)
|
44
43
|
- Supports Tooltip Hover Tips
|
45
44
|
- Intelligent repositioning to always float optimally in view
|
46
45
|
- Supports automatic theme switching following Material's light/dark color scheme
|
47
|
-
- Support for customizing themes, styles, animations
|
48
|
-
- Compatible with mouse, keyboard and **touch** (mobile) to trigger hover
|
49
46
|
- Multi-language support, cross-platform support (Windows, macOS, Linux)
|
50
47
|
|
51
48
|
## Showcases
|
@@ -80,9 +77,7 @@ plugins:
|
|
80
77
|
exclude: # List of excluded files
|
81
78
|
- temp.md # Exclude specific file
|
82
79
|
- private/* # Exclude all files in private directory, including subdirectories
|
83
|
-
|
84
80
|
show_author: true # Show author or not, default: true
|
85
|
-
|
86
81
|
```
|
87
82
|
|
88
83
|
## Specify time manually
|
@@ -123,7 +118,7 @@ email: e-name@gmail.com
|
|
123
118
|
|
124
119
|
## Customization
|
125
120
|
|
126
|
-
The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc.
|
121
|
+
The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc. Everything is customizable (I've already written the code, you just need to turn on the uncomment switch):
|
127
122
|
|
128
123
|
| Function: | Location: |
|
129
124
|
| :----------------------: | ---------------------------------------- |
|
@@ -131,7 +126,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
131
126
|
| **Properties & Functions** | `docs/assets/document_dates/user.config.js` |
|
132
127
|
| **Localized languages** | `docs/assets/document_dates/languages/` <br />refer to the template file `en.json` for any additions or modifications |
|
133
128
|
|
134
|
-
**Tip**: when `type: timeago` is set, timeago.js is enabled to render time
|
129
|
+
**Tip**: when `type: timeago` is set, timeago.js is enabled to render dynamic time, `timeago.min.js` only contains English and Chinese by default, if you need to load other languages, you can configure it as below (choose one):
|
135
130
|
|
136
131
|
- In `user.config.js`, refer to [the demo commented out](https://github.com/jaywhj/mkdocs-document-dates/blob/main/mkdocs_document_dates/static/config/user.config.js) at the bottom, translate it into your local language
|
137
132
|
- In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
|
@@ -150,12 +145,37 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
150
145
|

|
151
146
|
|
152
147
|

|
153
|
-

|
154
148
|

|
155
149
|
|
150
|
+
## Used in templates
|
151
|
+
|
152
|
+
You can access the meta-info of a document in a template using the following variables:
|
153
|
+
|
154
|
+
- page.meta.document_dates_created
|
155
|
+
- page.meta.document_dates_modified
|
156
|
+
- page.meta.document_dates_authors
|
157
|
+
|
158
|
+
For example like this:
|
159
|
+
|
160
|
+
```jinja2
|
161
|
+
<div><span>{{ page.meta.document_dates_created }}</span></div>
|
162
|
+
<div><span>{{ page.meta.document_dates_modified }}</span></div>
|
163
|
+
{% set authors = page.meta.document_dates_authors %}
|
164
|
+
{% if authors %}
|
165
|
+
<div>
|
166
|
+
{% for author in authors %}
|
167
|
+
{% if author.email %}<a href="mailto:{{ author.email }}">{{ author.name }}</a>
|
168
|
+
{% else %}<span>{{ author.name }}</span>{% endif %}
|
169
|
+
{% endfor %}
|
170
|
+
</div>
|
171
|
+
{% endif %}
|
172
|
+
```
|
173
|
+
|
174
|
+
**Full example**: set the correct lastmod for [sitemap.xml](https://github.com/jaywhj/mkdocs-document-dates/blob/main/sitemap.xml) so that search engines can better handle SEO and thus increase your site's exposure (override path: `docs/overrides/sitemap.xml`)
|
175
|
+
|
156
176
|
## Other Tips
|
157
177
|
|
158
|
-
- In order to always get the exact creation time, a separate cache file is used to store the creation time of the document, located in the docs folder (hidden by default), please don't
|
178
|
+
- In order to always get the exact creation time, a separate cache file is used to store the creation time of the document, located in the docs folder (hidden by default), please don't remove it:
|
159
179
|
- `docs/.dates_cache.jsonl`, cache file
|
160
180
|
- `docs/.gitattributes`, merge mechanism for cache file
|
161
181
|
- 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!
|
@@ -167,11 +187,11 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
167
187
|
A dispensable, insignificant little plug-in, friends who have time can take a look \^\_\^
|
168
188
|
|
169
189
|
- **Origin**:
|
170
|
-
- Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), 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 system time, but to use the git time, and the filesystem time is
|
190
|
+
- Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), 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 system time, but to use the git time, and the filesystem time 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
|
171
191
|
- **Iteration**:
|
172
|
-
- After development, I understood why not use filesystem time, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information
|
173
|
-
- Method 1: Use the last git commit time as the last update time
|
174
|
-
- Method 2:
|
192
|
+
- After development, I understood why not use filesystem time, 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:
|
193
|
+
- Method 1: Use the last git commit time as the last update time and the first git commit time as the creation time, mkdocs-git-revision-date-localized-plugin does this. (This way, there will be a margin of error and dependency on git)
|
194
|
+
- 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!
|
175
195
|
- **Difficulty**:
|
176
196
|
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!
|
177
197
|
- Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific git action occurs, such as every time commit is performed
|
@@ -11,14 +11,11 @@ An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark>
|
|
11
11
|
- Always display exact meta-info of the document for any environment (no-Git, Git, all CI/CD build systems, etc)
|
12
12
|
- Support for manually specifying time and author in `Front Matter`
|
13
13
|
- Support for multiple time formats (date, datetime, timeago)
|
14
|
-
- Support for document exclusion mode
|
15
14
|
- Flexible display position (top or bottom)
|
16
15
|
- Elegant styling (fully customizable)
|
17
16
|
- Supports Tooltip Hover Tips
|
18
17
|
- Intelligent repositioning to always float optimally in view
|
19
18
|
- Supports automatic theme switching following Material's light/dark color scheme
|
20
|
-
- Support for customizing themes, styles, animations
|
21
|
-
- Compatible with mouse, keyboard and **touch** (mobile) to trigger hover
|
22
19
|
- Multi-language support, cross-platform support (Windows, macOS, Linux)
|
23
20
|
|
24
21
|
## Showcases
|
@@ -53,9 +50,7 @@ plugins:
|
|
53
50
|
exclude: # List of excluded files
|
54
51
|
- temp.md # Exclude specific file
|
55
52
|
- private/* # Exclude all files in private directory, including subdirectories
|
56
|
-
|
57
53
|
show_author: true # Show author or not, default: true
|
58
|
-
|
59
54
|
```
|
60
55
|
|
61
56
|
## Specify time manually
|
@@ -96,7 +91,7 @@ email: e-name@gmail.com
|
|
96
91
|
|
97
92
|
## Customization
|
98
93
|
|
99
|
-
The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc.
|
94
|
+
The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc. Everything is customizable (I've already written the code, you just need to turn on the uncomment switch):
|
100
95
|
|
101
96
|
| Function: | Location: |
|
102
97
|
| :----------------------: | ---------------------------------------- |
|
@@ -104,7 +99,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
104
99
|
| **Properties & Functions** | `docs/assets/document_dates/user.config.js` |
|
105
100
|
| **Localized languages** | `docs/assets/document_dates/languages/` <br />refer to the template file `en.json` for any additions or modifications |
|
106
101
|
|
107
|
-
**Tip**: when `type: timeago` is set, timeago.js is enabled to render time
|
102
|
+
**Tip**: when `type: timeago` is set, timeago.js is enabled to render dynamic time, `timeago.min.js` only contains English and Chinese by default, if you need to load other languages, you can configure it as below (choose one):
|
108
103
|
|
109
104
|
- In `user.config.js`, refer to [the demo commented out](https://github.com/jaywhj/mkdocs-document-dates/blob/main/mkdocs_document_dates/static/config/user.config.js) at the bottom, translate it into your local language
|
110
105
|
- In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
|
@@ -123,12 +118,37 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
123
118
|

|
124
119
|
|
125
120
|

|
126
|
-

|
127
121
|

|
128
122
|
|
123
|
+
## Used in templates
|
124
|
+
|
125
|
+
You can access the meta-info of a document in a template using the following variables:
|
126
|
+
|
127
|
+
- page.meta.document_dates_created
|
128
|
+
- page.meta.document_dates_modified
|
129
|
+
- page.meta.document_dates_authors
|
130
|
+
|
131
|
+
For example like this:
|
132
|
+
|
133
|
+
```jinja2
|
134
|
+
<div><span>{{ page.meta.document_dates_created }}</span></div>
|
135
|
+
<div><span>{{ page.meta.document_dates_modified }}</span></div>
|
136
|
+
{% set authors = page.meta.document_dates_authors %}
|
137
|
+
{% if authors %}
|
138
|
+
<div>
|
139
|
+
{% for author in authors %}
|
140
|
+
{% if author.email %}<a href="mailto:{{ author.email }}">{{ author.name }}</a>
|
141
|
+
{% else %}<span>{{ author.name }}</span>{% endif %}
|
142
|
+
{% endfor %}
|
143
|
+
</div>
|
144
|
+
{% endif %}
|
145
|
+
```
|
146
|
+
|
147
|
+
**Full example**: set the correct lastmod for [sitemap.xml](https://github.com/jaywhj/mkdocs-document-dates/blob/main/sitemap.xml) so that search engines can better handle SEO and thus increase your site's exposure (override path: `docs/overrides/sitemap.xml`)
|
148
|
+
|
129
149
|
## Other Tips
|
130
150
|
|
131
|
-
- In order to always get the exact creation time, a separate cache file is used to store the creation time of the document, located in the docs folder (hidden by default), please don't
|
151
|
+
- In order to always get the exact creation time, a separate cache file is used to store the creation time of the document, located in the docs folder (hidden by default), please don't remove it:
|
132
152
|
- `docs/.dates_cache.jsonl`, cache file
|
133
153
|
- `docs/.gitattributes`, merge mechanism for cache file
|
134
154
|
- 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!
|
@@ -140,11 +160,11 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
140
160
|
A dispensable, insignificant little plug-in, friends who have time can take a look \^\_\^
|
141
161
|
|
142
162
|
- **Origin**:
|
143
|
-
- Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), 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 system time, but to use the git time, and the filesystem time is
|
163
|
+
- Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), 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 system time, but to use the git time, and the filesystem time 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
|
144
164
|
- **Iteration**:
|
145
|
-
- After development, I understood why not use filesystem time, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information
|
146
|
-
- Method 1: Use the last git commit time as the last update time
|
147
|
-
- Method 2:
|
165
|
+
- After development, I understood why not use filesystem time, 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:
|
166
|
+
- Method 1: Use the last git commit time as the last update time and the first git commit time as the creation time, mkdocs-git-revision-date-localized-plugin does this. (This way, there will be a margin of error and dependency on git)
|
167
|
+
- 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!
|
148
168
|
- **Difficulty**:
|
149
169
|
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!
|
150
170
|
- Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific git action occurs, such as every time commit is performed
|
{mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/cache_manager.py
RENAMED
@@ -26,7 +26,7 @@ def find_mkdocs_projects():
|
|
26
26
|
projects.append(config_file.parent)
|
27
27
|
|
28
28
|
if not projects:
|
29
|
-
logging.
|
29
|
+
logging.warning("No MkDocs projects found in the repository")
|
30
30
|
except subprocess.CalledProcessError as e:
|
31
31
|
logging.error(f"Failed to find the Git repository root: {e}")
|
32
32
|
except Exception as e:
|
@@ -67,7 +67,7 @@ def setup_gitattributes(docs_dir):
|
|
67
67
|
updated = False
|
68
68
|
try:
|
69
69
|
gitattributes_path = docs_dir / '.gitattributes'
|
70
|
-
union_config_line = ".dates_cache.jsonl merge=union"
|
70
|
+
union_config_line = ".dates_cache.jsonl merge=union"
|
71
71
|
if gitattributes_path.exists():
|
72
72
|
with open(gitattributes_path, 'r', encoding='utf-8') as f:
|
73
73
|
content = f.read()
|
@@ -98,7 +98,7 @@ def read_json_cache(cache_file):
|
|
98
98
|
with open(cache_file, "r", encoding='utf-8') as f:
|
99
99
|
dates_cache = json.load(f)
|
100
100
|
except (IOError, json.JSONDecodeError) as e:
|
101
|
-
logging.
|
101
|
+
logging.warning(f"Error reading from '.dates_cache.json': {str(e)}")
|
102
102
|
return dates_cache
|
103
103
|
|
104
104
|
def read_jsonl_cache(jsonl_file):
|
@@ -115,7 +115,7 @@ def read_jsonl_cache(jsonl_file):
|
|
115
115
|
except (json.JSONDecodeError, StopIteration) as e:
|
116
116
|
logging.warning(f"Skipping invalid JSONL line: {e}")
|
117
117
|
except IOError as e:
|
118
|
-
logging.
|
118
|
+
logging.warning(f"Error reading from '.dates_cache.jsonl': {str(e)}")
|
119
119
|
return dates_cache
|
120
120
|
|
121
121
|
def write_jsonl_cache(jsonl_file, dates_cache, tracked_files):
|
@@ -144,88 +144,81 @@ def write_jsonl_cache(jsonl_file, dates_cache, tracked_files):
|
|
144
144
|
|
145
145
|
def update_cache():
|
146
146
|
global_updated = False
|
147
|
-
try:
|
148
|
-
for project_dir in find_mkdocs_projects():
|
149
|
-
try:
|
150
|
-
project_updated = False
|
151
147
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
continue
|
148
|
+
for project_dir in find_mkdocs_projects():
|
149
|
+
try:
|
150
|
+
project_updated = False
|
156
151
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
152
|
+
docs_dir = project_dir / 'docs'
|
153
|
+
if not docs_dir.exists():
|
154
|
+
logging.error(f"Document directory does not exist: {docs_dir}")
|
155
|
+
continue
|
161
156
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
157
|
+
# 设置.gitattributes文件
|
158
|
+
gitattributes_updated = setup_gitattributes(docs_dir)
|
159
|
+
if gitattributes_updated:
|
160
|
+
global_updated = True
|
166
161
|
|
167
|
-
|
168
|
-
|
169
|
-
|
162
|
+
# 获取docs目录下已跟踪(tracked)的markdown文件
|
163
|
+
cmd = ["git", "ls-files", "*.md"]
|
164
|
+
result = subprocess.run(cmd, cwd=docs_dir, capture_output=True, text=True, check=True)
|
165
|
+
tracked_files = result.stdout.splitlines() if result.stdout else []
|
170
166
|
|
171
|
-
|
172
|
-
|
173
|
-
|
167
|
+
if not tracked_files:
|
168
|
+
logging.info(f"No tracked markdown files found in {docs_dir}")
|
169
|
+
continue
|
174
170
|
|
175
|
-
|
176
|
-
|
177
|
-
|
171
|
+
# 读取旧的JSON缓存文件(如果存在)
|
172
|
+
json_cache_file = docs_dir / '.dates_cache.json'
|
173
|
+
json_dates_cache = read_json_cache(json_cache_file)
|
178
174
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
# 处理新文件或迁移旧JSON缓存
|
190
|
-
if rel_path in json_dates_cache:
|
191
|
-
jsonl_dates_cache[rel_path] = json_dates_cache[rel_path]
|
192
|
-
project_updated = True
|
193
|
-
elif full_path.exists():
|
194
|
-
created_time = get_file_creation_time(full_path)
|
195
|
-
if not jsonl_cache_file.exists() and not json_cache_file.exists():
|
196
|
-
git_time = get_git_first_commit_time(full_path)
|
197
|
-
if git_time is not None:
|
198
|
-
created_time = min(created_time, git_time)
|
199
|
-
jsonl_dates_cache[rel_path] = {
|
200
|
-
"created": created_time.isoformat()
|
201
|
-
}
|
202
|
-
project_updated = True
|
203
|
-
except Exception as e:
|
204
|
-
logging.error(f"Error processing file {file_path}: {e}")
|
175
|
+
# 读取新的JSONL缓存文件(如果存在)
|
176
|
+
jsonl_cache_file = docs_dir / '.dates_cache.jsonl'
|
177
|
+
jsonl_dates_cache = read_jsonl_cache(jsonl_cache_file)
|
178
|
+
|
179
|
+
# 根据 git已跟踪的文件来更新
|
180
|
+
for rel_path in tracked_files:
|
181
|
+
try:
|
182
|
+
# 如果文件已在JSONL缓存中,跳过
|
183
|
+
if rel_path in jsonl_dates_cache:
|
205
184
|
continue
|
206
185
|
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
186
|
+
full_path = docs_dir / rel_path
|
187
|
+
# 处理新文件或迁移旧JSON缓存
|
188
|
+
if rel_path in json_dates_cache:
|
189
|
+
jsonl_dates_cache[rel_path] = json_dates_cache[rel_path]
|
190
|
+
project_updated = True
|
191
|
+
elif full_path.exists():
|
192
|
+
created_time = get_file_creation_time(full_path)
|
193
|
+
if not jsonl_cache_file.exists() and not json_cache_file.exists():
|
194
|
+
git_time = get_git_first_commit_time(full_path)
|
195
|
+
if git_time:
|
196
|
+
created_time = min(created_time, git_time)
|
197
|
+
jsonl_dates_cache[rel_path] = {
|
198
|
+
"created": created_time.isoformat()
|
199
|
+
}
|
200
|
+
project_updated = True
|
201
|
+
except Exception as e:
|
202
|
+
logging.error(f"Error processing file {rel_path}: {e}")
|
203
|
+
continue
|
204
|
+
|
205
|
+
# 标记删除不再跟踪的文件
|
206
|
+
files_to_remove = set(jsonl_dates_cache.keys()) - set(tracked_files)
|
207
|
+
if files_to_remove:
|
208
|
+
project_updated = True
|
209
|
+
logging.info(f"Removing {len(files_to_remove)} untracked files from cache")
|
210
|
+
|
211
|
+
# 如果有更新,写入JSONL缓存文件
|
212
|
+
if project_updated or not jsonl_cache_file.exists():
|
213
|
+
if write_jsonl_cache(jsonl_cache_file, jsonl_dates_cache, tracked_files):
|
214
|
+
global_updated = True
|
215
|
+
except subprocess.CalledProcessError as e:
|
216
|
+
logging.error(f"Failed to execute git command: {e}")
|
217
|
+
continue
|
218
|
+
except Exception as e:
|
219
|
+
logging.error(f"Error processing project directory {project_dir}: {e}")
|
220
|
+
continue
|
225
221
|
|
226
|
-
except Exception as e:
|
227
|
-
logging.error(f"Unexpected error in update_cache: {e}")
|
228
|
-
|
229
222
|
return global_updated
|
230
223
|
|
231
224
|
|
{mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/hooks_installer.py
RENAMED
@@ -43,14 +43,6 @@ def detect_python_interpreter():
|
|
43
43
|
# 如果都失败了,使用当前运行的Python解释器
|
44
44
|
return f'#!{sys.executable}'
|
45
45
|
|
46
|
-
def check_git_available():
|
47
|
-
try:
|
48
|
-
subprocess.run(['git', '--version'], check=True, capture_output=True, encoding='utf-8')
|
49
|
-
return True
|
50
|
-
except Exception:
|
51
|
-
logging.warning("Git not detected, skip hooks installation")
|
52
|
-
return False
|
53
|
-
|
54
46
|
def setup_hooks_directory():
|
55
47
|
config_dir = get_config_dir() / 'mkdocs-document-dates' / 'hooks'
|
56
48
|
try:
|
@@ -95,16 +87,12 @@ def configure_git_hooks(hooks_dir):
|
|
95
87
|
)
|
96
88
|
logging.info(f"Git hooks successfully installed in: {hooks_dir}")
|
97
89
|
return True
|
98
|
-
except Exception
|
99
|
-
logging.
|
90
|
+
except Exception:
|
91
|
+
logging.warning("Git not detected, failed to set git hooks path")
|
100
92
|
return False
|
101
93
|
|
102
94
|
def install():
|
103
95
|
try:
|
104
|
-
# 检查git是否可用
|
105
|
-
if not check_git_available():
|
106
|
-
return False
|
107
|
-
|
108
96
|
# 创建hooks目录
|
109
97
|
hooks_dir = setup_hooks_directory()
|
110
98
|
if not hooks_dir:
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import os
|
2
2
|
import json
|
3
3
|
import shutil
|
4
|
-
import platform
|
5
4
|
import logging
|
6
5
|
import subprocess
|
7
6
|
from datetime import datetime
|
8
7
|
from pathlib import Path
|
9
8
|
from mkdocs.plugins import BasePlugin
|
10
9
|
from mkdocs.config import config_options
|
10
|
+
from .cache_manager import read_json_cache, read_jsonl_cache, get_file_creation_time, get_git_first_commit_time
|
11
11
|
|
12
12
|
# 配置日志等级 (INFO WARNING ERROR)
|
13
13
|
logging.basicConfig(
|
@@ -80,44 +80,15 @@ class DocumentDatesPlugin(BasePlugin):
|
|
80
80
|
|
81
81
|
# 加载日期缓存
|
82
82
|
jsonl_cache_file = docs_dir_path / '.dates_cache.jsonl'
|
83
|
-
|
84
|
-
|
85
|
-
with open(jsonl_cache_file, "r", encoding='utf-8') as f:
|
86
|
-
for line in f:
|
87
|
-
try:
|
88
|
-
entry = json.loads(line.strip())
|
89
|
-
if entry and isinstance(entry, dict) and len(entry) == 1:
|
90
|
-
file_path, file_info = next(iter(entry.items()))
|
91
|
-
self.dates_cache[file_path] = file_info
|
92
|
-
except (json.JSONDecodeError, StopIteration) as e:
|
93
|
-
logging.warning(f"Skipping invalid JSONL line: {e}")
|
94
|
-
logging.info(f"Loaded cache from JSONL file: {jsonl_cache_file}")
|
95
|
-
except IOError as e:
|
96
|
-
logging.warning(f"Error reading from '.dates_cache.jsonl': {str(e)}")
|
97
|
-
|
83
|
+
self.dates_cache = read_jsonl_cache(jsonl_cache_file)
|
84
|
+
|
98
85
|
# 兼容旧版缓存文件
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
self.dates_cache = json.load(f)
|
104
|
-
logging.info(f"Loaded cache from JSON file: {json_cache_file}")
|
105
|
-
except (json.JSONDecodeError, KeyError) as e:
|
106
|
-
logging.warning(f"Error reading from '.dates_cache.json': {str(e)}")
|
107
|
-
|
108
|
-
|
109
|
-
if 'extra_css' not in config:
|
110
|
-
config['extra_css'] = []
|
111
|
-
if 'extra_javascript' not in config:
|
112
|
-
config['extra_javascript'] = []
|
113
|
-
|
114
|
-
# 加载图标 Google Fonts Icons: https://fonts.google.com/icons
|
115
|
-
material_icons_url = 'https://fonts.googleapis.com/icon?family=Material+Icons'
|
116
|
-
if material_icons_url not in config['extra_css']:
|
117
|
-
config['extra_css'].append(material_icons_url)
|
118
|
-
|
119
|
-
# 加载 Tooltip 资源:Tippy.js
|
86
|
+
if not self.dates_cache:
|
87
|
+
json_cache_file = docs_dir_path / '.dates_cache.json'
|
88
|
+
self.dates_cache = read_json_cache(json_cache_file)
|
89
|
+
|
120
90
|
"""
|
91
|
+
Tippy.js
|
121
92
|
# core
|
122
93
|
https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js
|
123
94
|
https://unpkg.com/tippy.js@6/dist/tippy.umd.min.js
|
@@ -148,12 +119,20 @@ class DocumentDatesPlugin(BasePlugin):
|
|
148
119
|
if not target_config.exists():
|
149
120
|
shutil.copy2(source_config, target_config)
|
150
121
|
|
122
|
+
|
123
|
+
# 加载图标 Google Fonts Icons: https://fonts.google.com/icons
|
124
|
+
material_icons_url = 'https://fonts.googleapis.com/icon?family=Material+Icons'
|
125
|
+
if material_icons_url not in config['extra_css']:
|
126
|
+
config['extra_css'].append(material_icons_url)
|
127
|
+
|
151
128
|
# 加载 timeago.js
|
152
129
|
# https://cdn.jsdelivr.net/npm/timeago.js@4.0.2/dist/timeago.min.js
|
153
130
|
# https://cdnjs.cloudflare.com/ajax/libs/timeago.js/4.0.2/timeago.full.min.js
|
154
131
|
if self.config['type'] == 'timeago':
|
155
|
-
config['extra_javascript']
|
156
|
-
|
132
|
+
config['extra_javascript'][0:0] = [
|
133
|
+
'assets/document_dates/core/timeago.min.js',
|
134
|
+
'assets/document_dates/core/timeago-load.js'
|
135
|
+
]
|
157
136
|
|
158
137
|
# 加载 Tippy CSS 文件
|
159
138
|
tippy_css_dir = dest_dir / 'tippy'
|
@@ -180,42 +159,36 @@ class DocumentDatesPlugin(BasePlugin):
|
|
180
159
|
return config
|
181
160
|
|
182
161
|
def on_page_markdown(self, markdown, page, config, files):
|
183
|
-
file_path = page.file.abs_src_path
|
184
162
|
# 获取相对路径,src_uri 总是以"/"分隔
|
185
163
|
rel_path = getattr(page.file, 'src_uri', None)
|
186
164
|
if not rel_path:
|
187
165
|
rel_path = page.file.src_path
|
188
166
|
if os.sep != '/':
|
189
167
|
rel_path = rel_path.replace(os.sep, '/')
|
190
|
-
|
191
|
-
# 检查是否需要排除
|
192
|
-
if self._is_excluded(rel_path):
|
193
|
-
return markdown
|
168
|
+
file_path = page.file.abs_src_path
|
194
169
|
|
195
|
-
#
|
170
|
+
# 获取时间信息
|
196
171
|
created = self._find_meta_date(page.meta, self.config['created_field_names'])
|
197
172
|
modified = self._find_meta_date(page.meta, self.config['modified_field_names'])
|
198
|
-
|
199
173
|
if not created:
|
200
174
|
created = self._get_file_creation_time(file_path, rel_path)
|
201
175
|
if not modified:
|
202
176
|
modified = self._get_file_modification_time(file_path)
|
203
|
-
|
177
|
+
|
204
178
|
# 获取作者信息
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
author = self._get_local_author()
|
179
|
+
authors = self._get_author_info(file_path, page, config)
|
180
|
+
|
181
|
+
# 在排除前暴露 meta 信息给前端使用
|
182
|
+
page.meta['document_dates_created'] = created.isoformat()
|
183
|
+
page.meta['document_dates_modified'] = modified.isoformat()
|
184
|
+
page.meta['document_dates_authors'] = authors
|
185
|
+
|
186
|
+
# 检查是否需要排除
|
187
|
+
if self._is_excluded(rel_path):
|
188
|
+
return markdown
|
216
189
|
|
217
190
|
# 生成日期和作者信息 HTML
|
218
|
-
info_html = self._generate_html_info(created, modified,
|
191
|
+
info_html = self._generate_html_info(created, modified, authors)
|
219
192
|
|
220
193
|
# 将信息写入 markdown
|
221
194
|
return self._insert_date_info(markdown, info_html)
|
@@ -278,44 +251,20 @@ class DocumentDatesPlugin(BasePlugin):
|
|
278
251
|
continue
|
279
252
|
return None
|
280
253
|
|
281
|
-
def _get_git_first_commit_time(self, file_path):
|
282
|
-
if self.is_git_repo:
|
283
|
-
try:
|
284
|
-
# git log --reverse --format="%aI" --date=iso -- {file_path} | head -n 1
|
285
|
-
result = subprocess.run(['git', 'log', '--reverse', '--format=%aI', '--', file_path], capture_output=True, text=True)
|
286
|
-
if result.returncode == 0:
|
287
|
-
first_line = result.stdout.partition('\n')[0].strip()
|
288
|
-
if first_line:
|
289
|
-
return datetime.fromisoformat(first_line).replace(tzinfo=None)
|
290
|
-
except Exception as e:
|
291
|
-
logging.warning(f"Error getting git first commit time for {file_path}: {e}")
|
292
|
-
return None
|
293
|
-
|
294
254
|
def _get_file_creation_time(self, file_path, rel_path):
|
295
255
|
# 优先从缓存中读取
|
296
256
|
if rel_path in self.dates_cache:
|
297
257
|
return datetime.fromisoformat(self.dates_cache[rel_path]['created'])
|
298
258
|
|
299
|
-
#
|
300
|
-
|
301
|
-
system = platform.system().lower()
|
302
|
-
fs_time = None
|
303
|
-
if system.startswith('win'): # Windows
|
304
|
-
fs_time = datetime.fromtimestamp(stat.st_ctime)
|
305
|
-
elif system == 'darwin': # macOS
|
306
|
-
try:
|
307
|
-
fs_time = datetime.fromtimestamp(stat.st_birthtime)
|
308
|
-
except AttributeError:
|
309
|
-
fs_time = datetime.fromtimestamp(stat.st_ctime)
|
310
|
-
else: # Linux, 没有创建时间,使用修改时间
|
311
|
-
fs_time = datetime.fromtimestamp(stat.st_mtime)
|
259
|
+
# 从文件系统获取
|
260
|
+
fs_time = get_file_creation_time(file_path)
|
312
261
|
|
313
262
|
# 获取Git首次提交时间
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
263
|
+
if self.is_git_repo:
|
264
|
+
git_time = get_git_first_commit_time(file_path)
|
265
|
+
# 取两者更早的时间
|
266
|
+
if git_time:
|
267
|
+
return min(fs_time, git_time)
|
319
268
|
return fs_time
|
320
269
|
|
321
270
|
def _get_file_modification_time(self, file_path):
|
@@ -338,6 +287,20 @@ class DocumentDatesPlugin(BasePlugin):
|
|
338
287
|
return datetime.fromtimestamp(stat.st_mtime)
|
339
288
|
|
340
289
|
|
290
|
+
def _get_author_info(self, file_path, page, config):
|
291
|
+
if not self.config['show_author']:
|
292
|
+
return None
|
293
|
+
# 1. meta author
|
294
|
+
authors = self._process_meta_author(page.meta)
|
295
|
+
if authors:
|
296
|
+
return authors
|
297
|
+
# 2. git author
|
298
|
+
authors = self._get_git_authors(file_path)
|
299
|
+
if authors:
|
300
|
+
return authors
|
301
|
+
# 3. site_author 或 PC username
|
302
|
+
return [Author(name=config.get('site_author') or Path.home().name)]
|
303
|
+
|
341
304
|
def _process_meta_author(self, meta):
|
342
305
|
try:
|
343
306
|
# 1. 处理 author 对象,或 author 字符串
|
@@ -351,8 +314,8 @@ class DocumentDatesPlugin(BasePlugin):
|
|
351
314
|
# 提取扩展属性
|
352
315
|
extra_attrs = {k: str(v) for k, v in author_data.items()
|
353
316
|
if k not in ['name', 'email']}
|
354
|
-
return Author(name=name, email=email, **extra_attrs)
|
355
|
-
return Author(name=str(author_data))
|
317
|
+
return [Author(name=name, email=email, **extra_attrs)]
|
318
|
+
return [Author(name=str(author_data))]
|
356
319
|
|
357
320
|
# 2. 处理独立字段,匹配 author_field_mapping 配置
|
358
321
|
name = ''
|
@@ -370,8 +333,8 @@ class DocumentDatesPlugin(BasePlugin):
|
|
370
333
|
|
371
334
|
if name or email:
|
372
335
|
if not name and email:
|
373
|
-
name = email.
|
374
|
-
return Author(name=name, email=email)
|
336
|
+
name = email.partition('@')[0]
|
337
|
+
return [Author(name=name, email=email)]
|
375
338
|
except Exception as e:
|
376
339
|
logging.warning(f"Error processing author meta: {e}")
|
377
340
|
return None
|
@@ -380,12 +343,6 @@ class DocumentDatesPlugin(BasePlugin):
|
|
380
343
|
if not self.is_git_repo:
|
381
344
|
return None
|
382
345
|
try:
|
383
|
-
# # 检查文件是否在 Git 中
|
384
|
-
# check_file = subprocess.run(f'git ls-files --error-unmatch {file_path}',
|
385
|
-
# shell=True, capture_output=True, text=True)
|
386
|
-
# if check_file.returncode != 0:
|
387
|
-
# return None
|
388
|
-
|
389
346
|
# 获取作者信息(为了兼容性,不采用管道命令,在 python 中处理去重)
|
390
347
|
# git_log_cmd = f'git log --format="%an|%ae" -- {file_path} | sort | uniq'
|
391
348
|
# git_log_cmd = f'git log --format="%an|%ae" -- {file_path} | grep -vE "bot|noreply|ci|github-actions|dependabot|renovate" | sort | uniq'
|
@@ -402,16 +359,11 @@ class DocumentDatesPlugin(BasePlugin):
|
|
402
359
|
name, email = line.split('|')
|
403
360
|
authors_map[line] = Author(name=name, email=email)
|
404
361
|
|
405
|
-
|
406
|
-
return authors[0] if len(authors) == 1 else authors or None
|
362
|
+
return list(authors_map.values()) or None
|
407
363
|
except Exception as e:
|
408
364
|
logging.warning(f"Failed to get git author info: {str(e)}")
|
409
365
|
return None
|
410
366
|
|
411
|
-
def _get_local_author(self):
|
412
|
-
username = Path.home().name
|
413
|
-
return Author(name=username)
|
414
|
-
|
415
367
|
|
416
368
|
def _get_formatted_date(self, date):
|
417
369
|
if self.config['type'] == 'timeago':
|
@@ -420,7 +372,7 @@ class DocumentDatesPlugin(BasePlugin):
|
|
420
372
|
return date.strftime(f"{self.config['date_format']} {self.config['time_format']}")
|
421
373
|
return date.strftime(self.config['date_format'])
|
422
374
|
|
423
|
-
def _generate_html_info(self, created, modified,
|
375
|
+
def _generate_html_info(self, created, modified, authors=None):
|
424
376
|
html = ""
|
425
377
|
try:
|
426
378
|
locale = 'zh_CN' if self.config['locale'] == 'zh' else self.config['locale']
|
@@ -439,11 +391,20 @@ class DocumentDatesPlugin(BasePlugin):
|
|
439
391
|
)
|
440
392
|
|
441
393
|
# 添加作者信息
|
442
|
-
if self.config['show_author'] and
|
443
|
-
if
|
394
|
+
if self.config['show_author'] and authors:
|
395
|
+
if len(authors) == 1:
|
396
|
+
author, = authors
|
397
|
+
author_tooltip = f'<a href="mailto:{author.email}">{author.name}</a>' if author.email else author.name
|
398
|
+
html += (
|
399
|
+
f"<span data-tippy-content='{self.translation.get('author', 'Author')}: {author_tooltip}'>"
|
400
|
+
f"<span class='material-icons' data-icon='doc_author'></span>"
|
401
|
+
f"{author.name}</span>"
|
402
|
+
# f"{author_tooltip}</span>"
|
403
|
+
)
|
404
|
+
else:
|
444
405
|
# 多个作者的情况
|
445
|
-
authors_info = ', '.join(a.name for a in
|
446
|
-
authors_tooltip = ', '.join(f'<a href="mailto:{a.email}">{a.name}</a>' if a.email else a.name for a in
|
406
|
+
authors_info = ', '.join(a.name for a in authors if a.name)
|
407
|
+
authors_tooltip = ', '.join(f'<a href="mailto:{a.email}">{a.name}</a>' if a.email else a.name for a in authors)
|
447
408
|
|
448
409
|
html += (
|
449
410
|
f"<span data-tippy-content='{self.translation.get('authors', 'Authors')}: {authors_tooltip}'>"
|
@@ -451,15 +412,6 @@ class DocumentDatesPlugin(BasePlugin):
|
|
451
412
|
f"{authors_info}</span>"
|
452
413
|
# f"{authors_tooltip}</span>"
|
453
414
|
)
|
454
|
-
else:
|
455
|
-
# 单个作者的情况
|
456
|
-
author_tooltip = f'<a href="mailto:{author.email}">{author.name}</a>' if author.email else author.name
|
457
|
-
html += (
|
458
|
-
f"<span data-tippy-content='{self.translation.get('author', 'Author')}: {author_tooltip}'>"
|
459
|
-
f"<span class='material-icons' data-icon='doc_author'></span>"
|
460
|
-
f"{author.name}</span>"
|
461
|
-
# f"{author_tooltip}</span>"
|
462
|
-
)
|
463
415
|
|
464
416
|
html += f"</div></div>"
|
465
417
|
|
@@ -13,16 +13,16 @@
|
|
13
13
|
/* Customized icons, just change the icon name.
|
14
14
|
Google Fonts Icons (2500+): https://fonts.google.com/icons
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
doc_created: add_circle, add_circle, note_add, more_time
|
17
|
+
doc_modified: update, check_circle, task, refresh
|
18
|
+
doc_author: person, account_circle
|
19
|
+
doc_authors: group, groups */
|
20
20
|
/*
|
21
21
|
.document-dates-plugin .material-icons[data-icon="doc_created"]::before {
|
22
|
-
content: "
|
22
|
+
content: "more_time";
|
23
23
|
}
|
24
24
|
.document-dates-plugin .material-icons[data-icon="doc_modified"]::before {
|
25
|
-
content: "
|
25
|
+
content: "refresh";
|
26
26
|
}
|
27
27
|
.document-dates-plugin .material-icons[data-icon="doc_author"]::before {
|
28
28
|
content: "person";
|
@@ -24,21 +24,22 @@
|
|
24
24
|
}
|
25
25
|
|
26
26
|
/* Customized icons, just change the icon name.
|
27
|
-
Google Fonts Icons (2500+): https://fonts.google.com/icons
|
27
|
+
Google Fonts Icons (2500+): https://fonts.google.com/icons
|
28
|
+
|
29
|
+
doc_created: add_circle, add_circle, note_add, more_time
|
30
|
+
doc_modified: update, check_circle, task, refresh
|
31
|
+
doc_author: person, account_circle
|
32
|
+
doc_authors: group, groups */
|
28
33
|
.document-dates-plugin .material-icons[data-icon="doc_created"]::before {
|
29
|
-
|
30
|
-
content: "add_circle";
|
34
|
+
content: "more_time";
|
31
35
|
}
|
32
36
|
.document-dates-plugin .material-icons[data-icon="doc_modified"]::before {
|
33
|
-
|
34
|
-
content: "update";
|
37
|
+
content: "refresh";
|
35
38
|
}
|
36
39
|
.document-dates-plugin .material-icons[data-icon="doc_author"]::before {
|
37
|
-
/* person, account_circle */
|
38
40
|
content: "person";
|
39
41
|
}
|
40
42
|
.document-dates-plugin .material-icons[data-icon="doc_authors"]::before {
|
41
|
-
/* group, groups */
|
42
43
|
content: "group";
|
43
44
|
}
|
44
45
|
|
{mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates.egg-info/PKG-INFO
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mkdocs-document-dates
|
3
|
-
Version: 3.1.
|
3
|
+
Version: 3.1.6
|
4
4
|
Summary: An easy-to-use, lightweight MkDocs plugin for displaying the exact creation time, last modification time and author info of markdown documents.
|
5
5
|
Home-page: https://github.com/jaywhj/mkdocs-document-dates
|
6
6
|
Author: Aaron Wang
|
@@ -38,14 +38,11 @@ An easy-to-use, lightweight MkDocs plugin for displaying the <mark>exact</mark>
|
|
38
38
|
- Always display exact meta-info of the document for any environment (no-Git, Git, all CI/CD build systems, etc)
|
39
39
|
- Support for manually specifying time and author in `Front Matter`
|
40
40
|
- Support for multiple time formats (date, datetime, timeago)
|
41
|
-
- Support for document exclusion mode
|
42
41
|
- Flexible display position (top or bottom)
|
43
42
|
- Elegant styling (fully customizable)
|
44
43
|
- Supports Tooltip Hover Tips
|
45
44
|
- Intelligent repositioning to always float optimally in view
|
46
45
|
- Supports automatic theme switching following Material's light/dark color scheme
|
47
|
-
- Support for customizing themes, styles, animations
|
48
|
-
- Compatible with mouse, keyboard and **touch** (mobile) to trigger hover
|
49
46
|
- Multi-language support, cross-platform support (Windows, macOS, Linux)
|
50
47
|
|
51
48
|
## Showcases
|
@@ -80,9 +77,7 @@ plugins:
|
|
80
77
|
exclude: # List of excluded files
|
81
78
|
- temp.md # Exclude specific file
|
82
79
|
- private/* # Exclude all files in private directory, including subdirectories
|
83
|
-
|
84
80
|
show_author: true # Show author or not, default: true
|
85
|
-
|
86
81
|
```
|
87
82
|
|
88
83
|
## Specify time manually
|
@@ -123,7 +118,7 @@ email: e-name@gmail.com
|
|
123
118
|
|
124
119
|
## Customization
|
125
120
|
|
126
|
-
The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc.
|
121
|
+
The plugin supports deep customization, such as **icon style, font style, theme color, animation type, dividing line**, etc. Everything is customizable (I've already written the code, you just need to turn on the uncomment switch):
|
127
122
|
|
128
123
|
| Function: | Location: |
|
129
124
|
| :----------------------: | ---------------------------------------- |
|
@@ -131,7 +126,7 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
131
126
|
| **Properties & Functions** | `docs/assets/document_dates/user.config.js` |
|
132
127
|
| **Localized languages** | `docs/assets/document_dates/languages/` <br />refer to the template file `en.json` for any additions or modifications |
|
133
128
|
|
134
|
-
**Tip**: when `type: timeago` is set, timeago.js is enabled to render time
|
129
|
+
**Tip**: when `type: timeago` is set, timeago.js is enabled to render dynamic time, `timeago.min.js` only contains English and Chinese by default, if you need to load other languages, you can configure it as below (choose one):
|
135
130
|
|
136
131
|
- In `user.config.js`, refer to [the demo commented out](https://github.com/jaywhj/mkdocs-document-dates/blob/main/mkdocs_document_dates/static/config/user.config.js) at the bottom, translate it into your local language
|
137
132
|
- In `mkdocs.yml`, add the following two lines to configure the full version of `timeago.full.min.js` to load all languages at once
|
@@ -150,12 +145,37 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
150
145
|

|
151
146
|
|
152
147
|

|
153
|
-

|
154
148
|

|
155
149
|
|
150
|
+
## Used in templates
|
151
|
+
|
152
|
+
You can access the meta-info of a document in a template using the following variables:
|
153
|
+
|
154
|
+
- page.meta.document_dates_created
|
155
|
+
- page.meta.document_dates_modified
|
156
|
+
- page.meta.document_dates_authors
|
157
|
+
|
158
|
+
For example like this:
|
159
|
+
|
160
|
+
```jinja2
|
161
|
+
<div><span>{{ page.meta.document_dates_created }}</span></div>
|
162
|
+
<div><span>{{ page.meta.document_dates_modified }}</span></div>
|
163
|
+
{% set authors = page.meta.document_dates_authors %}
|
164
|
+
{% if authors %}
|
165
|
+
<div>
|
166
|
+
{% for author in authors %}
|
167
|
+
{% if author.email %}<a href="mailto:{{ author.email }}">{{ author.name }}</a>
|
168
|
+
{% else %}<span>{{ author.name }}</span>{% endif %}
|
169
|
+
{% endfor %}
|
170
|
+
</div>
|
171
|
+
{% endif %}
|
172
|
+
```
|
173
|
+
|
174
|
+
**Full example**: set the correct lastmod for [sitemap.xml](https://github.com/jaywhj/mkdocs-document-dates/blob/main/sitemap.xml) so that search engines can better handle SEO and thus increase your site's exposure (override path: `docs/overrides/sitemap.xml`)
|
175
|
+
|
156
176
|
## Other Tips
|
157
177
|
|
158
|
-
- In order to always get the exact creation time, a separate cache file is used to store the creation time of the document, located in the docs folder (hidden by default), please don't
|
178
|
+
- In order to always get the exact creation time, a separate cache file is used to store the creation time of the document, located in the docs folder (hidden by default), please don't remove it:
|
159
179
|
- `docs/.dates_cache.jsonl`, cache file
|
160
180
|
- `docs/.gitattributes`, merge mechanism for cache file
|
161
181
|
- 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!
|
@@ -167,11 +187,11 @@ The plugin supports deep customization, such as **icon style, font style, theme
|
|
167
187
|
A dispensable, insignificant little plug-in, friends who have time can take a look \^\_\^
|
168
188
|
|
169
189
|
- **Origin**:
|
170
|
-
- Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), 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 system time, but to use the git time, and the filesystem time is
|
190
|
+
- Because [mkdocs-git-revision-date-localized-plugin](https://github.com/timvink/mkdocs-git-revision-date-localized-plugin), 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 system time, but to use the git time, and the filesystem time 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
|
171
191
|
- **Iteration**:
|
172
|
-
- After development, I understood why not use filesystem time, because files will be rebuilt when they go through git checkout or clone, resulting in the loss of original timestamp information
|
173
|
-
- Method 1: Use the last git commit time as the last update time
|
174
|
-
- Method 2:
|
192
|
+
- After development, I understood why not use filesystem time, 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:
|
193
|
+
- Method 1: Use the last git commit time as the last update time and the first git commit time as the creation time, mkdocs-git-revision-date-localized-plugin does this. (This way, there will be a margin of error and dependency on git)
|
194
|
+
- 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!
|
175
195
|
- **Difficulty**:
|
176
196
|
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!
|
177
197
|
- Let's take a straight shot: the Git Hooks mechanism was found, prompted by the AI, which can trigger a custom script when a specific git action occurs, such as every time commit is performed
|
@@ -6,7 +6,6 @@ def trigger_hook_install():
|
|
6
6
|
try:
|
7
7
|
import os
|
8
8
|
import sys
|
9
|
-
# 动态添加包路径确保导入成功
|
10
9
|
package_path = os.path.abspath(os.path.dirname(__file__))
|
11
10
|
if package_path not in sys.path:
|
12
11
|
sys.path.insert(0, package_path)
|
@@ -20,7 +19,6 @@ def trigger_hook_install():
|
|
20
19
|
|
21
20
|
class CustomInstallCommand(install):
|
22
21
|
def run(self):
|
23
|
-
# 注册在安装结束时执行 trigger_hook_install
|
24
22
|
atexit.register(trigger_hook_install)
|
25
23
|
install.run(self)
|
26
24
|
|
@@ -30,7 +28,7 @@ try:
|
|
30
28
|
except FileNotFoundError:
|
31
29
|
long_description = "An easy-to-use, lightweight MkDocs plugin for displaying the exact creation time, last modification time and author info of markdown documents."
|
32
30
|
|
33
|
-
VERSION = '3.1.
|
31
|
+
VERSION = '3.1.6'
|
34
32
|
|
35
33
|
setup(
|
36
34
|
name="mkdocs-document-dates",
|
@@ -59,7 +57,7 @@ setup(
|
|
59
57
|
'document-dates = mkdocs_document_dates.plugin:DocumentDatesPlugin',
|
60
58
|
],
|
61
59
|
'console_scripts': [
|
62
|
-
#
|
60
|
+
# 提供手动安装 hooks 的入口
|
63
61
|
'mkdocs-document-dates-hooks=mkdocs_document_dates.hooks_installer:install'
|
64
62
|
],
|
65
63
|
},
|
File without changes
|
{mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/__init__.py
RENAMED
File without changes
|
{mkdocs_document_dates-3.1.5 → mkdocs_document_dates-3.1.6}/mkdocs_document_dates/hooks/pre-commit
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|