All work

Case 05 / 10

Recruitment site for a Belgian federal public service

A Belgian federal public service needed one recruitment site for students, starters and professionals, in Dutch and French. Through DLVX, working for a Belgian digital agency, I built it as a custom WordPress theme that HR runs without a developer. The agency reports 2,000+ applications in the first six months and 40,000+ visitors a month.

Role
WordPress Developer
Client
Belgian federal public service, via a Belgian agency
Year
2024–2025
Stack
WordPress, ACF Pro, WPML, Bootstrap, SCSS
Home page: a full-width photo hero with the headline, and a job title and location search bar below it.

2,000+

applications in the first six months

40,000+

visitors a month

2,787

Belgian places, searchable by name or postcode

NL / FR

every page, term and field in both languages

Applications and visitors as reported by the agency.

Key contributions

  1. 01

    Vacancy search built for public hiring

    Search by job title, location, diploma, department and contract type. Vacancies with a fixed application window hide themselves outside it, and a filterable RSS feed passes them on to other systems.

  2. 02

    2,800 Belgian locations, in two languages

    Imported every Belgian postcode with its coordinates into a location taxonomy, mirrored terms and fields into French with WPML, and cached location search so it stays fast.

  3. 03

    A content model HR can run

    Custom post types, 23 ACF field groups and 36 reusable page sections cover vacancies, departments, job domains, events, staff stories and FAQs. Event filters show the number of results live, before you apply them.

Screens

Vacancy archive: search fields for job title and place, dropdowns for diploma, department and contract type, a result count and vacancy cards. (opens in a new tab)
Vacancy search
Vacancy page: the job title and contract type, a collapsible job description, and a sidebar with location, required diploma, field of study and department. (opens in a new tab)
Vacancy page
Event filter modal with checkboxes for profile, location, event type and region. One profile is ticked and the button already shows 32 results. (opens in a new tab)
Event filter
Mobile home page with the headline and stacked search fields.
Mobile vacancy search with full-width fields and filter dropdowns.

Screens from the live site, in Dutch.

Anonymised: logos, brand names, photos, departments and contact details are removed or blurred, and the brand colours are greyed out.

The backend

Every page is built from one flexible-content field with 36 reusable section layouts. Editors stack sections in any order on a page, and set shared sections once for each type of detail page: vacancies, events, job domains, FAQs and news. Each layout maps to one PHP partial, so adding a new section means one layout and one file, and nothing else in the theme changes.

WordPress page editor with a Flexible sections box listing eight collapsed sections in order: a hero, centred content, numbers, a quote, a tabbed grid, a two- or three-column CTA, a CTA grid and a full-width CTA. (opens in a new tab)
Page sections
An expanded Numbers section with a title, a subtitle, a repeater of number and label rows, and a button link. (opens in a new tab)
Editing a section
The add-section menu open next to the page sections, listing the available layouts: several hero variants, about, content beside image or video, steps, and story, FAQ, news and vacancy sliders. (opens in a new tab)
Section picker
Field group list with 23 groups, each showing its location (options pages, departments, pages, posts) and a Local JSON status of Saved. (opens in a new tab)
Field groups

The theme running in a local Docker copy with only one plugin, Secure Custom Fields (the free fork of ACF), and demo content.

Field groups, post types, taxonomies and options pages all load from JSON in the theme, so the content model lives in version control.

One layout, one file

// page.php: render the sections in the order the editor set
foreach (get_field('flexible_sections') ?: [] as $section) {
    echo getFlexibleSections($section['acf_fc_layout'], $section);
}

// functions.php: each layout name is a partial
function getFlexibleSections($layout, $flexible_section = null) {
    ob_start();
    require get_template_directory() . "/template-parts/flexible/$layout.php";
    return ob_get_clean();
}

Simplified from the theme. The same loop runs on pages, vacancies, events, job domains, stories and FAQs.

The section library

Heroes 6
  • Hero
  • Blue-light hero
  • Home hero
  • About hero with quote
  • Benefits hero
  • FAQ hero with search
Content 9
  • About us with links
  • Content beside image or video
  • Image beside content
  • Centred content
  • Free content
  • Tabbed grid
  • Steps with tabs
  • Numbers
  • Embed code
Quotes & stories 3
  • Quote with image
  • Quote with text
  • Latest story
Sliders 5
  • Story slider
  • FAQ slider
  • Latest FAQ slider
  • News slider
  • Vacancy slider
Calls to action 3
  • Two- or three-column CTA
  • CTA grid
  • Full-width CTA
Archives & feeds 10
  • Departments
  • Job domains
  • Events
  • Stories
  • Benefits
  • FAQ archive
  • How to start
  • General updates
  • Related questions
  • Related news
Next case Trilingual webshop for a premium beauty brand