-
-
Notifications
You must be signed in to change notification settings - Fork 11
Automate jobs board with schema validation #360
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
937757a
b941db1
bf8c2c5
d6f7765
c6f022f
3980ea3
3e6b9d6
5859815
542e662
2d0361c
96237a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,3 +44,48 @@ content-container class */ | |
| .news-container, .hero-container { | ||
| width: 100%; | ||
| } | ||
|
|
||
| /* Admonitions: minor accessibility tweaks */ | ||
| .adm { opacity: 1; } | ||
| .adm a { text-decoration: underline; } | ||
|
|
||
| @media (prefers-color-scheme: dark) { | ||
| /* prefer specificity over !important to avoid fighting the theme */ | ||
| .article .adm, .article .adm *, | ||
| .content .adm, .content .adm *, | ||
| .markdown .adm, .markdown .adm * { | ||
| color: var(--text, #f1f5f9); | ||
| } | ||
| .adm a { color: var(--primary, #9ae6b4); } | ||
| .adm { background: var(--surface-2, rgba(255,255,255,0.06)); } | ||
| } | ||
|
Comment on lines
56
to
61
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed, removed !important and used selector specificity as advised |
||
|
|
||
| /* Jobs board styles, scoped */ | ||
| .jobs-board .job-card { | ||
| border: 1px solid var(--border, rgba(0,0,0,0.15)); | ||
| padding: 1rem; | ||
| border-radius: 6px; | ||
| margin: 1rem 0; | ||
| background: var(--surface, transparent); | ||
| } | ||
| .jobs-board .job-card__header { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; } | ||
| .jobs-board .job-card__title { margin: 0; font-size: 1.15rem; } | ||
| .jobs-board .job-card__entity { color: var(--text-muted, inherit); font-weight: 600; } | ||
| .jobs-board .job-card__meta, .jobs-board .job-card__dates { display: flex; flex-wrap: wrap; gap: .5rem .5rem; margin: .5rem 0; } | ||
| .jobs-board .job-badge { | ||
| display: inline-flex; | ||
| align-items: center; | ||
| background: var(--surface-2, rgba(0,0,0,0.04)); | ||
| border: 1px solid var(--border, rgba(0,0,0,0.15)); | ||
| padding: .15rem .4rem; | ||
| border-radius: 999px; | ||
| font-size: .85rem; | ||
| color: var(--text, inherit); | ||
| margin-right: .5rem; | ||
| margin-bottom: .5rem; | ||
| } | ||
| .jobs-board .job-card__dates span { margin-right: .75rem; } | ||
| .jobs-board .job-card__description { margin: .5rem 0; color: inherit; line-height: 1.55; } | ||
| .jobs-board .job-card__description ul, .jobs-board .job-card__description ol { margin: .5rem 0 .5rem 1.25rem; } | ||
| .jobs-board .job-card__apply .button { display: inline-block; } | ||
| .jobs-board .job-card--archived { opacity: .85; } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # Job posting template for the PyBaMM jobs board. | ||
| # Copy this file to a new name (e.g. acme-battery-modeler-20250315.yaml) and fill it in. | ||
| # Required keys: entity, title, url, percentTime, percentOSS, deadline, expires, location, description | ||
| # Notes: dates = YYYY-MM-DD; url starts with http(s); percentTime 1–100; percentOSS 0–100. | ||
|
|
||
| entity: Your Organisation | ||
| title: Battery Modeling Engineer (PyBaMM) | ||
| url: https://www.example.com/careers/battery-modeling-engineer | ||
| percentTime: 100 | ||
| percentOSS: 50 | ||
| deadline: 2026-01-31 | ||
| expires: 2026-02-28 | ||
| location: Remote (UTC±2 preferred) | ||
| tags: [full-time, PyBaMM, Python] | ||
| # author_date: 2025-12-01 | ||
|
|
||
| description: | | ||
| One or two short paragraphs describing the role and team. | ||
|
|
||
| Responsibilities: | ||
| - Build, validate, and maintain physics-based battery models with PyBaMM | ||
| - Parameterise models, run studies, and analyse results | ||
| - Collaborate with the open-source community where appropriate | ||
|
|
||
| Requirements: | ||
| - Strong Python and numerical methods | ||
| - Experience with physics-based battery modeling or electrochemistry | ||
| - Clear communication and collaboration |
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use the existing Ionworks example here and include it, instead of Example Company.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. addressed, replaced the example with Ionworks example |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| entity: Ionworks | ||
| title: Battery Modeling Engineer (PyBaMM) | ||
| url: https://www.ionworks.com/ | ||
| percentTime: 100 | ||
| percentOSS: 50 | ||
| deadline: 2026-01-31 | ||
| expires: 2026-02-28 | ||
| location: Remote (UK/EU time zones preferred) | ||
| tags: [full-time, modeling, PyBaMM, Python] | ||
| description: | | ||
| Ionworks is looking for a Battery Modeling Engineer to build and deploy | ||
| physics-based battery models using PyBaMM for clients across industry and academia. | ||
|
|
||
| Responsibilities: | ||
| - Develop, validate, and maintain battery models using PyBaMM | ||
| - Parameterise models, run simulations, and analyse results for production use | ||
| - Collaborate with open-source maintainers and contribute improvements back to PyBaMM where appropriate | ||
|
|
||
| Requirements: | ||
| - Strong Python experience and familiarity with numerical methods | ||
| - Experience with physics-based battery modelling and scientific computing | ||
| - Excellent communication and collaboration skills |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "title": "PyBaMM Jobs Board Posting", | ||
| "type": "object", | ||
| "additionalProperties": false, | ||
| "required": [ | ||
| "entity", | ||
| "title", | ||
| "url", | ||
| "percentTime", | ||
| "percentOSS", | ||
| "deadline", | ||
| "expires", | ||
| "location", | ||
| "description" | ||
| ], | ||
| "properties": { | ||
| "entity": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "title": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "url": { | ||
| "type": "string", | ||
| "minLength": 1, | ||
| "pattern": "^https?://" | ||
| }, | ||
| "percentTime": { | ||
| "type": "integer", | ||
| "minimum": 1, | ||
| "maximum": 100 | ||
| }, | ||
| "percentOSS": { | ||
| "type": "integer", | ||
| "minimum": 0, | ||
| "maximum": 100 | ||
| }, | ||
| "deadline": { | ||
| "type": "string", | ||
| "pattern": "^\\d{4}-\\d{2}-\\d{2}$" | ||
| }, | ||
| "expires": { | ||
| "type": "string", | ||
| "pattern": "^\\d{4}-\\d{2}-\\d{2}$" | ||
| }, | ||
| "author_date": { | ||
| "type": "string", | ||
| "pattern": "^\\d{4}-\\d{2}-\\d{2}$" | ||
| }, | ||
| "location": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "tags": { | ||
| "type": "array", | ||
| "items": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| }, | ||
| "uniqueItems": true | ||
| }, | ||
| "description": { | ||
| "type": "string", | ||
| "minLength": 1 | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| {{/* Renders a single job using theme shortcodes (card, badge, button). Expects dict with keys: job, now */}} | ||
| {{- $job := .job -}} | ||
| {{- $now := .now -}} | ||
| {{- $open := or (not $job.expires) (ge (time $job.expires) $now) -}} | ||
|
|
||
| {{- $scratch := newScratch -}} | ||
|
|
||
| {{/* Build badges using theme badge shortcode */}} | ||
| {{- with $job.location -}} | ||
| {{- $scratch.Add "badges" (printf "{{< badge secondary >}}%s{{< /badge >}} " .) -}} | ||
| {{- end -}} | ||
| {{- with $job.percentTime -}} | ||
| {{- $scratch.Add "badges" (printf "{{< badge primary >}}%d%% time{{< /badge >}} " .) -}} | ||
| {{- end -}} | ||
| {{- with $job.percentOSS -}} | ||
| {{- $scratch.Add "badges" (printf "{{< badge success >}}%d%% OSS{{< /badge >}} " .) -}} | ||
| {{- end -}} | ||
| {{- with $job.tags -}} | ||
| {{- range . -}} | ||
| {{- $scratch.Add "badges" (printf "{{< badge muted >}}%s{{< /badge >}} " .) -}} | ||
| {{- end -}} | ||
| {{- end -}} | ||
| {{- $badges := $scratch.Get "badges" | default "" -}} | ||
|
|
||
| {{/* Dates summary */}} | ||
| {{- $dates := "" -}} | ||
| {{- with $job.deadline -}} | ||
| {{- $dates = printf "%s\n- Deadline: %s" $dates . -}} | ||
| {{- end -}} | ||
| {{- with $job.expires -}} | ||
| {{- $dates = printf "%s\n- Visible until: %s" $dates . -}} | ||
| {{- end -}} | ||
|
|
||
| {{/* Optional apply button */}} | ||
| {{- $apply := "" -}} | ||
| {{- with $job.url -}} | ||
| {{- $apply = printf "\n\n{{< button style=\"primary\" label=\"Apply / Learn more\" link=\"%s\" >}}" . -}} | ||
| {{- end -}} | ||
|
|
||
| {{/* Card class for archived */}} | ||
| {{- $classcard := "" -}} | ||
| {{- if not $open -}} | ||
| {{- $classcard = "sd-opacity-75" -}} | ||
| {{- end -}} | ||
|
|
||
| {{- $body := printf "%s\n\n%s\n\n%s%s" ($job.entity | default "") $badges ($job.description | default "") $apply -}} | ||
| {{- $card := printf "{{< card >}}\n%s\n%s\n%s\n%s\n{{< /card >}}" | ||
| (printf "title = '%s'" ($job.title | default "")) | ||
| (cond (ne $classcard "") (printf "classcard = '%s'" $classcard) "") | ||
| (printf "body = '''\n%s\n%s\n'''" ($body | replaceRE "'" "\\'")) | ||
| (cond (and $job.url (ne $job.url "")) (printf "link = '%s'" $job.url) "") | ||
| -}} | ||
|
|
||
| {{ .Page.RenderString $card }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| {{/* | ||
| Lists jobs from data/jobs. Splits into open and archived by expires date. | ||
| Sorts open by deadline asc; archived by expires desc. | ||
| */}} | ||
| {{- $now := now -}} | ||
| {{- $jobs := slice -}} | ||
|
|
||
| {{/* Load YAML job postings directly from data/jobs */}} | ||
| {{- range (readDir "data/jobs") -}} | ||
| {{- if and (not .IsDir) (or (hasSuffix .Name ".yaml") (hasSuffix .Name ".yml")) (ne .Name "_TEMPLATE.yaml") (ne .Name "schema.json") -}} | ||
| {{- $path := printf "data/jobs/%s" .Name -}} | ||
| {{- $data := (readFile $path | transform.Unmarshal) -}} | ||
| {{- $key := replaceRE "\\.(yaml|yml)$" "" .Name -}} | ||
| {{- $job := (dict "key" $key) | merge $data -}} | ||
| {{- $jobs = $jobs | append $job -}} | ||
| {{- end -}} | ||
| {{- end -}} | ||
|
|
||
| {{/* partition */}} | ||
| {{- $open := slice -}} | ||
| {{- $archived := slice -}} | ||
| {{- range $jobs -}} | ||
| {{- $exp := .expires -}} | ||
| {{- if or (not $exp) (ge (time $exp) $now) -}} | ||
| {{- $open = $open | append . -}} | ||
| {{- else -}} | ||
| {{- $archived = $archived | append . -}} | ||
| {{- end -}} | ||
| {{- end -}} | ||
|
|
||
| {{- $sortedOpen := sort $open "deadline" "asc" -}} | ||
|
|
||
| <h2 id="open-roles">Open roles</h2> | ||
| {{- if gt (len $sortedOpen) 0 -}} | ||
| {{- range $sortedOpen -}} | ||
| {{ partial "jobs/card.html" (dict "job" . "now" $now) }} | ||
| {{- end -}} | ||
| {{- else -}} | ||
| <p>No open roles at the moment.</p> | ||
| {{- end -}} | ||
|
|
||
| <hr/> | ||
|
|
||
| {{- $sortedArchived := sort $archived "expires" "desc" -}} | ||
| {{- $body := "" -}} | ||
| {{- if gt (len $sortedArchived) 0 -}} | ||
| {{- $scratch := newScratch -}} | ||
| {{- range $sortedArchived -}} | ||
| {{- $scratch.Add "html" (partial "jobs/card.html" (dict "job" . "now" $now)) -}} | ||
| {{- end -}} | ||
| {{- $body = $scratch.Get "html" -}} | ||
| {{- else -}} | ||
| {{- $body = "<p>No archived roles yet.</p>" -}} | ||
| {{- end -}} | ||
| {{- $md := printf "{{< details \"%s\" >}}\n%s\n{{< /details >}}" "Archived roles" $body -}} | ||
| {{ .Page.RenderString $md }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| {{/* Shortcode to render the jobs list from data/jobs */}} | ||
| <div class="jobs-board"> | ||
| {{ partial "jobs/list.html" . }} | ||
| </div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the code in this file was generated with AI. While we are okay with the use of AI-written code, we consider it your responsibility to thoroughly review it and address any potential mistakes. Could you please remove the comments indicative of AI and remove the redundant CSS rules from here?
Also, these styles will apply to the entire website, so we must ensure that they affect only the jobs page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
addressed and applied the requested clean up and scoping
scoped jobs styles to jobs page and removed ai indicative and verbose comments, also avoided unnecessary global impact, now job related rules are isolated under .jobs-board