You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Separating out the "configuration" from the "placement" of these components has a couple of downsides.
It means that creating a new kind of UI also means creating a new theme configuration variable in theme.conf, which is already quite long.
It makes it more difficult to re-use the same configuration structure for different parts of the theme (for example, a language switcher is basically the same thing as a version switcher, but with the current setup we'd need to define a new HTML template + configuration variable for it.
Separating the configuration from the placement means keeping track of the same kind of information in two different places, which seems artificial and may lead to confusion.
Since we already ask people to provide a list of templates, we could simplify things by instead letting people provide a list of configurations that would define the elements inserted into that section of the page.
Proposal
Instead of using two configuration variables to configure and place theme UI elements, we instead combine these into a single configuration. For the major UI areas, rather than accepting a list of template names, they would instead accept a list of dictionaries of configuration that corresponds to a type of widget to be inserted.
For example, below would be the same configuration as above, but also shows off how we could define a second dropdown switcher by re-using the same config:
html_theme_options= {
# Widget configuration for the end of the navbar"navbar_end": [
# First few items are icon links
{
"kind": "link",
"label": "PyPI",
"url": "https://pypi.org/project/pydata-sphinx-theme",
"icon": "fas fa-box",
},
{
"kind": "link",
"label": "Pandas",
"url": "https://pandas.pydata.org",
"icon": "_static/pandas-square.svg",
"type": "local",
},
# Now a widget of type "switcher"
{
"kind": "switcher",
"json_url": "https://pydata-sphinx-theme.readthedocs.io/en/latest/_static/switcher.json",
"version_match": version_match,
},
# We could then define a different switcher w/ the same widget type like so:
{
"kind": "switcher",
"json_url": "https://pydata-sphinx-theme.readthedocs.io/en/latest/_static/switcher_language.json",
"version_match": language_match,
},
]
}
You could also re-use the same widgets in multiple places, with different configurations. For example, if you wanted some icon links in the navbar, but other icon links in the sidebar or footer.
ref: this is inspired by the furo topbar theme, but uses a list of dictionaries so that we could re-use the same widget type multiple times in the same UI area.
How could this be implemented?
One way to implement this would be to define a variable in the HTML context called something like html-widgets. This would be a dictionary of the form <widget-kind> : <jinja macro>. It would work like this:
The kind key of our widget configuration would be used to select a widget macro from html-widgets
The macro would then accept all other keys for that widget's configuration (other than kind) as key/val pairs
The macro would be expected to return a blob of HTML
In our theme templates, we could use this html-widgets dictionary like so:
{% for config in context.get("theme_navbar_end", []) %}
{% set kind = config.pop("kind") %}
{{ context["html-widgets"][kind](**config)
{% endfor %}
With a structure like that, it would also be possible for other packages to piggy-back on the same functionality, by adding their own widget-kind/macro pairs with a Sphinx event, which users could then insert into their theme configuration via the same mechanism described above.
We could define and register these macros like so:
(I'm not positive this is the right syntax but I think you can do something like this in Jinja.)
Or you could similarly define a function in Python, and add it to the context html-widgets list in the same way. It would just need to output an HTML string.
Longer term
Longer term, I think that it would be best if we tried to standardize these configuration structures across themes, such as Furo and the Book Theme, so that users could port their configurations for common things across themes. This has also already been discussed in the book theme in this issue on pluggable widgets and there's also an implementation to play around with here. I'm opening up the issue in this repository in case we can use this as a chance to prototype some functionality in this theme and see how it feels.
Feedback?
I'd love to hear what people think about the general idea, and about the specific configuration proposed above. Does this seem like it would be useful?
The text was updated successfully, but these errors were encountered:
choldgraf
changed the title
Make our version switcher configuration (and other navbar elements) more self-contained
Use self-contained widgets for UI elements (e.g. the version switcher)
Feb 26, 2022
@choldgraf pinged me via another channel about this... and this is something I've been thinking about a bunch.
I think what we should do for version switchers is have them be external-to-the-theme, provided to the templates as context variables. The theme can then make its own decisions/choice on how to present the various versions for the user, and provide users with configuration knobs for those things.
The version information can be manually provided by a user through html_context or, more realistically, by a Sphinx extension or RTD's injection logic. That way (a) this would be transferable across themes, (b) would externalise the complexity of "how do I specify multiple versions" away from the theme and into an extension; allowing that to be a replaceable thing and (c) has a clearer separation of concerns.
Context
Currently, we have a number of "widgets" that can be turned on in the navbar of the theme. These are configured with a combination of two things:
html_theme_options
. For example, for icon links + a version switcher, as we use in our docs now:Separating out the "configuration" from the "placement" of these components has a couple of downsides.
theme.conf
, which is already quite long.language
switcher is basically the same thing as aversion
switcher, but with the current setup we'd need to define a new HTML template + configuration variable for it.Since we already ask people to provide a list of templates, we could simplify things by instead letting people provide a list of configurations that would define the elements inserted into that section of the page.
Proposal
Instead of using two configuration variables to configure and place theme UI elements, we instead combine these into a single configuration. For the major UI areas, rather than accepting a list of template names, they would instead accept a list of dictionaries of configuration that corresponds to a type of widget to be inserted.
For example, below would be the same configuration as above, but also shows off how we could define a second dropdown switcher by re-using the same config:
You could also re-use the same widgets in multiple places, with different configurations. For example, if you wanted some icon links in the navbar, but other icon links in the sidebar or footer.
ref: this is inspired by the furo topbar theme, but uses a list of dictionaries so that we could re-use the same widget type multiple times in the same UI area.
How could this be implemented?
One way to implement this would be to define a variable in the HTML context called something like
html-widgets
. This would be a dictionary of the form<widget-kind> : <jinja macro>
. It would work like this:kind
key of our widget configuration would be used to select a widget macro fromhtml-widgets
kind
) as key/val pairsIn our theme templates, we could use this
html-widgets
dictionary like so:With a structure like that, it would also be possible for other packages to piggy-back on the same functionality, by adding their own
widget-kind
/macro
pairs with a Sphinx event, which users could then insert into their theme configuration via the same mechanism described above.We could define and register these macros like so:
(I'm not positive this is the right syntax but I think you can do something like this in Jinja.)
Or you could similarly define a function in Python, and add it to the context
html-widgets
list in the same way. It would just need to output an HTML string.Longer term
Longer term, I think that it would be best if we tried to standardize these configuration structures across themes, such as Furo and the Book Theme, so that users could port their configurations for common things across themes. This has also already been discussed in the book theme in this issue on pluggable widgets and there's also an implementation to play around with here. I'm opening up the issue in this repository in case we can use this as a chance to prototype some functionality in this theme and see how it feels.
Feedback?
I'd love to hear what people think about the general idea, and about the specific configuration proposed above. Does this seem like it would be useful?
The text was updated successfully, but these errors were encountered: