Remove the word "module" from Sphinx documentation - python

Using Sphinx for documenting my Python project. I want to remove the word "module" which follows the name of each python file (in the navbar, TOC, the page title, etc).
e.g. Details:
The project is composed of 2 files utils.py and main.py.
In my index.rst file, I use:
.. toctree::
:maxdepth: 2
utils
main
to import both files as "modules". From the docs/ folder, I then call:
sphinx-apidoc -f -o ./source/ ..
make html
to generate the static site. In the site, the word "module" follows every file name, and I would like to remove it.

Sphinx 2.2 adds templating for the reST files generated by sphinx-apidoc.
Use the --templatedir option to set the path to a dir containing module.rst_t, package.rst_t and toc.rst_t files. The files can be created from the corresponding files in site-packages/sphinx/templates/apidoc.
Then, in package.rst_treplace
{{- [submodule, "module"] | join(" ") | e | heading(2) }}
with
{{- submodule | e | heading(2) }}
Repeat for module.rst_t.

One possible solution uses JS to find & replace the word "module" after the page loads:
Create a file source/_templates/layout.html with the following content:
{% extends "!layout.html" %}
{% block extrahead %}
<script type="text/javascript">
window.onload = function() {
document.body.innerHTML = document.body.innerHTML.replace(/ module/g, '');
}
</script>
{% endblock %}
Make sure that conf.py has templates_path = ['_templates'] set, then Sphinx will append the script to the <head> of all documentation pages, and voila!

Related

How to handle line breaks in a templated file included in a Jinja2 JSON template

