JPKCom ACF Jobs — Guide & Tips

Manage job postings with JPKCom ACF Jobs — installation, custom post types, shortcodes, template overrides and practical tips for ACF Pro-based job listings.

JPKCom ACF Jobs is a job listing and application management system built on Advanced Custom Fields Pro. It ships three custom post types (Jobs, Locations, Companies), JobPosting Schema.org data, Bootstrap 5 templates and shortcodes — aimed at career pages, HR teams and job boards.

Guide

Requirements

Required:

Optional: WPML (opens in a new tab) for multilingual job postings.

Installation

  1. Download the latest release ZIP from the GitHub Releases page (opens in a new tab).
  2. In your admin panel: Plugins → Add New → Upload Plugin, choose the ZIP, Install Now, then Activate.
  3. Make sure ACF Pro and ACF Quick Edit Fields are active.

Alternatively upload via FTP to /wp-content/plugins/, or clone it for development:

cd /path/to/wordpress/wp-content/plugins/
git clone https://github.com/JPKCom/jpkcom-acf-jobs.git

On multisite the plugin is network-compatible (Network Admin → Plugins → Network Activate).

Getting started

After activation you'll see Jobs, Locations and Companies menu items. Recommended flow:

  1. Create a location under Locations → Add New.
  2. Create a company under Companies → Add New.
  3. Create a job under Jobs → Add New, fill the ACF fields (job type, location, company, salary) and assign job attributes via the taxonomy on the right (e.g. benefits, requirements).
  4. Publish the job — it appears in the archive at /jobs/ and is marked up with JobPosting Schema.org data.

Displaying jobs

Via shortcode (all attributes optional):

[jpkcom_acf_jobs_list type="FULL_TIME" company="6,8" location="1,3,7" limit="10" sort="DSC"]

company and location expect post IDs (visible in the admin URL, post=123). Attributes (benefits/requirements) can be rendered separately:

[jpkcom_acf_jobs_attributes id="3,7,21"]

Alternatively visit the archive at /jobs/ directly, or build custom output with WP_Query and post_type => 'job'.

Jobs as data: the Abilities API

Since version 1.4.0 the plugin registers three read-only abilities. The Abilities API is a WordPress core registry of machine-readable capabilities — AI assistants, MCP clients and REST automation can use it to query your job listings as structured data instead of scraping the page:

Ability What it answers
jpkcom-acf-jobs/list-filters which job types, companies, locations and job attributes exist on this site
jpkcom-acf-jobs/query-jobs a filtered, paginated list of jobs
jpkcom-acf-jobs/get-job one job in full

The point of the pair: list-filters takes the guesswork out of query-jobs — a caller looks up the real values first, then filters with them. The abilities live under /wp-json/wp-abilities/v1/; because they only read, they answer on GET.

Who sees what:

  • A logged-in user with the read capability is required — that includes subscribers. Anonymous requests are rejected.
  • Only published jobs come back, under the same visibility rule your archive and [jpkcom_acf_jobs_list] use — the same function, not a second copy of it. The abilities narrow it further: password-protected jobs are not served at all, even though the archive shows them.
  • Detail fields — salary, postal address, application details, the full job text — are returned only for jobs whose detail page a visitor could actually open. A job that redirects to an external application URL and an expired job have no public detail page, so those fields are withheld and the reason is stated in the response. A password-protected job is a different case: it is not trimmed but withheld entirely — query-jobs omits it, list-filters does not count it, and get-job answers with the same message and the same 404 it gives for an ID that does not exist. That sameness is deliberate: otherwise the abilities could be used to work out which post IDs the site holds.
  • The search covers titles only, because this plugin stores job text in ACF fields. The ability says so in its description and points at the filters that reach further.
  • Note that WordPress lists the abilities themselves — names, descriptions, parameters — to any logged-in user. That is core behaviour, not a setting of this plugin.

To switch the whole thing off, add this to wp-config.php:

define( 'JPKCOM_ACFJOBS_ABILITIES', false );

Or keep the abilities and raise the capability they require:

add_filter( 'jpkcom_acf_jobs_ability_capability', static function ( $capability ) {
	return 'edit_posts';
} );

Beyond that, jpkcom_acf_jobs_ability_meta controls how the abilities are exposed — REST route, MCP visibility, annotations — and jpkcom_acf_jobs_ability_query_args narrows the query behind query-jobs — only meta_query and tax_query clauses are taken from what it returns.

Tips & Tricks

  • Disable/redirect the job archive: Under Jobs → Options you can disable the /jobs/ archive and optionally redirect it to a custom URL (e.g. /careers/) via HTTP 307. Individual job pages stay accessible — handy if you prefer to show jobs via shortcodes on your own pages.
  • Override templates (priority order):
    1. Child theme (recommended): copy templates from plugins/jpkcom-acf-jobs/templates/ to your-child-theme/jpkcom-acf-jobs/.
    2. Parent theme: copy to your-theme/jpkcom-acf-jobs/.
    3. MU-plugin: copy to mu-plugins/jpkcom-acf-jobs-overrides/templates/ for site-wide customization.
  • Extend paths programmatically: The filters jpkcom_acf_jobs_template_paths and jpkcom_acfjobs_file_paths let you prepend your own directories; jpkcom_acf_jobs_final_template allows overriding the final template dynamically.
  • Render ACF fields with Bootstrap 5 markup: jpkcom_render_acf_fields() outputs all ACF fields of a post; fetch template parts with jpkcom_acf_jobs_get_template_part( 'partials/job/company' ).
  • Schema.org with no configuration: JobPosting JSON-LD output is automatic and usable by Google for Jobs — nothing to configure.
  • Expiry follows the site timezone: Expired listings drop out of the archive, the shortcode lists and the single view at local midnight. Up to version 1.3.6 the comparison ran against the UTC date — WordPress sets the PHP timezone to UTC, so expired listings stayed visible for the length of the site's UTC offset (1–2 hours past midnight for Europe/Berlin). Since 1.3.7 the check uses current_time().
  • Behaviour change for ability callers (1.5.0): Until then, get-job accepted parameters it does not know — a typo, or a filter that only query-jobs has, was silently ignored and the request answered normally. The other two abilities had always refused the same input with an error. Since 1.5.0 get-job does too: a call that previously got an answer now gets an error naming the parameter it rejected and the ones it accepts. If you built your own automation against this ability, check it after the update.
  • Multilingual with WPML: Via wpml-config.xml, jobs, locations, companies and taxonomies are translatable; fields carry appropriate translation strategies (translate/copy/copy-once).
  • Interface translations: Seven languages ship with the plugin — German in informal and formal address, Spanish, French, Hungarian, Italian and Polish. Up to 1.5.0 the translation catalogue had not been regenerated since October 2025 and covered 64 of what is now just over 200 texts; since 1.5.1 it covers the whole plugin, and a build step fails as soon as it falls behind again. Newly listed texts are not translated everywhere yet and appear in English until they are. Since 1.5.4 the updater's four security messages exist in all seven languages — the messages you see when an update is refused because its checksum does not match or cannot be checked at all.
  • Updates & security: The plugin updates securely via GitHub with SHA256 checksum verification; update notices appear under Dashboard → Updates and on the Plugins page.

Further reading