JobPosting Structured Data for Job Listings
Adds JobPosting JSON-LD (salary, employment type, location or remote, closing date and employer) to single job listings, so they can appear in Google for Jobs.
Opens WPIDE on
Code
add_action( 'wp_head', function () {
if ( ! is_singular( 'job' ) ) {
return;
}
$post = get_queried_object();
$get = function ( $key ) use ( $post ) {
return trim( (string) get_post_meta( $post->ID, '_job_' . $key, true ) );
};
$data = array(
'@context' => 'https://schema.org',
'@type' => 'JobPosting',
'title' => wp_strip_all_tags( get_the_title( $post ) ),
'description' => wp_kses_post( wpautop( $post->post_content ) ),
'datePosted' => get_the_date( DATE_W3C, $post ),
'employmentType' => $get( 'type' ),
'directApply' => false,
'hiringOrganization' => array(
'@type' => 'Organization',
'name' => get_bloginfo( 'name' ),
'sameAs' => home_url( '/' ),
'logo' => has_custom_logo() ? wp_get_attachment_image_url( (int) get_theme_mod( 'custom_logo' ), 'full' ) : '',
),
);
if ( $get( 'valid_through' ) ) {
$data['validThrough'] = $get( 'valid_through' ) . 'T23:59:59' . wp_date( 'P' );
}
if ( $get( 'city' ) || $get( 'country' ) ) {
$data['jobLocation'] = array(
'@type' => 'Place',
'address' => array_filter( array( '@type' => 'PostalAddress', 'addressLocality' => $get( 'city' ), 'addressCountry' => $get( 'country' ) ) ),
);
}
if ( $get( 'remote' ) ) {
$data['jobLocationType'] = 'TELECOMMUTE';
if ( $get( 'country' ) ) {
$data['applicantLocationRequirements'] = array( '@type' => 'Country', 'name' => $get( 'country' ) );
}
}
if ( is_numeric( $get( 'salary_min' ) ) && $get( 'currency' ) ) {
$value = array( '@type' => 'QuantitativeValue', 'unitText' => $get( 'salary_unit' ) ? $get( 'salary_unit' ) : 'YEAR' );
if ( is_numeric( $get( 'salary_max' ) ) && (float) $get( 'salary_max' ) > (float) $get( 'salary_min' ) ) {
$value['minValue'] = (float) $get( 'salary_min' );
$value['maxValue'] = (float) $get( 'salary_max' );
} else {
$value['value'] = (float) $get( 'salary_min' );
}
$data['baseSalary'] = array( '@type' => 'MonetaryAmount', 'currency' => strtoupper( $get( 'currency' ) ), 'value' => $value );
}
$data['hiringOrganization'] = array_filter( $data['hiringOrganization'] );
echo '<script type="application/ld+json">' . wp_json_encode( array_filter( $data, function ( $v ) { return '' !== $v && null !== $v; } ), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG ) . "</script>\n";
} );
Notes
Reads the Job Details meta box fields. Remove or expire listings once filled; Google penalises stale job markup.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.