fralau / mkdocs-macros-plugin

Create richer and more beautiful pages in MkDocs, by using variables and calls to macros in the markdown code.
https://mkdocs-macros-plugin.readthedocs.io
Other
336 stars 51 forks source link

macros and filters unrecognised in custom footer.html #83

Closed rodrigoschwencke closed 3 years ago

rodrigoschwencke commented 3 years ago

Hi, I am having problems to get the context (custom macros and filters defined in my main.py file) in a custom footer.html file. I am overriding the material-theme with this file structure :

mysite :

|--custom
      |-- .icons
      |-- assets
      |-- jinja  (just some tests)
      |-- partials
              |-- footer.html
      | main.html
|--docs
...
mkdocs.yaml
main.py

My main.html file contains basic stuff:

{% extends "base.html" %}

{% block htmltitle %}
        <title>Custom title goes here</title>
{% endblock %}

{% block footer scoped %}
        {% include "partials/footer.html" with context %}
{% endblock %}

And also my footer stuff contains basically a copy of the footer.html file of the material-theme:

{% import "partials/language.html" as lang with context %}

<footer class="md-footer">
  {% if page.previous_page or page.next_page %}
    <nav class="md-footer__inner md-grid" aria-label="{{ lang.t('footer.title') }}">
      {% if page.previous_page %}
        <a href="{{ page.previous_page.url | url }}" class="md-footer__link md-footer__link--prev" rel="prev">
          <div class="md-footer__button md-icon">
            {% include ".icons/material/arrow-left.svg" %}
          </div>
          <div class="md-footer__title">
            <div class="md-ellipsis">
              <span class="md-footer__direction">
                {{ lang.t("footer.previous") }}
              </span>
              {{ page.previous_page.title }}
            </div>
          </div>
        </a>
      {% endif %}
      {% if page.next_page %}
        <a href="{{ page.next_page.url | url }}" class="md-footer__link md-footer__link--next" rel="next">
          <div class="md-footer__title">
            <div class="md-ellipsis">
              <span class="md-footer__direction">
                {{ lang.t("footer.next") }}
              </span>
              {{ page.next_page.title }}
            </div>
          </div>
          <div class="md-footer__button md-icon">
            {% include ".icons/material/arrow-right.svg" %}
          </div>
        </a>
      {% endif %}
    </nav>
  {% endif %}
  <div class="md-footer-meta md-typeset">
    <div class="md-footer-meta__inner md-grid">
      <div class="md-footer-copyright">
        {% if config.copyright %}
          <div class="md-footer-copyright__highlight">
            {# {{ config | pprint }} #}
            Hey :<b>{{ config.copyright | formatWithDate }} </b>
            Hey :<b>{{ get_year() }} </b>
            {{ config.copyright }}
          </div>
        {% endif %}
        <a href="https://custom_url/" target="_blank" rel="noopener">
          Blabla
        </a>
        {{ extracopyright }}
      </div>
      {% include "partials/social.html" %}
    </div>
  </div>
</footer>

Main.py file:

import os
import datetime

def define_env(env):
  "Hook function"
   def get_year():
   now = datetime.datetime.now()
   return now.year

  @env.filter
  def formatWithDate(s:str)->str:
    """Replaces {date} by the current Year"""
    print("-------------TYPE of s = ", type(s))
    i0 = s.index("{date}")
    return s[:i0]+str(get_year())+s[i0+6:]

PROBLEM - Current Behavior: I got an error "jinja2.exceptions.TemplateAssertionError: no filter named 'formatWithDate' " It clearly looks like a jinja context problem (macros and filters not passed to the jinja global context), but I can't solve it.

Precision:

Expected Behavior: I should detect both macros and filters defined in my main.py file.

CAN SOMEONE HELP ME ??? PLEEEEASE? ANY IDEA? OR CLUE?

Is this "normal"? I mean : Do macros and filters of this plugin (defined in the main.py file) only get passed to the jinja global context inside markdown files of the docs folder?? (i also tried to rename my file footer.html into footer.md: still does not work) Isn't it possible to get macros and filters inside the custom footer.html file? Hope I am being very precise. I can give more precisions if needed, please any help is welcome :)

github-actions[bot] commented 3 years ago

Welcome to this project and thank you!' first issue

fralau commented 3 years ago

I see where the issue is: currently the macros plugin is used to interpret macros in the markdown documents (this is the jinja2 environment).

The jinja2 engine for HTML templates is completely distinct (it is part of the standard mkdocs). It is possible to trickle variables to the template, through the page metadata.

It is, however, the first time that someone tried to use macros in the way you are trying to do.

Instead of applying the filter within the template, why don't you do it at the markdown level?

Something like this might work, in the markdown page:

---
formatted_copyright: {{ config.copyright | formatWithDate }}
---

Then you would pass the metadata as a variable to the template:

 Hey :<b>{{ page.meta.formatted_copyright }} </b

But since you don't want to redefine that metadata every page, you should just ask your Python module to do it for you, automatically:


FORMATTED_COPYRIGHT = formatWithDate(env.config.copyright)

def on_post_page_macros(env):
    """
    Actions to be done after macro interpretation,
    just before the markdown is generated
    """
    env.page.meta['formatted_copyright'] =  FORMATTED_COPYRIGHT

I did it off my hat. Let me know whether that works for you?

fralau commented 3 years ago

@rodrigoschwencke How is this issue right now?