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
335 stars 51 forks source link

mymacro is undefined #95

Closed Grzy7316 closed 3 years ago

Grzy7316 commented 3 years ago

I attempted to create a basic macro, and it is unable to work with mkdoc.

my main.py file looks like this

def define_env(env):
  "Hook function"

  @env.macro
  def mymacro():
      some_string = "some_string" 
      return some_string

and in my index.md file I have {{ mymacro() }}

I get the error jinja2.exceptions.UndefinedError: 'mymacro' is undefined

github-actions[bot] commented 3 years ago

Welcome to this project and thank you!' first issue

Grzy7316 commented 3 years ago

Figured it out - has the python file 1 level down . my bad

fralau commented 3 years ago

@Grzy7316 What happened? Did you place the main.py file in the docs directory?

Grzy7316 commented 3 years ago

I did place it in the docs directory - vs codes explorer is not the best at showing folder structure with default settings. - but now I have a new question - What do I need to do to have multiple macros in my main.py file? Do I just define it with

@env.macro
  def my_new_macro():

underneath the

def define_env(env):
  "Hook function"?
fralau commented 3 years ago

You can put as many function in the file at the same level of my_new_macro(), as long as you decorate each with env.macro.

There are other ways to export a function, see the documentation.

Grzy7316 commented 3 years ago

so if I want to create a subfolder with a bunch of python scripts in it, as long as I create a define_env() function in them and decorate them with @env.macro ?

fralau commented 3 years ago

@Grzy7316 Perhaps I did not understand your question? If you want to create a subfolder, you can just call it module and treat it as a package.

See documentation page for more information:

Instead of a module file, it could also be a package (i.e. a main subdirectory), as long as the define_env() function is accessible through the __init__.py file.

Grzy7316 commented 3 years ago

What I was asking is if I need to call it from main.py, or if I can call it from in my docs like ``{{% from Macrofolder import filename as name %}}}

fralau commented 3 years ago

@Grzy7316 I am not sure I understand your question?

The functions so exported are directly available in a markdown page:

Calling the macro: {{ mymacro() }}

The fact that they have been declared as macros, makes them available in the template.

Grzy7316 commented 3 years ago

so I have a subfolder called MyMacros that is at the root level of my repository (same folder as mkdocs.yml ) Inside the MyMacros I have an __init__.py file that is blank Inside there I have a file called xphandling.py. I have the following in this code file , but when I try to load my document, I get the error 'clearxp' is undefined

import pandas as pd 
import numpy as np

def define_env(env):
  "Hook function"

  @env.macro
  def clearxp():

    with open('Tracking/XpTracking.csv',"w" ) as clearfile:
      clearfile.truncate(0)
    with open('Tracking/XpTracking.csv',"w") as setheader:
      # headerwriter =(setheader)
      setheader.write("Location,Instance,XP")
      setheader.write("\n0,0,0")
      return "XP RESET "
Grzy7316 commented 3 years ago

My latest move was to add this to the __init__.py file in Mymacros,

def define_env(env):
  "Hook function"

which at least gets me to not throw an error when I put module_name: MyMacros in my mkdocs.yml file. I am also able to use the macros I have in xphandling.py if I put MyMacros/xphandling in my mkdocs.yml file. I am now just not sure how I would go about using all of the different python files under the myMacros folder. If I try with Modeules and then put in the individual file paths I get the error Could not import installed module 'MyMacros/xphandling' (missing?)

fralau commented 3 years ago

@Grzy7316 As long as your package exports define_env(env) and a call to @env.macro is performed, then it is going to work.

Another approach if you think it is simpler, is to define all your functions however you like, and then import them into the __init__.py file. Then you manage your list of macros explicitly:

from .foo import f1, 
from .bar import f2, f3

def define_env(env):
  "Hook function"
  for f in [f1, f2, f3]:
      env.macro(f)
Grzy7316 commented 3 years ago

I am pretty new to python, what do you mean by

@Grzy7316 As long as your package exports define_env(env)

fralau commented 3 years ago

If you are new to Python, you are boldly venturing into the unknown! I would really recommend that you spend a few hours studying:

In the mean time, the above snippet should work.

fralau commented 3 years ago

How is this going?