diff --git a/.github/ISSUE_TEMPLATE/project.md b/.github/ISSUE_TEMPLATE/project.md index 54e486a..29c8c01 100644 --- a/.github/ISSUE_TEMPLATE/project.md +++ b/.github/ISSUE_TEMPLATE/project.md @@ -7,6 +7,16 @@ assignees: "" --- + + +## Project page + +(Link to the pull request that adds the project page.) + ## Description (Give a complete description of the proposed documentation changes. Include specific steps. Break it down into tasks people can start working on.) @@ -22,3 +32,7 @@ assignees: "" ## Challenges and risks (Enumerate some possible pitfalls that will need to be navigated.) + +## How to help + +(Concrete ways a contributor can get involved.) diff --git a/README.md b/README.md index d088072..282198d 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,16 @@ pixi run serve Use `pixi run build` to build the production site into `public/`. +## Adding a project + +The [Projects page](https://python.github.io/editorial-board/projects/) is built from one Markdown +file per project under ``content/projects/``, using the template in +[archetypes/projects.md](archetypes/projects.md). + +See [Adding a project](https://python.github.io/editorial-board/projects/how-to-add/) on the site +for how to propose a project, the frontmatter fields, and how the project page is laid out. +Its source is [content/adding-a-project.md](content/adding-a-project.md). + ## Writing new changelog Use the template in [archetypes/changelog.md](archetypes/changelog.md). diff --git a/archetypes/projects.md b/archetypes/projects.md new file mode 100644 index 0000000..39fe9ab --- /dev/null +++ b/archetypes/projects.md @@ -0,0 +1,44 @@ +--- +title: "{{ replace .File.ContentBaseName "-" " " | title }}" +# The date the project was added to the list. Used to order the RSS feed. +date: "{{ .Date }}" +# proposed | active | blocked | done +status: "proposed" +# Editorial Board member sponsoring the project. Leave empty if none yet. +sponsor: "" +# Person actively leading the work. Leave empty if none yet. +# An active project must have a lead. +lead: "" +# One or two sentences on what this project delivers. +summary: "" +# Link to the project issue: the issue that fully describes the project. +project_issue: "" +# Rough priority within its status group: lower numbers are listed first. +weight: 100 +# Other relevant issues, PRs, discussions, or docs. GitHub issue and PR links +# get a live status badge, and their title is filled in from GitHub if left empty. +links: [] +# - title: "" +# url: "" +--- + +## Description + +What the work is, broken down into tasks if possible. + +## Benefits + +Who benefits and why this is worth doing now. + +## Decisions + +Smaller decisions that are still open. Major decisions should be made before the +project is listed. + +## Challenges and risks + +The hard parts and possible pitfalls. + +## How to help + +Concrete ways a contributor can get involved. diff --git a/assets/css/extended/custom.css b/assets/css/extended/custom.css index f2fc370..33e6419 100644 --- a/assets/css/extended/custom.css +++ b/assets/css/extended/custom.css @@ -36,4 +36,258 @@ } #members li:last-child:after { content: ""; -} \ No newline at end of file +} +.project-meta { + display: grid; + grid-template-columns: max-content 1fr; + gap: 0.25rem 1rem; + margin: 0.75rem 0 1.5rem; + font-size: 0.9em; +} + +.project-meta dt { + font-weight: 600; +} + +.project-meta dd { + margin: 0; +} + +.project-status { + display: inline-block; + min-width: 5.5em; + padding: 0 0.5em; + border-radius: 999px; + border: 1px solid currentColor; + font-size: 0.8em; + text-align: center; +} + +.project-status-active { color: #1a7f37; } +.project-status-proposed { color: #0969da; } +.project-status-blocked { color: #bc4c00; } +.project-status-done { color: #8250df; } + +[data-theme="dark"] .project-status-active { color: #3fb950; } +[data-theme="dark"] .project-status-proposed { color: #4493f8; } +[data-theme="dark"] .project-status-blocked { color: #db6d28; } +[data-theme="dark"] .project-status-done { color: #ab7df8; } + +.project-filter { + display: flex; + flex-wrap: wrap; + gap: 0.75rem 1.5rem; + align-items: end; + margin: 1rem 0 1.5rem; +} + +.project-filter label { + display: flex; + flex-direction: column; + gap: 0.25rem; + font-size: 0.9em; +} + +.project-filter input[type="search"], +.project-filter select { + padding: 0.3rem 0.5rem; + border: 1px solid var(--border); + border-radius: 4px; + background: var(--entry); + color: var(--primary); + box-sizing: border-box; + width: 16rem; + max-width: 100%; + height: 2.25rem; + font: inherit; + font-size: 0.95em; + line-height: normal; +} + +.project-filter #project-filter-empty, +.project-filter #project-filter-count { + flex-basis: 100%; + margin: 0; +} + +.project-meta a, +.project-refs td a, +.project-table a.project-title { + text-decoration: underline; + text-underline-offset: 0.15em; +} + +.project-meta a:hover, +.project-refs td a:hover, +.project-table a.project-title:hover { + text-decoration-thickness: 2px; +} + +.project-table-wrap { + overflow-x: auto; +} + +.post-content .project-table { + display: table; + width: 100%; + border-collapse: collapse; + font-size: 0.95em; +} + +.md-content .project-table-wrap table.project-table th, +.md-content .project-table-wrap table.project-table td { + padding: 0.6rem 0.75rem; + border: 0; + border-bottom: 1px solid var(--border); + text-align: left; + vertical-align: top; +} + +.md-content .project-table-wrap table.project-table th { + font-weight: 600; + white-space: nowrap; +} + +.md-content .project-table-wrap table.project-table td:not(:first-child) { + white-space: nowrap; +} + +.project-table a.project-title { + font-weight: 600; +} + +.project-row-summary { + margin-top: 0.25rem; + color: var(--secondary); + font-size: 0.9em; +} + +.project-row-summary p { + margin: 0; +} + +.project-needed { + color: var(--secondary); +} + +.project-row:target { + background: var(--code-bg); +} + +.gh-ref .gh-title { + color: var(--secondary); +} + +.gh-state { + display: inline-block; + min-width: 5.5em; + margin-right: 0.4em; + padding: 0 0.5em; + border-radius: 999px; + border: 1px solid currentColor; + font-size: 0.8em; + text-align: center; +} + +.gh-state-open { color: #1a7f37; } +.gh-state-merged, +.gh-state-completed { color: #8250df; } +.gh-state-closed { color: #cf222e; } +.gh-state-draft, +.gh-state-not-planned { color: #59636e; } + +[data-theme="dark"] .gh-state-open { color: #3fb950; } +[data-theme="dark"] .gh-state-merged, +[data-theme="dark"] .gh-state-completed { color: #ab7df8; } +[data-theme="dark"] .gh-state-closed { color: #f85149; } +[data-theme="dark"] .gh-state-draft, +[data-theme="dark"] .gh-state-not-planned { color: #9198a1; } + +/* Smaller heading scale than PaperMod's defaults (40/32/24px), site-wide. */ +.page-header h1, +.post-title { + font-size: 30px; +} + +.md-content h1 { + margin: 32px auto 20px; + font-size: 28px; +} + +.md-content h2 { + margin: 28px auto 16px; + font-size: 24px; +} + +.md-content h3 { + margin: 24px auto 12px; + font-size: 20px; +} + +.md-content h4 { + font-size: 18px; +} + +.first-entry .entry-header h1 { + font-size: 30px; +} + +.first-entry .entry-header h2 { + font-size: 30px; +} + +.entry-header h2 { + font-size: 20px; +} + +@media screen and (max-width: 768px) { + .page-header h1, + .post-title { + font-size: 26px; + } + + .md-content h2 { + font-size: 22px; + } +} + +.project-refs { + margin-top: 2rem; +} + +.md-content .project-table-wrap table.gh-ref-table td:first-child { + width: 1%; +} + +.md-content .project-table-wrap table.gh-ref-table td.gh-title { + white-space: normal; + color: var(--primary); +} + +.gh-ref-table .gh-state { + margin-right: 0; +} + +.project-filter input[type="search"] { + -webkit-appearance: none; + appearance: none; +} + +.md-content .project-table-wrap table.link-table td:first-child { + white-space: normal; +} + +.md-content .project-table-wrap table.link-table td:last-child { + color: var(--secondary); +} + +/* PaperMod has no [hidden] reset, so the display rules above would otherwise + override the hidden attribute. Scoped to the project elements: a global rule + would also hide PaperMod's heading anchors, which use hidden too. */ +.gh-state[hidden], +.project-filter[hidden], +.project-filter p[hidden], +.project-table[hidden], +.project-row[hidden] { + display: none; +} diff --git a/content/adding-a-project.md b/content/adding-a-project.md new file mode 100644 index 0000000..ef06179 --- /dev/null +++ b/content/adding-a-project.md @@ -0,0 +1,150 @@ +--- +title: "Adding a project" +url: "/projects/how-to-add/" +summary: "How to propose a documentation project and add it to the Editorial Board's project list." +hideMeta: true +ShowToc: true +TocOpen: false +ShowPostNavLinks: false +--- + +This page explains how a project gets onto the [project list]({{< relref "projects" >}}), +and how to write its page. + +## From idea to project page + +1. **Open an issue.** Use the + [Suggest a project](https://github.com/python/editorial-board/issues/new?template=project.md) + template. Describe the work, its benefits, the decisions needed, and the challenges and risks. + The issue is where the proposal is discussed. +2. **Open a pull request with the project page.** Alongside the issue, open a pull request that + adds one Markdown file for the project under + [`content/projects/`](https://github.com/python/editorial-board/tree/main/content/projects), + filled in as described below. Set `project_issue` to the issue from step 1, and mention the + issue in the pull request description. You don't need Hugo installed: a preview of the site + is built for every pull request, so you can see how the page will look. +3. **Get it approved.** The Editorial Board reviews the issue and the project page together, + usually at a monthly meeting. The board may ask for changes to the page, for example to + the scope, the challenges, or the status. Merging the pull request adds the project to the list. + +## Creating the file + +Copy the template in +[`archetypes/projects.md`](https://github.com/python/editorial-board/blob/main/archetypes/projects.md), +or, if you have Hugo installed, run: + +``` +hugo new content content/projects/short-project-name.md +``` + +The file name becomes the project page's URL, so keep it short and descriptive. + +## Frontmatter + +| Field | Required | Description | +|-------|----------|-------------| +| `title` | yes | The project's name. | +| `date` | yes | The date the project was added to the list, for example `2026-11-10`. Used to order the projects RSS feed. | +| `status` | yes | One of `proposed`, `active`, `blocked`, or `done`. Any other value fails the build. See [Statuses](#statuses). | +| `lead` | for `active` | The person actively leading the work. Leave empty if there is no lead yet; the page shows "Needs a committed lead". | +| `sponsor` | no | The Editorial Board member sponsoring the project. Leave empty if none yet. | +| `summary` | yes | One or two sentences on what the project delivers. Shown in the project list. | +| `project_issue` | no | Link to the project issue: the issue that fully describes the project, usually the one opened with the "Suggest a project" template. | +| `weight` | no | Rough priority. The list shows active projects first, then proposed, blocked, and done; within each status, lower numbers are listed first. | +| `links` | no | Related issues, PRs, discussions, or docs, as a list of `url` entries with an optional `title`. See [Links](#links). | + +See the [example](#example) below for a complete project file. + +## Page body + +Below the frontmatter, describe the project with these sections, matching the issue template: + +- **Description**: what the work is, broken down into tasks if possible. +- **Benefits**: who benefits and why it is worth doing now. +- **Decisions**: smaller decisions that are still open. Major decisions should be made + before a project is listed, so the work is ready to start. +- **Challenges and risks**: the hard parts. Every project should name these. +- **How to help**: concrete ways a contributor can get involved. + +## Example + +A complete project file, `content/projects/off-by-one-pizza.md`: + +```markdown +--- +title: "End the off-by-one pizza incidents" +date: "2026-04-01" +status: "active" +sponsor: "" +lead: "Spam Eggington" +summary: "Explain range() so clearly that nobody orders 9 pizzas for a party of 10 ever again." +project_issue: "https://github.com/example/office-party/issues/42" +weight: 10 +links: + - title: "range(10) stopping at 9 is not intuitive" + url: "https://github.com/example/office-party/issues/43" + - url: "https://github.com/example/office-party/pull/44" + - title: "Pizza slicing reference" + url: "https://docs.example.com/pizza/slicing.html" +--- + +## Description + +Every office party, someone writes `for slice in range(1, 10)` and one guest goes hungry. +This project rewrites the guide to counting things so the end of a range is never a surprise. + +1. Explain why `range(10)` gives ten numbers but never the number 10. +2. Add a worked example: splitting 8 slices between 3 people with `divmod()`, + and what to do with the leftover slices. +3. Add a "counting from zero" sidebar for readers who still count on their fingers. + +## Benefits + +- Fewer hungry guests, and fewer bug reports titled "range is broken". +- Readers new to Python learn half-open ranges once, instead of once per party. + +## Decisions + +- Should the examples use pizza, or something less controversial, like cake? +- Does the leftover-slices example belong in this guide or in the `divmod()` reference? + +## Challenges and risks + +- Pineapple: any pizza example will start an argument that has nothing to do with Python. +- Readers who are used to inclusive ranges in other languages may need more than one example. +- The lead is easily distracted by actual pizza. + +## How to help + +- Review the draft and tell us where you first got confused. +- Suggest a better example than pizza, if one exists. +- Bring snacks to the review meeting. +``` + +## Links + +The entries in `links` are shown after the page body, in two tables: + +- **Issues and pull requests**: any GitHub issue or pull request URL. Each one is shown as + `owner/repo#number` with a status badge: Open, Draft, Merged, Closed, or Not planned. + The status is fetched from GitHub in the reader's browser, so it stays current without + rebuilding the site. If `title` is left out, the title from GitHub is shown instead. + Don't put the status in the title, since the badge already shows it. +- **Links**: everything else, such as pages in the docs, shown with the site they're on. + Give these a `title`, otherwise the URL itself is shown. + +The `project_issue` link is shown at the top of the page, with the same status badge. + +If GitHub can't be reached, for example because of its limit on anonymous requests, +the links still work but are shown without a status badge. + +## Statuses + +- **Proposed**: approved as worth doing, but not yet started, or still missing a lead. +- **Active**: work is underway with a committed lead. +- **Blocked**: work can't continue, for example because the project lost its lead. +- **Done**: finished. Keep the page so the list shows what was accomplished. + +The project list can be searched and filtered by status. Filters are kept in the URL, so a +filtered view can be shared, for example +[`/projects/?status=active`]({{< relref "projects" >}}?status=active). diff --git a/content/projects.md b/content/projects.md deleted file mode 100644 index 7ee89cd..0000000 --- a/content/projects.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: "Projects" -url: "/projects" -summary: "Documentation projects the Editorial Board is leading or shepherding." -hideMeta: true -ShowToc: true -TocOpen: true ---- - -> **Status: Draft.** This page is a work in progress, started following the -> [June 2026 meeting]({{< relref "updates/2026-06-09" >}}). - -This is the Editorial Board's list of significant documentation projects we have identified as valuable and actionable. It reflects our -[proactive stance]({{< relref "expectations#how-we-work-proactive-not-just-reactive" >}}): -rather than only reacting to requests, we identify important work and find -people to carry it out. - -## How this list works - -- **Every active project has a committed lead.** If a project loses its lead, it - becomes Blocked until a new lead steps up. -- **Each project names its challenges**, not just the goal. Describing the - hard parts up front helps contributors know what they are taking on. -- **We keep the list short and prioritized** rather than long and - aspirational, so we can give each project real oversight. - -Want to help with a project, or propose a new one? Open an -[issue on this repo](https://github.com/python/editorial-board/issues/new/choose) -or reach out in the [Python Docs Discord](https://discord.gg/nXkJ2JYvCu). - -## Project template - -Once a project is approved by the Editorial Board, copy this block to add a new project. - -```markdown -### - -- **Sponsor:** -- **Lead:** -- **Status:** Proposed | Active | Blocked | Done -- **Summary:** One or two sentences on what this project delivers. -- **Full issue:** A link to the issue (in this repo or elsewhere) that fully describes the project. Include complete description, decisions made, challenges/risks, acceptance criteria, etc. -- **Why it matters:** Who benefits and why this is worth doing now. -- **How to help:** Concrete ways a contributor can get involved. -- **Links:** Other relevant issues, PRs, discussions, or docs, if any. -``` - -## Projects - -_None listed yet. Add projects here using the template above._ Order them by rough priority with active projects first. - - diff --git a/content/projects/_index.md b/content/projects/_index.md new file mode 100644 index 0000000..a6b9455 --- /dev/null +++ b/content/projects/_index.md @@ -0,0 +1,44 @@ +--- +title: "Projects" +summary: "Documentation projects the Editorial Board is leading or shepherding." +hideMeta: true +ShowToc: false +cascade: + hideMeta: true + ShowToc: false + ShowPostNavLinks: false + ShowShareButtons: false +--- + +> **Status: Draft.** This page is a work in progress, started following the +> [June 2026 meeting]({{< relref "updates/2026-06-09" >}}). + +This is the Editorial Board's list of significant documentation projects we have identified as valuable and actionable. It reflects our +[proactive stance]({{< relref "expectations#how-we-work-proactive-not-just-reactive" >}}): +rather than only reacting to requests, we identify important work and find +people to carry it out. + +## How this list works + +- **Every active project has a committed lead.** If a project loses its lead, it + becomes Blocked until a new lead steps up. +- **Each project names its challenges**, not just the goal. Describing the + hard parts up front helps contributors know what they are taking on. +- **We keep the list short and prioritized** rather than long and + aspirational, so we can give each project real oversight. + +Want to help with a project, or propose a new one? Open an +[issue on this repo](https://github.com/python/editorial-board/issues/new/choose) +or reach out in the [Python Docs Discord](https://discord.gg/nXkJ2JYvCu). + +To hear about new projects, subscribe to the +[projects RSS feed]({{< relref "projects" >}}index.xml). + +## Adding a project {#project-template} + +Each project has its own page in +[`content/projects/`](https://github.com/python/editorial-board/tree/main/content/projects). +To propose a project, open an issue and, alongside it, a pull request adding the +project's page. The project is added to the list when the Editorial Board approves it +and the pull request is merged. See [Adding a project]({{< relref "adding-a-project" >}}) +for the details. diff --git a/hugo.yaml b/hugo.yaml index 72694fa..04adbbe 100644 --- a/hugo.yaml +++ b/hugo.yaml @@ -11,7 +11,7 @@ buildFuture: false buildExpired: false enableEmoji: true pygmentsUseClasses: true -mainsections: ["updates"] +mainsections: ["updates", "projects"] minify: disableXML: true @@ -44,13 +44,15 @@ params: homeInfoParams: Title: "Python Docs Editorial Board" - Content: > + Content: | This site contains activity updates, process, and planning information for the Python Documentation Editorial Board. See [PEP 732](https://peps.python.org/pep-0732/). The Editorial Board's private meetings are monthly on the second Tuesday at 1:30pm Pacific. + We maintain a [list of documentation projects](projects/) that we lead or shepherd. To propose a project, see [Adding a project](projects/how-to-add/). + If you have a general request or question, please use the [Documentation category in Discourse](https://discuss.python.org/c/documentation/26). If you need Editorial Board assistance, please [file an issue on this repo](https://github.com/python/editorial-board/issues/new/choose). diff --git a/layouts/_default/single.html b/layouts/_default/single.html index 8123b8d..d64aa52 100644 --- a/layouts/_default/single.html +++ b/layouts/_default/single.html @@ -29,6 +29,10 @@

{{- end }} {{- partial "members.html" . }} + {{- if eq .Section "projects" }} + {{- with .Params.summary }}
{{ . | markdownify }}
{{ end }} + {{- partial "project_meta.html" . }} + {{- end }} {{- $isHidden := (.Param "cover.hiddenInSingle") | default (.Param "cover.hidden") | default false }} {{- partial "cover.html" (dict "cxt" . "IsSingle" true "isHidden" $isHidden) }} @@ -43,6 +47,9 @@

{{- else }}in content{{ .Content }}{{ end }} {{- end }} + {{- if eq .Section "projects" }} + {{- partial "project_refs.html" . }} + {{- end }}