I am writing a Jinja2 template to output a JSON DAG where one value is a string containing a list of commands from an external shell script, (containing templated variables. This works if the commands in the script are semicolon-separated on a single line:
echo 'hello'; echo 'world';
But, it fails to render the template when formatted with each command on its own line:
echo 'hello';
echo 'world';
JSONDecodeError: Invalid control character at: line 2 column 29 (char 30)` where character 30 is the line break.
I understand this is because JSON does not support multi-line strings. I am using Jinja2's {% include path %} to load the file but am not sure how to escape the new lines before rendering them.
I was not able to pipe the include output through a Python replace successfully:
{% include path | replace("\n", " ") %}
I also tried putting the include in a macro with the replace calling inside or outside the macro.
Here is a full example of the template and rendering code.
multi_line.sh
echo 'hello';
echo '{{variable}}';
variables.json
{
"variable": "world!"
}
template.j2
{
{# Render included file into single line #}
"multi": "{% include './multi_line.sh' %}"
}
template_renderer.py
from jinja2 import Environment, FileSystemLoader
import json
with open("./variables.json") as variables_file:
variables_json = json.load(variables_file)
loader = FileSystemLoader("./")
env = Environment(loader=loader)
template = env.get_template("./template.j2")
rendered_template = template.render(variables_json)
json_output = json.loads(rendered_template)
print(json.dumps(json_output, indent=2))
The solution for me was to wrap the include in a block assignment and then pipe the results into replace to remove occurrences of \n.
{% set multi_line_script %}
{% include 'multi_line.sh' %}
{% endset %}
{
"multi": "{{ multi_line_script | replace("\n", " ") }}"
}

Equivalent to wildcards in Flask's url_for?

I am developing a Flask application, and have it set so that my app's CSS file is generated with a random name via this build script:
rm style/main-*.css;
KEY=`tr -dc A-Za-z0-9 </dev/urandom | head -c 6`;
postcss build ./style/src/main.css -o ./style/main-$KEY.css
This is mostly for cache-related reasons; but it regardless results in a name with the wildcard pattern main-*.css
Since this name is randomized every build, I do not want to edit the template I include it in. Unfortunately, wildcards do not appear to work in Flask, as this:
<link rel='stylesheet" href='{{ url_for('static', filename='style/main-*.css') }}'>
… does nothing (except, of course, yield a 404).
Is there a way to do this kind of behavior via Flask? Thank you.
You can write your own function and add it to the jinja2 environment as a global function.
import os
from glob import glob
from flask import current_app
def glob_assets(target):
root = current_app.static_folder
return [f[len(root)+1:] for f in glob(os.path.join(root, target))]
app.jinja_env.globals.update(get_assets=glob_assets)
Then you can add the stylesheets to the template within one iteration.
{% for css in get_assets('style/main-*.css') -%}
<link rel="stylesheet" href="{{ url_for('static', filename=css) }}">
{% endfor -%}

Jinja2 {% include file %} outside of search path doesn't work

This is an elementary issue which is probably related to Jinja2 PrefixLoader or ChoiceLoader.
On Python 3.6 we load with this command
jinja2.FileSystemLoader( searchpath= "\\template_folder\\")
On Windows 7, our file structure is as follows.
- folder_bbb
* subfile.txt
- template_folder
* template_file
- folder_aaa
* subfile.txt
From the template_file we are successful with this command
{% include "folder_aaa/subfile.txt" %}
Now we wish to move the file one level up, and write
{% include "../folder_bbb/subfile.txt" %}
but that doesn't work, complaining file not found.
What is the correct way to write? Thanks.
You may specify all paths in the the loader
jinja2.FileSystemLoader(["c:\\template_folder\\", "c:\\folder_bbb\\"])
and refer the including block without a specific path
{% include "subfile.txt" %}
The path will be searched in order so that as you say, moving the file one level up, the file will be found. (You need the template_folder path for the template itself.)

pybabel ignoring files with autoescape

I have a python web application with jinja2 templates. I am using pybabel for localization. When using the pybabel extract command, it exports everything exactly as intended, EXCEPT for any files which use the jinja2 autoescape tag.
My babel.cfg file has the following line:
extensions=jinja2.ext.autoescape,jinja2.ext.with_
And the extract command I am using is:
pybabel extract -F ./babel.cfg -o ./locale/messages.pot ./
I have a file called settings.html, which has the following tag:
{% autoescape false %}
{% endautoescape %}
And pybabel lists this file in the console, in the list of files it extracts from:
extracting messages from templates/cfg/settings.html
But, when I check my pot file, there are no translations from settings.html.
If I delete the autoescape tag from settings.html, then re-run the pybabel extract command, then it correctly extracts the translations.
So there must be something up with use of autoescape.
Any clues?

How to add custom css file to Sphinx?

How can I add a custom css file? The following config does not work:
# conf.py
html_static_path = ['_static']
html_theme = 'default'
html_theme_options = {
'cssfiles': ['_static/style.css']
}
Result:
$ make html
Running Sphinx v1.2.2
loading pickled environment... not yet created
building [html]: targets for 2 source files that are out of date
updating environment: 2 added, 0 changed, 0 removed
reading sources... [ 50%] help
reading sources... [100%] index
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents...
Theme error:
unsupported theme option 'cssfiles' given
A simpler way is to add this to your conf.py:
def setup(app):
app.add_css_file('css/custom.css') # may also be an URL
Then put the file into the _static/css/ folder.
You should be able to include custom css by extending the default sphinx theme. In your conf.py you would specify where your extension to the theme would be, such as.
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Then in _templates you would create a extension to the default theme named 'layout.html' that would include your cssfiles such as.
{# layout.html #}
{# Import the layout of the theme. #}
{% extends "!layout.html" %}
{% set css_files = css_files + ['_static/style.css'] %}
See sphinx's documentation on templating for more information.
The options that you can configure via html_theme_options are theme-dependent. Check out the [options] section of your theme’s theme.conf to find out what is available.
On a global basis, though, you can define html_context in your conf.py to override the settings for css_files (and, for that matter, script_files too):
html_context = {
'css_files': ['_static/custom.css'],
}
(For reference, have a look at Sphinx’s builders.html.StandaloneHTMLBuilder.prepare_writing() and see how self.globalcontext gets populated there.)
I'm using Sphinx 3.2.
I was able to add some simple custom CSS by doing the following:
add this line in conf.py right under html_static_path = ['_static']:
html_css_files = ['css/custom.css']
go to docs/_static/ and add css/custom.css
add custom css to your file then $ make html
Source

Categories