diff --git a/copier.yml b/copier.yml index b8a2041..4872dab 100644 --- a/copier.yml +++ b/copier.yml @@ -8,6 +8,11 @@ project_url: type: str help: what is your project url? +footer_items_json: + type: str + help: path to JSON file defining links in the footer as a text-to-url mapping. + default: assets/json/footer_items.json + favicon: type: str help: what is your project favicon? diff --git a/template/assets/css/scientific-python.css b/template/assets/css/scientific-python.css index f29cdea..71f3166 100644 --- a/template/assets/css/scientific-python.css +++ b/template/assets/css/scientific-python.css @@ -31,15 +31,13 @@ main { padding-left: 2rem; padding-right: 2rem; - padding-left: 3.5rem; - padding-right: 3.5rem; - /* Outer content grid */ & .outer-grid { - /* spacer, project description, spacer, link columns, spacer */ - grid-template-columns: 3fr 3fr 4fr; + /* logo, project description, link columns, social icons */ + grid-template-columns: 2fr 6fr 8fr 3fr; + column-gap: 4rem; align-items: center; - margin-bottom: 0rem; + margin: 0rem 4rem; & li { list-style: none; @@ -68,6 +66,35 @@ main { font-size: 1.25rem; font-weight: bold; } + & .footer-links { + column-gap: 1.5rem; + line-height: normal; + + & a { + color: white; + text-decoration-color: white; + inline-size: min-content; + display: inline-block; + text-wrap: nowrap; + } + } + + & .footer-icons { + column-gap: 3rem; + row-gap: 1rem; + + & img { + filter: invert(100%); + margin-bottom: 0.1rem; + margin-top: 0.1rem; + min-width: 1.75rem; + width: 1.75rem; + } + } +} + +.footer-logo { + min-width: 60px; } /* Hide download button */ @@ -102,3 +129,7 @@ h4 { .bd-sidebar-primary { border-right: 0; } + +.copyright { + font-size: smaller; +} diff --git a/template/assets/icons/README.md b/template/assets/icons/README.md new file mode 100644 index 0000000..eff88d2 --- /dev/null +++ b/template/assets/icons/README.md @@ -0,0 +1,8 @@ +You can find more free icons at: + +- https://fonts.google.com/icons (Search and then click the SVG download button at the bottom of the right-hand column.) +- https://simpleicons.org/ + +Apache licensed, but with a notice at https://github.com/google/material-design-icons: + +> We'd love attribution in your app's about screen, but it's not required. diff --git a/template/assets/icons/bluesky.svg b/template/assets/icons/bluesky.svg new file mode 100644 index 0000000..e332981 --- /dev/null +++ b/template/assets/icons/bluesky.svg @@ -0,0 +1 @@ +Bluesky diff --git a/template/assets/icons/discord.svg b/template/assets/icons/discord.svg new file mode 100644 index 0000000..822322f --- /dev/null +++ b/template/assets/icons/discord.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/discourse.svg b/template/assets/icons/discourse.svg new file mode 100644 index 0000000..28eb5f7 --- /dev/null +++ b/template/assets/icons/discourse.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/facebook.svg b/template/assets/icons/facebook.svg new file mode 100644 index 0000000..2f755c3 --- /dev/null +++ b/template/assets/icons/facebook.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/github.svg b/template/assets/icons/github.svg new file mode 100644 index 0000000..7840857 --- /dev/null +++ b/template/assets/icons/github.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/instagram.svg b/template/assets/icons/instagram.svg new file mode 100644 index 0000000..a117827 --- /dev/null +++ b/template/assets/icons/instagram.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/linkedin.svg b/template/assets/icons/linkedin.svg new file mode 100644 index 0000000..8414bf3 --- /dev/null +++ b/template/assets/icons/linkedin.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/mail.svg b/template/assets/icons/mail.svg new file mode 100644 index 0000000..c307bed --- /dev/null +++ b/template/assets/icons/mail.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/mastodon.svg b/template/assets/icons/mastodon.svg new file mode 100644 index 0000000..d059845 --- /dev/null +++ b/template/assets/icons/mastodon.svg @@ -0,0 +1 @@ +Mastodon diff --git a/template/assets/icons/rss-feed.svg b/template/assets/icons/rss-feed.svg new file mode 100644 index 0000000..44b27a8 --- /dev/null +++ b/template/assets/icons/rss-feed.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/scientific-python.svg b/template/assets/icons/scientific-python.svg new file mode 100644 index 0000000..d9e0ad0 --- /dev/null +++ b/template/assets/icons/scientific-python.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/sent.svg b/template/assets/icons/sent.svg new file mode 100644 index 0000000..40c9490 --- /dev/null +++ b/template/assets/icons/sent.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/tiktok.svg b/template/assets/icons/tiktok.svg new file mode 100644 index 0000000..8248f39 --- /dev/null +++ b/template/assets/icons/tiktok.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/twitter.svg b/template/assets/icons/twitter.svg new file mode 100644 index 0000000..5e23e61 --- /dev/null +++ b/template/assets/icons/twitter.svg @@ -0,0 +1 @@ + diff --git a/template/assets/icons/youtube.svg b/template/assets/icons/youtube.svg new file mode 100644 index 0000000..eb6089f --- /dev/null +++ b/template/assets/icons/youtube.svg @@ -0,0 +1 @@ + diff --git a/template/assets/json/footer_items.json b/template/assets/json/footer_items.json new file mode 100644 index 0000000..4ab433c --- /dev/null +++ b/template/assets/json/footer_items.json @@ -0,0 +1,19 @@ +{ + "links": { + "About": "/about", + "Roadmap": "/roadmap", + "Code of conduct": "/code_of_conduct", + "SPECs": "/specs", + "Summits": "/summits", + "Calendars": "/calendars", + "Press kit": "/press-kit" + }, + "icons": { + "github": "https://github.com/scientific-python/", + "youtube": "https://www.youtube.com/c/ScientificPython-org", + "mastodon": "https://fosstodon.org/@scientific_python", + "bluesky": "https://bsky.app/profile/scientific-python.org", + "discourse": "https://discuss.scientific-python.org/", + "discord": "https://discord.com/invite/vur45CbwMz" + } +} diff --git a/template/config/scientific-python.yml b/template/config/scientific-python.yml index 2e1bdd6..f0379e0 100644 --- a/template/config/scientific-python.yml +++ b/template/config/scientific-python.yml @@ -2,7 +2,9 @@ version: 1 project: plugins: - team-grid.mjs - + - footer-items.mjs + exclude: + - assets/icons/README.md site: template: book-theme parts: diff --git a/template/footer-items.mjs b/template/footer-items.mjs new file mode 100644 index 0000000..fe8c959 --- /dev/null +++ b/template/footer-items.mjs @@ -0,0 +1,77 @@ +import { readFileSync } from 'node:fs'; + +/** @type {import('myst-common').DirectiveSpec} */ +const footerLinksDirective = { + name: 'footer-links', + doc: 'Display footer links from a JSON file.', + options: { + file: { + type: String, + required: true, + doc: 'Path to the JSON file, relative to the project root.', + }, + }, + run(data) { + const footerLinks = JSON.parse(readFileSync(data.options.file, 'utf-8')); + return Object.entries(footerLinks["links"]).map( + ([text, url]) => ({ + type: 'grid-item', + children: [ + { + type: 'link', + url: url, + children: [ + { + type: 'text', + value: text + } + ] + } + ] + }) + ); + } +}; + +/** @type {import('myst-common').DirectiveSpec} */ +const footerIconsDirective = { + name: 'footer-icons', + doc: 'Display footer icons from a JSON file.', + options: { + file: { + type: String, + required: true, + doc: 'Path to the JSON file, relative to the project root.', + }, + }, + run(data) { + const footerIcons = JSON.parse(readFileSync(data.options.file, 'utf-8')); + return Object.entries(footerIcons["icons"]).map( + ([text, url]) => ({ + type: 'grid-item', + children: [ + { + type: 'link', + url: url, + children: [ + { + type: 'image', + url: `/assets/icons/${text}.svg`, + alt: text + } + ] + } + ] + }) + ); + return IconsGrid; + } +}; + +/** @type {import('myst-common').MystPlugin} */ +const plugin = { + name: 'Footer Items', + directives: [footerLinksDirective, footerIconsDirective], +}; + +export default plugin; diff --git a/template/footer.md.jinja b/template/footer.md.jinja index 494e779..078c6e6 100644 --- a/template/footer.md.jinja +++ b/template/footer.md.jinja @@ -4,42 +4,58 @@ % parts: % footer: footer.md -% Here we use `grid` to add a basic grid structure to the HTML, -% but the formatting column sizes are defined manually in css/footer.css -% see the `grid-template-columns` line. -:::::{grid} 3 3 5 5 -:class: outer-grid col-screen - - +% Here we use `grid` to add a basic grid structure to the footer, but we don't use +% :columns: property of the grid-items to set widths; instead they're defined in +% asserts/css/scientific-python.css using the `grid-template-columns` property. -::::{div} +::::::{grid} 1 1 4 4 +:class: outer-grid col-screen -```{image} assets/images/logo.svg + +:::::{grid-item} +:::{image} assets/images/logo.svg :width: 60px -:align: left -``` - -Community-driven and community-owned initiative dedicated to building a robust, sustainable ecosystem for statistical software in Python. -:::: - - - -::::{div} -:::: +:class: footer-logo +::: +::::: - + +:::::{grid-item} +Community-driven and community-owned initiative dedicated to building a robust, sustainable ecosystem for scientific software in Python. +::::: -% This a _second_ grid embedded within the first one, to create nicer + +:::::{grid-item} +% This a grid embedded within the outer one, to create nicer % responsive design experience. This grid will have a single column on narrow screens, % and fan out into three columns on wide screens. However, it always remains within % its parent grid column. -::::{grid} 1 1 3 3 +::::{grid} 1 1 2 3 +:class: footer-links + +:::{footer-links} +:file: {{ footer_items_json }} +::: + +:::: +::::: -:::{div} + +:::::{grid-item} +:class: socials -- [About](/about) - ::: +::::{grid} 2 2 3 6 +:class: footer-icons + +:::{footer-icons} +:file: {{ footer_items_json }} +::: :::: +:::{div .copyright} +© 2026 {{ project_name }} team. All rights reserved. +::: + ::::: +::::::