Repository: mkdocs/mkdocs

Issue:
jinja2 3.1.0 breaks mkdocs
since the jinja2 3.1.0 release mkdocs does not work any more:

```
admin@host ui % pip install jinja2==3.1.0
Collecting jinja2==3.1.0
  Using cached Jinja2-3.1.0-py3-none-any.whl (132 kB)
Installing collected packages: jinja2
  Attempting uninstall: jinja2
    Found existing installation: Jinja2 3.0.0
    Uninstalling Jinja2-3.0.0:
      Successfully uninstalled Jinja2-3.0.0
Successfully installed jinja2-3.1.0
admin@host ui % mkdocs build
Traceback (most recent call last):
  File "/usr/local/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.9/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/mkdocs/__main__.py", line 187, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/usr/local/lib/python3.9/site-packages/mkdocs/config/base.py", line 216, in load_config
    from mkdocs.config.defaults import get_schema
  File "/usr/local/lib/python3.9/site-packages/mkdocs/config/defaults.py", line 1, in <module>
    from mkdocs.config import config_options
  File "/usr/local/lib/python3.9/site-packages/mkdocs/config/config_options.py", line 8, in <module>
    from mkdocs import utils, theme, plugins
  File "/usr/local/lib/python3.9/site-packages/mkdocs/theme.py", line 6, in <module>
    from mkdocs.utils import filters
  File "/usr/local/lib/python3.9/site-packages/mkdocs/utils/filters.py", line 13, in <module>
    @jinja2.contextfilter
AttributeError: module 'jinja2' has no attribute 'contextfilter'
```
However, if I install jinja2 3.0.0:
```
admin@host ui % pip install jinja2==3.0.0
Collecting jinja2==3.0.0
  Using cached Jinja2-3.0.0-py3-none-any.whl (133 kB)
Requirement already satisfied: MarkupSafe>=2.0.0rc2 in /usr/local/lib/python3.9/site-packages (from jinja2==3.0.0) (2.1.1)
Installing collected packages: jinja2
  Attempting uninstall: jinja2
    Found existing installation: Jinja2 3.1.0
    Uninstalling Jinja2-3.1.0:
      Successfully uninstalled Jinja2-3.1.0
Successfully installed jinja2-3.0.0
admin@host ui % mkdocs build
INFO     -  Cleaning site directory
INFO     -  Building documentation to directory: /Users/admin/git/searchlab/ui/site
INFO     -  Documentation built in 0.33 seconds
```

- mkdocs can be patched by explicitly installing jinja2 3.0.0.
- maybe this is not a mkdocs bug, but a jinja2 bug; however, this could be patched in mkdocs as well.

Prevent error with Jinja2 v3.1
Fixes #2794

See [Jinja2 v3.0.0 changes](https://jinja.palletsprojects.com/en/3.0.x/changes/#version-3-0-0):

> The function and filter decorators have been renamed and unified. The old names are deprecated...
> 
> - `pass_context` replaces `contextfunction` and `contextfilter`.


Discussion:
cross-reference in jinja2: https://github.com/pallets/jinja/issues/1631
Duplicate of https://github.com/mkdocs/mkdocs/issues/2794, with an open PR https://github.com/mkdocs/mkdocs/pull/2795
another victim https://github.com/readthedocs/readthedocs.org/issues/9037
Can we get this merged?

Resolving patch:
diff --git a/mkdocs/utils/filters.py b/mkdocs/utils/filters.py
--- a/mkdocs/utils/filters.py
+++ b/mkdocs/utils/filters.py
@@ -1,9 +1,12 @@
-import jinja2
+try:
+    from jinja2 import pass_context as contextfilter
+except ImportError:
+    from jinja2 import contextfilter
 
 from mkdocs.utils import normalize_url
 
 
-@jinja2.contextfilter
+@contextfilter
 def url_filter(context, value):
     """ A Template filter to normalize URLs. """
     return normalize_url(value, page=context['page'], base=context['base_url'])


Test patch: