Skip to content

Careers and vacancies

Vacancies are career posts listed in an accordion block on the careers page and given a full page each under /careers/listing/<slug>. Applying uses a dedicated Contact Form 7 form whose vacancy dropdown is generated from the same posts.

Recruitment is a real acquisition channel for the firm, and vacancies change often enough that they need to be editor-managed content rather than page copy. The accordion exists so the careers page can list every role with a teaser without becoming a wall of text, and the application form’s dropdown is generated so it can never list a vacancy that has been filled.

Path What it does
wp-content/themes/bpcollins/inc/cpt.php:190 career post type — rewrite slug careers/listing
wp-content/themes/bpcollins/blocks/careers-accordion/block-careers-accordion.php The vacancy accordion, up to 20 roles
wp-content/themes/bpcollins/blocks/careers-accordion/block-careers-accordion.js Expand/collapse behaviour
wp-content/themes/bpcollins/single-career.php A single vacancy page
wp-content/themes/bpcollins/inc/template-functions.php:495 dynamic_careers_field() — fills the CF7 careers select
wp-content/themes/bpcollins/blocks/form-block/block-form-block.php:11-14 Swaps in the careers form on career singles
wp-content/themes/bpcollins/inc/classes/BPCareer.php Accessor: title, link, image, excerpt

Post type. career is public and hierarchical with rewrite slug careers/listing, so a vacancy lives at /careers/listing/<slug>/ while the careers landing page itself is an ordinary WordPress page at /careers/. There is no archive (has_archive => false); listing is done by the block.

The accordion queries up to 20 published career posts ordered by title, and for each renders a clickable row (title plus a plus/minus icon), a collapsed content panel containing the excerpt, and a “Find out more” link to the vacancy page. Panels start at inline height: 0 and are expanded by the block’s JS via the js-expand class. The left column takes its heading, copy and buttons from the block’s own fields through BlockMeta.

A single vacancy (single-career.php) renders the hero block, the vacancy content, and a sidebar listing up to 10 other vacancies — except the query has no exclusion, so the current vacancy appears in its own “Other vacancies” list. Below the article: team-strip, cta-bar, form-block and logo-carousel.

Applying. On a career single the form block resolves to the global careers_form with heading careers_form_title, and the section id becomes apply rather than form (block-form-block.php:45-53) — that is the anchor “Apply now” buttons target. Inside the form, any CF7 select named careers has its options replaced at render time with up to 20 vacancy titles by dynamic_careers_field().

Breadcrumbs for a vacancy get a synthetic /careers/ ancestor (inc/template-functions.php:297-303).

flowchart TD
A[career posts] --> B[careers-accordion block on /careers/]
A --> C[dynamic_careers_field fills CF7 careers select]
B --> D[/careers/listing/slug/ vacancy page]
D --> E[form-block resolves to careers_form, section id #apply]
E --> C
D --> F[sidebar: other vacancies]
  • Global Options ACF: careers_form (the CF7 form id) and careers_form_title.
  • Per-block: heading fields, copy, buttons_list.
  • Per-vacancy: title, content, excerpt (the excerpt is what the accordion shows) and featured image.
  • Recipients for applications are configured in the Contact Form 7 admin, not here.
  • The vacancy’s own “Other vacancies” list includes itself. The query at single-career.php:52-57 has no post__not_in.
  • Three different caps on the same content: the accordion shows 20 (block-careers-accordion.php:30), the sidebar 10 (single-career.php:54), and the CF7 dropdown 20 (inc/template-functions.php:504). More than 20 live vacancies means the form cannot express some of them.
  • The CF7 dropdown stores the vacancy title as the submitted value, not an ID. Renaming a vacancy after applications have been received breaks the link between submission text and post.
  • The accordion excerpt is the WordPress excerpt, and excerpt_length is globally forced to 30 words with a ... suffix (inc/template-functions.php:564-571). Long teasers get truncated silently.
  • $career is reassigned inside its own loop (block-careers-accordion.php:43) — the loop variable is overwritten by the BPCareer object. Harmless as written, but do not add code after that line expecting the ID.
  • Vacancy URLs contain /listing/ because of the rewrite slug. Any hand-written link to /careers/<slug>/ will 404.
  • Removing a vacancy removes it from the application dropdown immediately — but any in-flight page a candidate already has open will submit a value the dropdown no longer offers.
  • New vacancy → add a career post with title, content and a short excerpt. It appears in the accordion, the dropdown and other vacancies’ sidebars automatically. No code change.
  • Excluding the current vacancy from its sidebar → add 'post__not_in' => array(get_the_ID()) to the query at single-career.php:52.
  • Raising the vacancy cap → change all three limits listed above together.
  • Changing the application form → edit it in Contact Form 7 and keep a select named careers if the vacancy list is wanted; the name is the hook.
  • Changing the accordion markup → the JS depends on .js-expand and on the inline height: 0 on .block-careers-accordion__list-content. Rebuild with gulp after editing.
  • Verify: the careers page accordion opens and closes, a vacancy page’s sidebar and #apply anchor work, and a test application arrives with the right vacancy name.

None. No automated tests exist in this repository. Applications should be verified with a real test submission on staging.