squidfunk / mkdocs-material

Documentation that simply works

Home Page:https://squidfunk.github.io/mkdocs-material/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tags plugin seems to cause build failure

jkaye2012 opened this issue · comments

Contribution guidelines

I've found a bug and checked that ...

  • ... the problem doesn't occur with the mkdocs or readthedocs themes
  • ... the problem persists when all overrides are removed, i.e. custom_dir, extra_javascript and extra_css
  • ... the documentation does not mention anything about my problem
  • ... there are no open or closed issues that are related to my problem

Description

Hey all - I tried enabling the tags plugin today, but found that this seems to cause a build error.

Expected behaviour

The documentation builds and creates a tag index.

Actual behaviour

Traceback (most recent call last):
  File "/usr/local/bin/mkdocs", line 8, in <module>
    sys.exit(cli())
  File "/usr/local/lib/python3.9/dist-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.9/dist-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.9/dist-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python3.9/dist-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.9/dist-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/usr/local/lib/python3.9/dist-packages/mkdocs/__main__.py", line 187, in build_command
    build.build(config.load_config(**kwargs), dirty=not clean)
  File "/usr/local/lib/python3.9/dist-packages/mkdocs/commands/build.py", line 290, in build
    for file in files.documentation_pages():
  File "/usr/local/lib/python3.9/dist-packages/mkdocs/structure/files.py", line 50, in documentation_pages
    return [file for file in self if file.is_documentation_page()]
  File "/usr/local/lib/python3.9/dist-packages/mkdocs/structure/files.py", line 50, in <listcomp>
    return [file for file in self if file.is_documentation_page()]
AttributeError: 'NoneType' object has no attribute 'is_documentation_page'

Steps to reproduce

Here's our plugin configuration:

plugins:
  build_plantuml:
    render: "server"
    server: "http://localhost:8080/plantuml"
    output_format: "svg"
    diagram_root: ""
    output_folder: "_doc"
    input_folder: "_doc"
    input_extensions: "puml"
  search: {}
  tags:
    tags_file: tags.md
  autolinks: {}
  mkdocstrings: {}
  mkdocs-jupyter: {}
  blog:
    format: "(%m/%y)"
  simple:
    include_folders:
      - "*"
    ignore_folders:
      - "node_modules"
      - "patches"
      - "usr"
      - "out"
    ignore_hidden: true
    merge_docs_dir: true
    build_docs_dir: ""
    include_extensions:
      - .bmp
      - .tif
      - .tiff
      - .gif
      - .svg
      - .jpeg
      - .jpg
      - .jif
      - .jfif
      - .jp2
      - .jpx
      - .j2k
      - .j2c
      - .fpx
      - .pcd
      - .png
      - .pdf
      - CNAME
      - .snippet
      - .pages
      - .ipynb

Running the build without the tags plugin works normally. With the tags plugin, it fails with the message included above.

Package versions

root@d8343eb9b9d1:/# python --version
Python 3.9.7
root@d8343eb9b9d1:/# mkdocs --version
mkdocs, version 1.2.3 from /usr/local/lib/python3.9/dist-packages/mkdocs (Python 3.9)
root@d8343eb9b9d1:/# pip show mkdocs-material | grep -E ^Version
Version: 8.2.7

Configuration

plugins:
  build_plantuml:
    render: "server"
    server: "http://localhost:8080/plantuml"
    output_format: "svg"
    diagram_root: ""
    output_folder: "_doc"
    input_folder: "_doc"
    input_extensions: "puml"
  search: {}
  tags:
    tags_file: tags.md
  autolinks: {}
  mkdocstrings: {}
  mkdocs-jupyter: {}
  blog:
    format: "(%m/%y)"
  simple:
    include_folders:
      - "*"
    ignore_folders:
      - "node_modules"
      - "patches"
      - "usr"
      - "out"
    ignore_hidden: true
    merge_docs_dir: true
    build_docs_dir: ""
    include_extensions:
      - .bmp
      - .tif
      - .tiff
      - .gif
      - .svg
      - .jpeg
      - .jpg
      - .jif
      - .jfif
      - .jp2
      - .jpx
      - .j2k
      - .j2c
      - .fpx
      - .pcd
      - .png
      - .pdf
      - CNAME
      - .snippet
      - .pages
      - .ipynb


