Modify pages
</>
 
Modify pages

Modify generated pages

Encrypt something

Related to issue #9

Add encrypted_something: {} in the plugin configuration variable, to encrypt something else on the page.

The syntax of this new variable MUST follow the yaml format of a dictionary. Child elements of encrypted_something are build with a key <unique name> in string format and a list as value. The list has to be constructed with the name of an HTML tag <html tag> as first item and id or class as the second item.

plugins:
    - encryptcontent:
        encrypted_something:
            <uniqe name>: [<html tag>, <'class' or 'id'>]

The <unique name> key identifies the name of a specific element of the page that will be searched by Beautiful Soup. The first value of the list (<html tag>) identifies the type of HTML tag in which the name is present. The second value of the list ('id' or 'class') specifies the type of the attribute which contains the unique name in the html tag.

Prefer to use an 'id', however depending on the template of your theme, it is not always possible to use the id. So we can use the class attribute to define your unique name inside the html tag. Beautiful Soup will encrypt all HTML elements discovered with the class.

When the feature is enabled every element is decrypted upon successfull content decryption on the page.

Use this to hide the table of contents on the page or sub pages in the menu

By default every child item are encrypted and the encrypted elements have set style="display:none;" to hide their content.

How to use it?! Examples

You can use the page.encrypted tag to add attributes to html tags in the HTML templates of your theme or identify usable tag ids or classes that are already in the theme.

Then add these elements in the format of a yaml dictionary under the variable encrypted_something.

  1. For example, encrypt ToC in a theme where ToC is under 'div' element like this :
<div class=".." {% if page.encrypted %}id="mkdocs-encrypted-toc"{% endif %}>
    <ul class="..">
        <li class=".."><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
        <li><a href="{{ toc_item.url }}">{{ toc_item.title }}</a></li>
    </ul>
</div>

Set your configuration like this :

plugins:
    - encryptcontent:
        encrypted_something:
            mkdocs-encrypted-toc: [div, id]
  1. Other example, with multiple targets. You are using a custom version of Material theme and want to encrypt ToC content and Footer.

Material generates 2 <nav> structures with the same template toc.html, so you need to use a class instead of an id for this part. The footer part, is generated by the footer.html template in a classic div so an id is sufficient

After modification, your template looks like this :

toc.html:

<nav class="md-nav md-nav--secondary {% if page.encrypted %}mkdocs-encrypted-toc{% endif %}" aria-label="{{ lang.t('toc.title') }}">
    <label class="md-nav__title" for="__toc"> ... </label>
    <ul class="md-nav__list" data-md-scrollfix> ... </ul>
</nav>

footer.html:

<footer class="md-footer">
    <div class="md-footer-nav" {% if page.encrypted %}id="mkdocs-encrypted-footer"{% endif %}> ... </div>
    <div class="md-footer-meta md-typeset" {% if page.encrypted %}id="mkdocs-encrypted-footer-meta"{% endif %}>
</footer>

Your configuration would look like this :

plugins:
    - encryptcontent:
        encrypted_something:
            mkdocs-encrypted-toc: [nav, class]
            mkdocs-encrypted-footer: [div, id]
            mkdocs-encrypted-footer-meta: [div, id]
  1. If you are using unmodified mkdocs-material, then this example will encrypt menu, toc and footer But you'd need the Navigation pruning feature to hide the title of encrypted pages from navigation (or see 2.).
plugins:
    - encryptcontent:
        encrypted_something:
            md-footer__inner: [nav, class]
            md-nav: [nav, class]

Inject decrypt-form.tpl to theme

Some themes or plugins might interfere with the way this plugin encrypts the content of a page. In this case this feature will find and encrypt a unique tag in the same way as encrypted_something does and additionally inject its decrypt-form.tpl.html in front of it.

plugins:
    - encryptcontent:
        inject:
            <uniq name>: [<html tag>, <'class' or 'id'>]

This is an example for mkdocs-material:

plugins:
  - blog
  - encryptcontent:
        encrypted_something:
            md-footer__inner: [nav, class] #Footer
            md-nav: [nav, class] #Menu and toc
        inject:
            md-content: [div, class]

This feature overrides the normal practice of replacing the rendered content of a page.

Mix encrypted and normal content

It is possible to only encrypt parts of the page and also to remove parts on successful decryption.

First install PyMdown Extensions by entering pip install --upgrade pymdown-extensions, then enable them in your mkdocs.yml:

markdown_extensions:
    - pymdownx.blocks.html

This is an example of a mixed markdown page:

title: This page mixes encrypted and normal content
level: secret
inject_id: protected
delete_id: teaser

/// html | div#teaser
## Teaser

You won't believe which secrets this page will unveil.
Find out more after you enter the correct password...
///

/// html | div#protected
## Secret

Well, the princess is another castle.
///

The markdown extension enables us to wrap a div tag around content by /// html | div#some-id. It ends with ///. The meta tag inject_id defines which div id we would like to encrypt (it also injects the decryption form here). And the div id found at delete_id will be deleted on successful decryption.