From 2465a91ad974ca28d15f1d42f652bc43d6d95176 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Thu, 24 Feb 2022 14:42:52 -0800 Subject: [PATCH 1/5] Remove double-linking of theme CSS --- src/pydata_sphinx_theme/__init__.py | 12 ++++++++++-- .../theme/pydata_sphinx_theme/theme.conf | 2 ++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/pydata_sphinx_theme/__init__.py b/src/pydata_sphinx_theme/__init__.py index 639e591a7..acfe9c02f 100644 --- a/src/pydata_sphinx_theme/__init__.py +++ b/src/pydata_sphinx_theme/__init__.py @@ -45,7 +45,8 @@ def update_config(app, env): def update_templates(app, pagename, templatename, context, doctree): - """Update template names for page build.""" + """Update template names and assets for page build.""" + # Allow for more flexibility in template names template_sections = [ "theme_navbar_start", "theme_navbar_center", @@ -55,7 +56,6 @@ def update_templates(app, pagename, templatename, context, doctree): "theme_left_sidebar_end", "sidebars", ] - for section in template_sections: if context.get(section): # Break apart `,` separated strings so we can use , in the defaults @@ -69,6 +69,14 @@ def update_templates(app, pagename, templatename, context, doctree): if not os.path.splitext(template)[1]: context[section][ii] = template + ".html" + # Remove a duplicate entry of the theme CSS. This is because it is in both: + # - theme.conf + # - manually linked in `webpack-macros.html` + if "css_files" in context: + theme_css_name = "_static/styles/pydata-sphinx-theme.css" + if theme_css_name in context["css_files"]: + context["css_files"].remove(theme_css_name) + def add_toctree_functions(app, pagename, templatename, context, doctree): """Add functions so Jinja templates can add toctree objects.""" diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf index 140692947..1de2beafa 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/theme.conf @@ -1,5 +1,7 @@ [theme] inherit = basic +# Note that we don't link the CSS file via Sphinx +# instead we manually link it in `webpack-macros.html` stylesheet = styles/pydata-sphinx-theme.css pygments_style = tango sidebars = search-field.html, sidebar-nav-bs.html From e66f9ff430de4c3db227c077a1d9e6869a582c8e Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Thu, 24 Feb 2022 20:19:20 -0800 Subject: [PATCH 2/5] Comments --- .../theme/pydata_sphinx_theme/layout.html | 5 +-- webpack.config.js | 37 ++++++++++++------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html index b0bc069bc..cff38d03c 100644 --- a/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html +++ b/src/pydata_sphinx_theme/theme/pydata_sphinx_theme/layout.html @@ -2,11 +2,8 @@ {%- import "static/webpack-macros.html" as _webpack with context %} {%- block css %} - {{ _webpack.head_pre_bootstrap() }} + {{ _webpack.head_pre_assets() }} {{ _webpack.head_pre_icons() }} - {% block fonts %} - {{ _webpack.head_pre_fonts() }} - {% endblock %} {{- css() }} {{ _webpack.head_js_preload() }} {%- endblock %} diff --git a/webpack.config.js b/webpack.config.js index ef6221ae5..c6c44cf7f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,13 @@ -// Webpack configuration for pydata-sphinx-theme. -// -// There's a decent amount of complexity here, arising from the fact that we -// have a fairly non-standard "JS application" here. +/** + * Webpack configuration for pydata-sphinx-theme. + * + * This script does a few primary things: + * + * - Genreates a `webpack-macros.html` file that defines macros used + * to insert CSS / JS at various places in the main `layout.html` template. + * - Compiles our SCSS and JS and places them in the _static/ folder + * - Downloads and links FontAwesome and some JS libraries (Bootstra, jquery, etc) + */ const { resolve } = require("path"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); @@ -31,26 +37,31 @@ const vendorPaths = { // function macroTemplate({ compilation }) { const hash = compilation.hash; + // We load these files into the theme via HTML templates const css_files = ["styles/theme.css", "styles/pydata-sphinx-theme.css"]; const js_files = ["scripts/pydata-sphinx-theme.js"]; + // Load a CSS script with a digest for cache busting. function stylesheet(css) { return ``; } + // Pre-load a JS script (script will need to be loaded later on in the page) function preload(js) { return ``; } + // Load a JS script with a digest for cache busting. function script(js) { return ``; } return dedent(`\ + {# Load FontAwesome icons #} {% macro head_pre_icons() %} {% endmacro %} - {% macro head_pre_fonts() %} - {% endmacro %} - - {% macro head_pre_bootstrap() %} - ${css_files.map(stylesheet).join("\n ")} + {% macro head_pre_assets() %} + + ${css_files.map(stylesheet).join("\n")} {% endmacro %} {% macro head_js_preload() %} - ${js_files.map(preload).join("\n ")} + + ${js_files.map(preload).join("\n")} {% endmacro %} {% macro body_post() %} - ${js_files.map(script).join("\n ")} + + ${js_files.map(script).join("\n")} {% endmacro %} `); } From 6c1fb167521c398a0809013f8cde214d79baea07 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Thu, 24 Feb 2022 20:37:50 -0800 Subject: [PATCH 3/5] Clarify assets --- CONTRIBUTING.md | 4 +- docs/contribute/index.md | 2 - docs/contribute/topics.md | 110 +++++++++++++++++--------------------- 3 files changed, 51 insertions(+), 65 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bc66f8dbb..55e6f3d8c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,5 +4,5 @@ Contributions are very welcome! Installing the development version, building the demo docs and developing the css/js of the theme, etc, is explained in more detail in the contributing section of the documentation: -- [Contributing source files](docs/contributing.md) -- [Contributing rendered docs](https://pydata-sphinx-theme.readthedocs.io/en/latest/contributing.html) +- [Contributing source files](docs/contribute/index.md) +- [Contributing rendered docs](https://pydata-sphinx-theme.readthedocs.io/en/latest/contribute/index.html) diff --git a/docs/contribute/index.md b/docs/contribute/index.md index b397ec748..dbd9a7ef2 100644 --- a/docs/contribute/index.md +++ b/docs/contribute/index.md @@ -36,8 +36,6 @@ The CSS and JS for this theme are built for the browser from `src/pydata_sphinx_ - the main part of the theme assets - customizes [Bootstrap](https://getbootstrap.com/) with [Sass](https://sass-lang.com) - - points to the `font-face` of vendored web fonts, but does not include their - CSS `@font-face` declaration - JS: `src/pydata_sphinx_theme/assets/scripts/index.js` diff --git a/docs/contribute/topics.md b/docs/contribute/topics.md index c09ea2cf8..1a6c13a2e 100644 --- a/docs/contribute/topics.md +++ b/docs/contribute/topics.md @@ -75,21 +75,62 @@ $ pre-commit run --all-files $ pre-commit run -a ``` -## Web asset compiling and bundling +## Web assets (CSS/JS/Fonts) -All of the CSS and JS assets stored in `src/pydata_sphinx_theme/assets` will be compiled and bundled with the theme when you build it locally. -These bundled assets will be placed in `src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static`. +This theme includes several web assets to ease development and design. +The configuration for our asset compilation is in `webpack.config.js`. -The configuration that defines what happens upon compilation is at `webpack.config.js`. +### Compile and bundle assets -When assets are compiled, a `` is generated for each, and appended to the end of the asset's reference in the HTML templates of the theme. +When assets are compiled, static versions are placed in various places in the theme's static folder: + +``` +src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static +``` + +For many assets, a `` is generated and appended to the end of its reference in the HTML templates of the theme. This ensures the correct asset versions are served when viewers return to your site after upgrading the theme. -Web fonts, and their supporting CSS, are copied into -`src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static/vendor///`. +To compile the assets and bundle them with the theme, run this command: + +```console +$ nox -s compile +``` + +### Styles (SCSS) and Scripts (JS) + +There are two relevant places for CSS/JS assets: + +- `src/pydata_sphinx_theme/assets/styles` has source files for SCSS assets. These will be compiled to CSS. +- `src/pydata_sphinx_theme/assets/scripts` has source files for JS assets. These will be compiled to JS and import several vendored libraries (like Bootstrap). +- `src/pydata_sphinx_theme/theme/pydata_sphinx_theme/static` has compiled versions of these assets (e.g. CSS files). This folder is not tracked in `.git` history, but it is bundled with the theme's distribution. -The links to these unique file names are captured as Jinja2 macros that are defined in HTML templates bundled with the theme. +### Vendored scripts + +We vendor several packages in addition to our own CSS and JS. +For example, Bootstrap, JQuery, and Popper. +This is configured in the `webpack.config.js` file, and imported in the respective `SCSS` or `JS` file in our assets folder. + +### FontAwesome icons + +Three "styles" of the [FontAwesome 5 Free](https://fontawesome.com/icons?m=free) +icon font are used for {ref}`icon links ` and admonitions, and is +the only `vendored` font. + +- It is managed as a dependency in `package.json` +- Copied directly into the site statics at compilation, including licenses +- Partially preloaded to reduce flicker and artifacts of early icon renders +- Configured in `webpack.js` + +### Jinja macros + +Our Webpack build generates a collection of [Jinja macros](https://jinja.palletsprojects.com/en/3.0.x/templates/#macros) in the `static/webpack-macros.html` file. + +These macros are imported in the main `layout.html` file, and then inserted at various places in the page to link the static assets. + +Some of the assets [are "preloaded"](https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload), meaning that the browser begins requesting these resources before they're actually needed. +In particular, our JavaScript assets are preloaded in ``, and the scripts are actually loaded at the end of ``. ## Accessibility checks @@ -171,59 +212,6 @@ The output of the last command includes: - a short summary of the current state of the accessibility rules we are trying to maintain - local paths to JSON and HTML reports which contain all of the issues found -## Change fonts - -Three "styles" of the [FontAwesome 5 Free](https://fontawesome.com/icons?m=free) -icon font are used for {ref}`icon links ` and admonitions, and is -the only `vendored` font. Further font choices are described in the {ref}`customizing` -section of the user guide, and require some knowledge of HTML and CSS. - -The remaining vendored font selection is: - -- managed as a dependency in `package.json` - - - allowing the version to be managed centrally - -- copied directly into the site statics, including licenses - - - allowing the chosen font to be replaced (or removed entirely) with minimal - templating changes: practically, changing the icon font is difficult at this - point. - -- partially preloaded - - - reducing flicker and re-layout artifacts of early icon renders - -- mostly managed in `webpack.js` - - - allowing upgrades to be handled in a relatively sane, manageable way, to - ensure the most recent icons - -### Upgrade a font - -If _only_ the version of the `existing` font must change, for example to enable -new icons, edit the appropriate font version in `package.json`. -Then re-compile the theme with: - -```console -$ nox -s compile -``` - -### Change a font - -If the above doesn't work, for example if file names for an existing font change, -or a new font variant altogether is being added, hand-editing of `webpack.config.js` -is required. The steps are roughly: - -- install the new font, as above -- in `webpack.config.js`: - - add the new font to `vendorVersions` and `vendorPaths` - - add new `link` tags to the appropriate macro in `macroTemplate` - - add the new font files (including the license) to `CopyPlugin` - - remove references to the font being replaced/removed, if applicable - - see the `font-awesome` sections of this configuration to see what the end-result configuration looks like. -- re-compile the theme's assets: `nox -s compile` - ## Update our kitchen sink documents The [kitchen sink reference](../demo/kitchen-sink/index.rst) is for demonstrating as much syntax and style for Sphinx builds as possible. From 3132c44ebfaac5ef95bd4d3a8f933f85dda279eb Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Thu, 24 Feb 2022 20:41:07 -0800 Subject: [PATCH 4/5] Typo --- webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index c6c44cf7f..25b8ad8f2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,7 @@ * * This script does a few primary things: * - * - Genreates a `webpack-macros.html` file that defines macros used + * - Generates a `webpack-macros.html` file that defines macros used * to insert CSS / JS at various places in the main `layout.html` template. * - Compiles our SCSS and JS and places them in the _static/ folder * - Downloads and links FontAwesome and some JS libraries (Bootstra, jquery, etc) From 4d3ad403088fd5574ef70e039a02fb8825228b30 Mon Sep 17 00:00:00 2001 From: Chris Holdgraf Date: Sat, 5 Mar 2022 16:23:25 -0800 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Damian Avila --- docs/contribute/topics.md | 2 +- webpack.config.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/contribute/topics.md b/docs/contribute/topics.md index 1a6c13a2e..4ebefdfe4 100644 --- a/docs/contribute/topics.md +++ b/docs/contribute/topics.md @@ -121,7 +121,7 @@ the only `vendored` font. - It is managed as a dependency in `package.json` - Copied directly into the site statics at compilation, including licenses - Partially preloaded to reduce flicker and artifacts of early icon renders -- Configured in `webpack.js` +- Configured in `webpack.config.js` ### Jinja macros diff --git a/webpack.config.js b/webpack.config.js index 25b8ad8f2..24d166edb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,7 +6,7 @@ * - Generates a `webpack-macros.html` file that defines macros used * to insert CSS / JS at various places in the main `layout.html` template. * - Compiles our SCSS and JS and places them in the _static/ folder - * - Downloads and links FontAwesome and some JS libraries (Bootstra, jquery, etc) + * - Downloads and links FontAwesome and some JS libraries (Bootstrap, jQuery, etc) */ const { resolve } = require("path");