As part of the pydata-sphinx-theme
we have a few settings that auto-enable extensions and configure them on behalf of the user.
It has always been mysterious to me how to do this properly during the Sphinx build.
It’s easy to configure things with conf.py
ahead of time, but what if you want to manually set a value during the build?
I finally figured it out, so documenting the process here.
Use the builder-inited
event¶
Define a Sphinx event for builder-inited
. This will trigger after the builder has been selected, but before the environent is finalized for the build.
This should be a function that takes a single (app)
parameter.
Use app._raw_config
to find the user-provided config¶
Use the app._raw_config
object to detect user-given config. This is first written when Sphinx is initialized and should be a good indication of what the user provided.
This is useful if you only want to over-ride something if the user didn’t set it themselves.
However, the app.config
object will have all of the config options, including defaults.
Update configuration options with the app.config
object¶
Update app.config.keyname
.
You can set and update configuration values directly with app.config.keyname = "foo"
.
The way Sphinx does this is by directly setting app.config.__dict__["keyname"] = "foo"
, but this doesn’t seem to be necessary and I’m not sure why they do it that way.
Update HTML theme options with app.builder.theme_options
¶
Update app.builder.theme_options
.
Many people (including myself) incorrectly try to update app.config.html_theme_options
during a build event.
But this doesn’t do anything because the’ve already been copied over to app.builder.theme_options
early in the build process.
Annoyingly, the copied dictionary in app.builder.theme_options
does not point to the same points in memory as app.config.html_theme_options
.
This copy action is done here.
An example¶
Here’s an example of the whole process in action:
# This function will update a single configuration value
def update_config(app):
# Check if a value was provided by the user
if "foo" in app.config._raw_values:
# Update a config value
app.config.__dict__["foo"] = "bar"
# Update an HTML theme value
app.builder.theme_options["foo2"] = "bar2"
# Register the above function to be called during the builder-inited phase
def setup(app):
app.connect("builder-inited", update_config)