MkDocs: using a variable to construct external URLs

1.1k Views Asked by At

Using AsciiDoc, I can define a base URL property and reference it to define links:

:external-url: https://www.example.com/docs

:Foo: {external-url}/foo[Foo,role=external-doc]
:Bar: {external-url}/bar[Bar,role=external-doc]
:Baz: {external-url}/baz[Baz,role=external-doc]

I can then use {Foo} syntax to inject links into my documentation pages.

What would be the best way to achieve this with MkDocs? I'd like to avoid duplicating the base URL if possible.

2

There are 2 best solutions below

1
On

MkDocs is using Markdown, and therefore there are no available off-the-shelf variables you could use. So instead, you need to use something to preprocess your markdown files.

You should decide two things:

  1. Which preprocessor to use
  2. How to integrate into your processing.

With the first one, my answer is Jamal, available from https://github.com/verhas/jamal

I have created Jamal to solve issues like this and to include programmable semantic information into your documentation. You should take this recommendation with a pinch of salt; since Jamal is my love child, I created it.

The other question is how to integrate it into Mkdocs. Here I see three different possibilities:

  1. Use the preprocessor manually to maintain .md.jam files and convert them to .md files before building your documentation site. It is the most straightforward approach because it only needs that you execute a command before starting your build. But, on the other hand, it is the easiest to forget to do that and end up having outdated markdown files.

You can mend this solution using ANT, make, or other build tools.

  1. Create a MkDocs plugin that starts the conversion and converts all md.jam files to .md files. You need to write a short Python module that initiates Jamal as an external process. It needs some Python programming but has the advantage that you will not forget to execute the Jamal processing since all the builds will do that for you.

Both of these approaches have the advantage that you can get rid of the introduced Jamal processing. You have your .md files created in your source structure. If you decide, you can delete the Jamal files and go on editing the Markdown files directly, bearing all the consequences of maintaining redundant-information infested documentation sources.

  1. Finally, you can develop a Python Markdown plugin to process the Jamal macros in the .md files. Since Jamal is written in Java, this plugin has to execute an external process. This is probably the most complex approach and, in my opinion, the least practical. In this case, your Markdown files contain the Jamal macros, and you do not have the converted, macro-free Markdown files in your source set. These come in handy many times. The plugin starts Jamal as a separate process for every Markdown file separately, while the earlier approaches can convert all the files in a single process.

What I recommend is that

have a look at the features of Jamal, if you like it, and understand if this is really what you need start using it as a separate preprocessor when you really want it, you may consider writing a MkDocs plugin to execute the conversions automatically.

0
On

In essence, you wish to add a mechanism of wikilinks.

I created mkdocs-macros for that kind of applications. Just install it and add the following in your config files (mkdocs.yml):

plugins:
  - search
  - macros

Then add the hyperlink in the extra section of this file, e.g:

extra:
  external-url: https://www.example.com/docs

Then, your markdown page:

The following [page]({{ external-url}}/foo), as well as this [other page]({{ external-url}}/foo)...

The variable {{ external-url}} will be translated into its equivalent.

In general, you can use mkdocs-macros in that way for any type of recurring string that you wish to keep centralized.


For completeness, see also the answer on MKDOCS - How to enable hyperlinks based on keywords found in the content? where solutions with markdown extensions are presented.