opened
timvink
username_0
__I checked that...__

- [x] ... the documentation does not mention anything about my idea
- [x] ... to my best knowledge, my idea wouldn't break something for other users
- [x] ... there are no open or closed issues that are related to my idea

## Description

Add support for [mkdocs-git-committers-plugin](https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin). In effect, when a user enables the plugin in `mkdocs.yml`, the latest revision date would automatically display under the page title.

### Use Cases

Users can see clearly when pages where last updated -- without having to go to git.

### Screenshots / Mockups

It would look something like this:

![image](https://user-images.githubusercontent.com/5570380/69553022-b343c080-0f9f-11ea-9535-c7f0e8cf8d2a.png)

If this is something that is considered useful I would be happy to work on the PR. Work to be done:

- Update `base.html` with conditional statements
- Some CSS work
- Update documentation page with supported extensions
Add support for mkdocs-git-revision-date-plugin and mkdocs-git-committers-plugin
issue
created
squidfunk
username_1
Looks useful to me, happy to collaborate on a PR.

How does the plugin handle L10N/I18N? Is the date string printed according to the environment locale? This also needs to be addressed in all other content that is automatically added to the template, i.e. `"Last update:"`
comment
created
timvink
username_0
Good points! 

The plugin outputs dates in YYYY-MM-DD format. We could use [timeago](https://timeago.org/) which has localization, which we can map to mkdocs [list of supported languages](https://www.mkdocs.org/user-guide/configuration/#lang). Downside is this adds a 2kb dependency. That doesn't solve the `"Last update:"` part though.  I realize now that this should be part of the `mkdocs-git-committers-plugin` plugin. 

Is I18N a hard requirement for you? If so, I'll need to go and contribute to that plugin first & then re-open this issue here. Otherwise, we can start already with adding an english version.
comment
created
squidfunk
username_1
Kind of. Adding a hard-coded string to the template I would want to provide a way to translate it easily.
comment
created
timvink
username_0
I looked into it, and mkdocs offers no special `datetime` formatting, username_2 refers to standard `strftime` functionality (see [this issue](https://github.com/mkdocs/mkdocs/issues/1408)), but the `mkdocs-git-revision-date-plugin` plugin returns a `str` and `datetime` is not imported by `mkdocs`.

If we accept the date is always in ISO-8610 format (the [only right format](https://xkcd.com/1179/) anyway), we can move forward with an output like:

```html
{% if git_revision_date is defined %}
  # ... 
  {{ lang.t('last.update') }}: {{ git_revision_date }}
{% endif %}
```

```html
Last updated: 2019-11-26
```
comment
created
squidfunk
username_1
`strftime` would be perfect, or am I missing something? So if the date would be exposed as a date variable, we could use `strftime` in the template with a localized format string (with a reasonable default). MkDocs's [`build_date_utc`](https://www.mkdocs.org/user-guide/custom-themes/#build_date_utc) is also exposed as a `datetime` object. So for reasons of consistency alone I would favor `datetime` over a string.

As much as I love XKCD – ISO-8610 is a very technical format. For my own docs I would prefer something more readable like _November 26, 2019_. Could we update the mentioned plugin that it outputs `datetime` objects? It could be implemented as an option to support both formats, `string` and `datetime`. If a `datetime` is encountered, Material will render it using the given format, otherwise it will just display the string.
comment
created
squidfunk
username_1
Also see https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin/issues/4, which is already a request for different date formats.
comment
created
timvink
username_0
Yes let's do it proper then, will contribute to `mkdocs-git-revision-date-plugin` first so we get a `datetime` object, then get back here. Thanks so far!
comment
created
timvink
username_0
Figured I could already start on this PR while I wait for the other one, so I started here: https://github.com/username_0/mkdocs-material/tree/1350-support-git-revision-date 

I need some help with the `scss`, basically with a conditional margin on `<h1>`, if revision date is available no `margin-bottom: -2em` on h1:

![image](https://user-images.githubusercontent.com/5570380/69639154-54904c80-105c-11ea-8344-cbc5981a3bb2.png)

And another more challenging issue: When you use a heading 1 (`#`) in a page it takes precedence over the navigation tree title (in `mkdocs.yml`), which means either the revision date is not shown (if within the title if block in `base.html`) or the ordering is wrong (when using separate if block below the title, see picture):

```html
{% if not "\x3ch1" in page.content %}
  <h1>{{ page.title | default(config.site_name, true)}}</h1>
{% endif %}
{% if page.meta.revision_date %}
  <small>
    {{ lang.t('last.update') }}: {{ page.meta.revision_date.strftime('%d %B %Y') }}
  </small>
{% endif %} 
```
![image](https://user-images.githubusercontent.com/5570380/69639435-cc5e7700-105c-11ea-881c-ad7163a8f97a.png)

Maybe you have some ideas or pointers in the right direction?
comment
created
squidfunk
username_1
Placing it under the `h1` will not work consistently, as the theme sets the page title as `h1` if there's no `h1` in the content as you already noticed. This behavior is not configurable. I think I would recommend to place it [at the bottom after the content and footnotes and before the footer](https://github.com/username_1/mkdocs-material/blob/c706667fb0db97fc8d7b0ae9b88f13e96e7e3436/src/base.html#L331). This should also solve the spacing problems, which are tricky to get right in all possible combinations, as there are quite some rules for subsequent headlines, e.g. `h1 + h2` etc.
comment
created
timvink
username_0
That's not as nice but a lot more practical.

I also only now realize `{{ page.meta.revision_date.strftime('%d %B %Y') }}` does not respect the language option from `mkdocs-material`. It will default to the user's python locale.

Changing that is possible in python:

```python
import locale
import datetime
date = datetime.datetime.now().date()
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
print(date.strftime('%A'))
#> Wednesday
locale.setlocale(locale.LC_ALL, 'nl_NL.UTF-8')
print(date.strftime('%A'))
#> woensdag
```

But not every user has every locale installed on his system. And it would also require a contribution to `mkdocs`. The alternative of exporting `LC_ALL` as an environment variable before building is not a failsafe method, and perhaps not user-friendly either.

Another way to do this is to use the python [timeago](https://github.com/hustcc/timeago) package that has localization files:

```python
import timeago
date = datetime.datetime.now().date()
print(timeago.format(date))
#> 9 hours ago
print(timeago.format(date, locale = "nl"))
#> 9 uren geleden
```

I could contribute to `mkdocs` a new custom jinja2 [mkdocs template filter](https://www.mkdocs.org/user-guide/custom-themes/#template-filters) that uses timeago and takes locale as an argument, something like:

```html
`{{ lang.t('last.update') }}:  {{ totimeago( page.meta.revision_date, config.theme.language) }}`
```

So finally output would be something like:

```html
Last update: 9 hours ago
```

Alternatively, the easiest route would be using YYYY-MM-DD format, e.g.:

```html
Last update: 2019-11-27
```

Let me know what you prefer, or if you have any other good ideas ;)
comment
created
squidfunk
username_1
@username_0 thanks for the thorough research and experimentation! If opening the possibility to set locales opens yet another can of worms, I would also be fine with an English-only formatted date string which is adjustable through `strftime`. I guess it's possible to adjust the locale via `LC_ALL` as an environment variable in front of the `mkdocs` command, isn't it? We could add a hint in the documentation how to achieve this, e.g:

```
LC_ALL=nl_NL mkdocs build
```

@username_2 could you maybe comment on this topic? Before we go down a specific path I would like to hear your opinion. I feel that localization is kind of an open and unresolved issue of MkDocs, which is also why Material went its own way with L10N based on template files / macros. Are there any plans for improving localization, maybe with a language parameter set in `mkdocs.yml` or via environment variables?
comment
created
waylan
username_2
The current state of L10N is summarized in mkdocs/mkdocs#211 and the beginning of an implementation exists in mkdocs/mkdocs#1778. That PR adds a `local` setting to the `theme`. In other words, the default language would be defined in [mkdocs_theme.yml][1] and could be overridden in `mkdocs.yml`:

```yml
theme:
    local: fr
```
comment
created
timvink
username_0
@username_1 Localization seems like the way to go then. I suggest I first propose & make a PR to `mkdocs` that implements the `totimeago` jinja2 filter. Then back here in addition to changes discussed we should also rename the `language` parameter to `locale` to be consistent with future versions of `mkdocs`. We can do this in a backwards compatible way with some jinja2 logic.
comment
created
squidfunk
username_1
We definitely need to provide backward-compatibility. Furthermore, we'll wait for a new MkDocs version to configure the locale for `strftime`, so there should be no necessity for `timeago` I guess.
comment
created
waylan
username_2
As this is all about supporting a third party plugin, I would suggest changes like this should be made to the plugin. As a reminder, plugins can alter the Jinja environment with the [on_env][1] event (to add filters, for example). I would expect a plugin which provides dates to a template to provide that date as a `datetime` object and also provide any date based filters needed to work with the `datetime` object. There is no need for MkDocs to change anything in that respect.

[1]: https://www.mkdocs.org/user-guide/plugins/#on_env
comment
created
waylan
username_2
I'm not sure what you mean here. Plugins have access to the config, including `config['theme']['locale']` so a plugin can, if it chooses, act on the `locale`. However, as it is currently implemented, the translation files are provided by the theme, so any translation should be done within the theme templates, not a plugin. 

As an example, the only change to the `search` plugin in the PR is [to the JS][1] and all that does is obtain the "no results found" string from the HTML rather than hardcoding it in the JS. The string is now defined and translated [in the template][2].

[1]: https://github.com/mkdocs/mkdocs/pull/1778/files#diff-a7101432976e7e08eca206a334bc12ed
[2]: https://github.com/mkdocs/mkdocs/pull/1778/files#diff-343ab2b4999ffe54a053bf9108362d29R15
comment
created
squidfunk
username_1
@username_2 thanks! Do you have a rough estimate on when this will be released? Are we talking weeks or months? I'm asking because I have Material v5 in the making which will have some breaking changes and it would be great to push them out at once and not with a v6 some weeks after that.
comment
created
waylan
username_2
I have no concrete timetable for this and can't commit to including it in a specific release. As it stands, the PR needs some more work: the `readthedocs` theme needs updated and the whole thing needs documented. I'm not sure when I'll have the time to get to it. In fact I haven't worked on MkDocs in months (aside from reviewing PRs by others). So if someone else completed the PR, it could get merged sooner, but the next release still has some other blockers so it will likely be a while. In other words, I wouldn't wait on it if I were you.
comment
created
squidfunk
username_1
@username_2 answers my question, thanks!
comment
created
timvink
username_0
Update: made a [PR for adding totimeago](https://github.com/zhaoterryy/mkdocs-git-revision-date-plugin/pull/8) jinja2 filter to `mkdocs-git-revision-date-plugin`, pending review
comment
created
squidfunk
username_1
@username_0 pretty cool. Is it possible to format a date with a locale similar to `strftime`, like for example `November 28, 2019`?
comment
created
timvink
username_0
`timeago` only has basic localization (see example for [en](https://github.com/hustcc/timeago/blob/master/src/timeago/locales/en.py)). 

Your remark made me think: dates don't require much translation. Then I found [babel](https://github.com/python-babel/babel):

```python
from datetime import date
from babel.dates import format_date
d = date(2007, 4, 1)
format_date(d, format='long', locale='en')
#> 'April 1, 2007'
```

I'll contribute a PR with a `formatdate` jinja2 filter to `mkdocs-git-revision-date-plugin` as well. Once it's merged I can come back here. We'll get there eventually!
comment
created
timvink
username_0
Update: `mkdocs-git-revision-date-plugin` v.02 is now published on PyPi which enables the option of having the date as a `datetime` instead of `str`.

I currently writing my own mkdocs plugin or order to provide some jinja2 date filters ([mkdocs-date-filters-plugin](https://github.com/username_0/mkdocs-date-filters-plugin)), because [babel](https://github.com/python-babel/babel) and [timeago](https://github.com/hustcc/timeago) are dependencies that shouldn't be in `mkdocs-git-revision-date-plugin`. That way I can also make sure that the plugin uses `theme.language` as the default locale, and mkdoc's future `locale` setting as well.

Then using all that in `mkdocs-material` should be relatively easy:

```yml
# mkdocs.yml
plugins:
    - git-revision-date:
        as_datetime: True
    - date-filters
```

And in `base.html`, including a nice fall back to `YYYY-MM-DD` if you don't want to use `date-filters`: 

```html
{% if todateformat is defined %}
    {{ page.meta.revision_date | todateformat }}
{% else %}
    {{ page.meta.revision_date }}
{% endif %}
```

I tested this, but jinja throws an error if you don't have the new `mkdocs-date-filters-plugin` installed:

```bash
jinja2.exceptions.TemplateAssertionError: no filter named 'todateformat'
```

There's an open issue for this behaviour in jinja: (https://github.com/pallets/jinja/issues/842).
I'll need to think about a workaround, or take up the challenge of providing a PR to jinja first.

To be continued :)
comment
created
squidfunk
username_1
Thanks for sharing your progress. I hope that in the end the configuration for this will not be too complicated with multiple possible scenarios that all need to be handled. There’s a reasonable amount of non tech-savvy people using this project.

As I understand there would be four cases that need to be addressed:

- both plugins set + `as_datetime: true`
- both plugins set + `as_datetime: false`
- no date filters plugin
- no revision date plugin (default, same as now)

That’s a lot of potential for breakage. Could we improve on the DX here?
comment
created
timvink
username_0
Yes you're right. I didn't even think of the "both plugins set + `as_datetime: false`" case. Setup is too involved, implementation in `mkdocs-material` is not clean, and indeed too much potential for breakage.

Thought about it some more and I have a new idea: Fork and create a new plugin `mkdocs-git-revision-date-localized-plugin` that just makes the localized git revision dates available as normal jinja variables. 

Usage:

```
# mkdocs.yml
plugins:
    - git-revision-date-localized:
```

Implementation:

```html
{% if git_revision_date_localized is defined %}
  # ... 
  {{ lang.t('last.update') }}: {{ git_revision_date_localized }}
{% endif %}
```

(and we could also support the `YYYY-MM-DD` version of `git_revision_date`, prioritizing the localizated version over the normal one). 

Should solve all the problems :)
comment
created
squidfunk
username_1
Yes, that sounds like a reasonable plan! So the format is automatically handled by the plugin according to the selected locale. How is the locale determined? `theme.lang`? Later it's possible to use `mkdocs.locale`, but not for now I guess.
comment
created
timvink
username_0
I published [username_0/mkdocs-git-revision-date-localized-plugin ](https://github.com/username_0/mkdocs-git-revision-date-localized-plugin) this morning. It supports `theme.language` as well as the future `mkdocs.locale`. 

I just opened a PR to add support for it. I included documentation & the translations I could find on google translate. Would appreciate a review!
comment
closed
squidfunk
username_1
issue
created
timvink
username_0
Thanks for all the support on this issue @username_1. I realize now even more how much effort has gone into `mkdocs-material`. Thanks for all your work and the awesome theme! Glad I could contribute back a little bit.
comment
created
squidfunk
username_1
Thanks for your contributions! Pleasure to work with you. The changes were just released with 4.6.0.
comment
created
RDIL
username_3
Hey @username_0, I tried it out but got:
```python
Exception in callback <bound method LiveReloadHandler.poll_tasks of <class 'livereload.handlers.LiveReloadHandler'>>
    Traceback (most recent call last):
      File "/home/gitpod/.pyenv/versions/3.7.4/lib/python3.7/site-packages/tornado/ioloop.py", line 907, in _run
        return self.callback()
      File "/workspace/.pip-modules/lib/python3.7/site-packages/livereload/handlers.py", line 69, in poll_tasks
        filepath, delay = cls.watcher.examine()
      File "/workspace/.pip-modules/lib/python3.7/site-packages/livereload/watcher.py", line 105, in examine
        func()
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/commands/serve.py", line 107, in builder
        site_dir=site_dir
      File "/workspace/.pip-modules/lib/python3.7/site-packages/mkdocs/config/base.py", line 210, in load_config
        "Aborted with {0} Configuration Errors!".format(len(errors))
    mkdocs.exceptions.ConfigurationError: Aborted with 1 Configuration Errors!
```
Any idea why? I really want to use it.

`mkdocs.yml`:

```yaml
site_name: username_3 Web Docs

theme:
  name: 'material'
  palette:
    primary: 'cyan'
    accent: 'cyan'
  feature:
    tabs: false
  favicon: /favicon.ico
  logo: assets/34555510.png

repo_name: 'rdilweb/docs'
repo_url: 'https://github.com/rdilweb/docs'

markdown_extensions:
  - markdown.extensions.admonition
  - markdown.extensions.codehilite:
      guess_lang: false
  - markdown.extensions.def_list
  - markdown.extensions.footnotes
  - markdown.extensions.meta
  - markdown.extensions.toc:
      permalink: true
  - pymdownx.arithmatex
  - pymdownx.betterem:
      smart_enable: all
  - pymdownx.caret
  - pymdownx.critic
  - pymdownx.details
  - pymdownx.emoji:
      emoji_generator: !!python/name:pymdownx.emoji.to_svg
  - pymdownx.inlinehilite
  - pymdownx.keys
  - pymdownx.magiclink
  - pymdownx.mark
  - pymdownx.smartsymbols
  - pymdownx.superfences
  - pymdownx.tasklist:
      custom_checkbox: true
  - pymdownx.tilde
  - git-revision-date-localized:
      type: timeago

site_description: Documentation for username_3's services and libraries.
site_url: https://docs.rdil.rocks
site_author: Reece Dunham
copyright: Copyright (©) Reece Dunham 2019-present
remote_branch: master

extra:
  social:
    - type: 'github'
      link: 'https://github.com/rdilweb'
    - type: 'twitter'
      link: 'https://twitter.com/rdil_pickle'

nav:
  - Home: index.md
  - API: api.md
  - Libraries:
    - area4: libraries/area4.md
    - filehandlers: libraries/filehandlers.md
    - intutils: libraries/intutils.md
    - lcpy: libraries/lcpy.md
    - LiquidBT:
      - Introduction: libraries/liquidbt/intro.md
      - "Getting Started": libraries/liquidbt/getting-started.md
      - Plugins: libraries/liquidbt/plugins.md
  - "Code of Conduct": CODE_OF_CONDUCT.md
  - "Docs License": LICENSE.md
```
comment
created
timvink
username_0
Hi @username_3 

Happy to hear you'd like to use it! 

You have an error in your config, as you added a plugin under `markdown-extensions`. Instead, add a new section with:

```
plugins:
  - git-revision-date-localized
      type: timeago
```

and if you use search, you need to explictly enable it under plugins as well, i.e.:

```
plugins:
  - search
  - git-revision-date-localized
      type: timeago
```

If you have any issues with the plugin you can open an issue at [mkdocs-git-revision-date-localized-plugin](https://github.com/username_0/mkdocs-git-revision-date-localized-plugin)
comment
created
RDIL
username_3
Ohhh thanks @username_0, didn't notice that. 😄
comment