### System information

Ubuntu focal

Also, I just want to say that I love this project and really appreciate the work that you've put into this. Happy to help in any way that I can to get this resolved.

Hi @squidfunk , just add an observation on top of this discussion, how to display the table of content of tag index page if I usetoc.integrate in the mkdocs.yml. looks like the toc.integrate will block the table of content of tag index page.

Thanks for reporting. First question: does the tags.md file actually exist? You need to create the file, the tags_file setting must refer to an existing file, as noted in the documentation.

The built-in tags plugin allows to define a file to render a tags index, which can be any page that is part of the nav section.

Also, please try and comment out the other plugins to narrow it down – we need a minimal reproducible example. You can attach a minimal example as a zip file to this issue.

Also, I just want to say that I love this project and really appreciate the work that you've put into this. Happy to help in any way that I can to get this resolved.

Thanks! My work on this project is only possible due to my awesome sponsors. If it wouldn't be for the sponsors, I wouldn't be able to work on it.

Hi @squidfunk , just add an observation on top of this discussion, how to display the table of content of tag index page if I usetoc.integrate in the mkdocs.yml. looks like the toc.integrate will block the table of content of tag index page.

This is completely unrelated. Please create a new discussion with your question, again with a minimal reproducible example.

Yep, you're right, I completely misread the docs on this one. Removing the tag_file configuration has everything working. So really just two notes:

  1. A nice QOL change would be a better error message for this - but definitely not required as this is ultimately user error
  2. I did have to add the attr_list markdown extension in order for the buttons to render properly, but I don't think I saw that as a requirement in the docs. Not a problem at all to add that, but if you agree that's something I could add

A nice QOL change would be a better error message for this - but definitely not required as this is ultimately user error

We have exactly that, but it appears that it's not triggered, possibly due to side effects of other plugins.

self.tags_file = files.get_file_from_path(file)
if not self.tags_file:
log.error(f"Configuration error: {file} doesn't exist.")
sys.exit()

If you manage to isolate the problem of why this is not triggered in your case, please create a PR. You didn't provide a reproducible example, which is why it's impossible for me to debug.

I did have to add the attr_list markdown extension in order for the buttons to render properly, but I don't think I saw that as a requirement in the docs. Not a problem at all to add that, but if you agree that's something I could add

What do you mean by buttons? The attribute list extension shouldn't be necessary for the tags plugin, as tags are generated by the plugin. The extension is only necessary when you want to attach attributes to elements within Markdown.

In any way, closing, as it's a configuration error.

The behavior I was seeing was that the tags plugin attaches {.button} attributes to the Markdown elements, thus the requirement. But I suppose it's possible another plugin was causing that?

Not really. This is how the tags index page is rendered:

def __render_tag_links(self, tag, pages):
content = [f"## <span class=\"md-tag\">{tag}</span>", ""]
for page in pages:
url = utils.get_relative_url(
page.file.src_path.replace(os.path.sep, "/"),
self.tags_file.src_path.replace(os.path.sep, "/")
)
# Ensure forward slashes, as we have to use the path of the source
# file which contains the operating system's path separator.
content.append("- [{}]({})".format(
page.meta.get("title", page.title),
url
))
# Return rendered tag links
return "\n".join(content)

On the individual pages, tags are rendered as part of the template:

<nav class="md-tags" {{ hidden }}>
{% for tag in tags %}
{% if tag.url %}
<a href="{{ tag.url | url }}" class="md-tag">
{{ tag.name }}
</a>
{% else %}
<span class="md-tag">{{ tag.name }}</span>
{% endif %}
{% endfor %}
</nav>

Note that this is exactly why a minimal reproducible example is so important. Otherwise, I can only guess.