ultrabug / mkdocs-static-i18n

MkDocs i18n plugin using static translation markdown files
https://ultrabug.github.io/mkdocs-static-i18n/
MIT License
238 stars 38 forks source link

Incompatibility with Mkdocs Material Blog plugin? #283

Open nathancatania opened 11 months ago

nathancatania commented 11 months ago

Tested with mkdocs-static.i18n 1.2.0 and mkdocs-material 9.5.2-insiders.4.47.1:

Whenever I add the blog plugin with a post, I get the following error attempting to run mkdocs serve:

Traceback (most recent call last):
  File "/Users/user/Projects/project-name/venv/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/click/core.py", line 1688, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs/__main__.py", line 270, in serve_command
    serve.serve(**kwargs)
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs/commands/serve.py", line 86, in serve
    builder(config)
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs/commands/serve.py", line 67, in builder
    build(config, live_server=None if is_clean else server, dirty=is_dirty)
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs/commands/build.py", line 311, in build
    nav = config.plugins.on_nav(nav, config=config, files=files)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs/plugins.py", line 536, in on_nav
    return self.run_event('nav', nav, config=config, files=files)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs/plugins.py", line 507, in run_event
    result = method(item, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs_static_i18n/plugin.py", line 76, in on_nav
    nav = self.reconfigure_material_blog(nav, config, files)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/user/Projects/project-name/venv/lib/python3.11/site-packages/mkdocs_static_i18n/reconfigure.py", line 765, in reconfigure_material_blog
    file.page._set_canonical_url(mkdocs_config.get('site_url', None))
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

site_url is definitely set in my mkdocs.yml:

site_name: Help Center
site_url: "https://help.company.com"
site_description: "Help Center"
repo_url: https://[REDACTED]
repo_name: repo/repo-name
edit_uri: edit/main/docs/
copyright: "&copy; 2023, [COMPANY] Inc."

theme:
  language: en
  name: material
  custom_dir: overrides
  icon:
    repo: material/github
  palette:
    - media: "(prefers-color-scheme: light)"
      scheme: company
      toggle:
          icon: material/weather-sunny
          name: Switch to dark mode
    - media: "(prefers-color-scheme: dark)"
      scheme: slate
      toggle:
        icon: material/weather-night
        name: Switch to system preference
  features:
    - navigation.indexes
    - navigation.tabs
    - navigation.sections
    - navigation.top
    - navigation.footer
    - navigation.path
    - announce.dismiss
    - content.action.edit
    - content.action.view
  alternate:
    - name: English
      link: /
      lang: en
    - name: Japanese
      link: /ja/
      lang: ja

markdown_extensions:
  - tables
  - attr_list
  - def_list
  - admonition
  - pymdownx.details
  - meta
  - pymdownx.superfences:
      custom_fences:
        - name: mermaid
          class: mermaid
          format: !!python/name:pymdownx.superfences.fence_code_format
  - md_in_html
  - pymdownx.tabbed:
      alternate_style: true
  - pymdownx.emoji:
      emoji_index: !!python/name:material.extensions.emoji.twemoji
      emoji_generator: !!python/name:material.extensions.emoji.to_svg

plugins:
  - awesome-pages
  - table-reader
  - search
  - social:
      cards_layout_options:
        cards_layout: default
  - i18n:
      docs_structure: suffix
      fallback_to_default: true
      reconfigure_material: true
      languages:
        - locale: en
          default: true
          name: English
          build: true
        - locale: ja
          name: Japanese
          build: true
          nav_translations:
            Home: ホーム
            Getting Started: はじめに
  - blog:
      enabled: true
      blog_dir: blog
      post_dir: "{blog}/posts"
      post_date_format: long
      post_url_format: "{slug}"
      draft_if_future_date: true
      draft_on_serve: true
      blog_toc: true
  - git-revision-date-localized:
      type: date
  - git-committers:
      repository: [REDACTED]
      branch: main
      enabled: !ENV [CI, false]

extra_css:
  - stylesheets/extra.css

janvanveldhuizen has the same issue as per this comment: https://github.com/ultrabug/mkdocs-static-i18n/pull/268#issuecomment-1825246468

youyoubilly commented 11 months ago

I'm having the same error, please help! Big thanks!

ultrabug commented 9 months ago

Yes this is a known incompatibility unfortunately, mkdocs-material broke support when they rewrote the blog plugin and I've been unable to fix that since.

That's on my TODO list but can't share any ETA tbh.

niccokunzmann commented 7 months ago

I just added an if:

                if file.page:
                    file.page._set_canonical_url(mkdocs_config.get('site_url', None))

This makes the build succeed but the blog is still empty.

SWHL commented 4 months ago

I have met the same problem. I can successfully build the site, but the blog part is empty.

kamilkrzyskow commented 4 months ago

In the Gothic Modding Community we finally decided we need the blog plugin to allow for more flexibility when adding non-documentation pages. We kept putting it off, because of the incompatibility here. However, one of the maintainers mentioned that our website is used primarily by the default (English) language users, so why don't we just create a non-i18n default language blog hack. So if you're interested in the same thing, adding an option to blog in your default language, then here you go. I'm still working on the PR for our project, which you can see here:

Here is the extracted hook from all of my hacky changes:

Hook ```py """MkDocs hook that hides the blog files from the i18n plugin MIT Licence 2024 Kamil Krzyśków (HRY) for Gothic Modding Community (https://gothic-modding-community.github.io/) """ from mkdocs import plugins from mkdocs.structure.files import Files BLOG_FILES = None """ List of files that belong to a blog. They will be temporarily removed and added back to hide them from the i18n plugin. Set later for mkdocs serve to work properly. """ @plugins.event_priority(-95) def _on_files_disconnect_blog_files(files: Files, config, *_, **__): """Disconnect blog files before on_files from the i18n plugin runs (-100) after blog (-50)""" global BLOG_FILES BLOG_FILES = [] non_blog_files: list[File] = [] blog_prefixes = [] for name, instance in config.plugins.items(): if name.startswith("material/blog"): blog_prefixes.append(instance.config.blog_dir) blog_prefixes = tuple(map(lambda x: x.rstrip("/") + "/", blog_prefixes)) # i18n blog prefix awareness can be used in overrides templates config.extra.i18n_blog_prefixes = blog_prefixes for file in files: if file.src_uri.startswith(blog_prefixes): BLOG_FILES.append(file) else: non_blog_files.append(file) return Files(non_blog_files) @plugins.event_priority(-105) def _on_files_connect_blog_files(files: Files, *_, **__): """Breaking the convention of a minimal -100. Restore blog files after i18n on_files""" for file in BLOG_FILES: files.append(file) return files on_files = plugins.CombinedEvent(_on_files_disconnect_blog_files, _on_files_connect_blog_files) ```

Here is a mini example I tested:

Reference:


[!NOTE] I updated the hook above after the initial comment, so please update it if you used it :v:

machinaeXlasse commented 4 months ago

For the blog I am fine with the default language too so this is really great. Thanks so much for sharing!

Since it occured to me too, you need to update to the latest i18n, mkdocs and material for above script to work.

SWHL commented 4 months ago

@kamilkrzyskow I tried your script, and it can solve the part problem. Without using the hook script, the blog of my site is empty. After using the hook script, the blog can render correctly.

But it displays blogs in all languages simultaneously. Normally, when I choose English, the page only displays the English version of the blog. I choose Chinese, and the page only displays the Chinese version of the blog.

image

Here is a mini example I tested: i18n-with-default-blog.zip

kamilkrzyskow commented 4 months ago

Hi @SWHL, you have misunderstood. The purpose of this hook is to only allow to add default language posts, and they'll will be added for every language.

Currently the i18n plugin doesn't support the blog plugin at all, so it's empty, no posts are shown. This hook allows to add files and make them display. So do not add multiple languages for blog posts, only add one language, preferably the default language.

❗ This hook doesn't fix the lack of i18n support for the blog, via this plugin.

SWHL commented 4 months ago

@kamilkrzyskow Thank you for your reply, I did misunderstand.