feat: register custom Elementor dynamic tags for job offer fields

Adds a "Stellenangebot" group to Elementor's dynamic tags dropdown with
tags for Standort, Art, Bewerbungsfrist, Kontakt-E-Mail (text), and
Logo (image). This removes the dependency on Elementor Pro's ACF module
for displaying job offer fields in templates and loop items.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-04 12:46:44 +09:00
parent 0bef634eb8
commit f0de02ca94
7 changed files with 286 additions and 0 deletions

View File

@@ -45,6 +45,7 @@ require_once DDHH_JM_PLUGIN_DIR . 'includes/class-template.php';
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-admin-ui.php'; require_once DDHH_JM_PLUGIN_DIR . 'includes/class-admin-ui.php';
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-user-preferences.php'; require_once DDHH_JM_PLUGIN_DIR . 'includes/class-user-preferences.php';
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-scheduler.php'; require_once DDHH_JM_PLUGIN_DIR . 'includes/class-scheduler.php';
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-elementor-tags.php';
require_once DDHH_JM_PLUGIN_DIR . 'includes/class-ddhh-job-manager.php'; require_once DDHH_JM_PLUGIN_DIR . 'includes/class-ddhh-job-manager.php';
// Register activation and deactivation hooks (must be at top level). // Register activation and deactivation hooks (must be at top level).
@@ -58,3 +59,11 @@ function ddhh_jm_init() {
DDHH_JM_Job_Manager::get_instance(); DDHH_JM_Job_Manager::get_instance();
} }
add_action( 'plugins_loaded', 'ddhh_jm_init', 10 ); add_action( 'plugins_loaded', 'ddhh_jm_init', 10 );
/**
* Initialize Elementor dynamic tags when Elementor is loaded.
*/
function ddhh_jm_elementor_init() {
DDHH_JM_Elementor_Tags::init();
}
add_action( 'elementor/init', 'ddhh_jm_elementor_init' );

View File

@@ -0,0 +1,58 @@
<?php
/**
* Elementor Dynamic Tags integration.
*
* Registers custom dynamic tags for job offer fields so they appear
* in the Elementor editor's dynamic tags dropdown under a
* "Stellenangebot" group.
*
* @package DDHH_Job_Manager
*/
defined( 'ABSPATH' ) || exit;
/**
* Class DDHH_JM_Elementor_Tags
*/
class DDHH_JM_Elementor_Tags {
/**
* Group slug used for all job offer tags.
*/
const GROUP_SLUG = 'ddhh-job-offer';
/**
* Initialize hooks.
*/
public static function init() {
add_action( 'elementor/dynamic_tags/register', array( __CLASS__, 'register_tags' ) );
}
/**
* Register the dynamic tag group and individual tags.
*
* @param \Elementor\Core\DynamicTags\Manager $manager Elementor dynamic tags manager.
*/
public static function register_tags( $manager ) {
$manager->register_group(
self::GROUP_SLUG,
array(
'title' => 'Stellenangebot',
)
);
$tag_dir = DDHH_JM_PLUGIN_DIR . 'includes/elementor-tags/';
require_once $tag_dir . 'class-tag-job-location.php';
require_once $tag_dir . 'class-tag-job-type.php';
require_once $tag_dir . 'class-tag-job-deadline.php';
require_once $tag_dir . 'class-tag-job-contact-email.php';
require_once $tag_dir . 'class-tag-job-logo.php';
$manager->register( new DDHH_JM_Tag_Job_Location() );
$manager->register( new DDHH_JM_Tag_Job_Type() );
$manager->register( new DDHH_JM_Tag_Job_Deadline() );
$manager->register( new DDHH_JM_Tag_Job_Contact_Email() );
$manager->register( new DDHH_JM_Tag_Job_Logo() );
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* Elementor dynamic tag: Kontakt-E-Mail (job_contact_email).
*
* Registered in both TEXT and URL categories so it can be used
* as link href (mailto:) or plain text display.
*
* @package DDHH_Job_Manager
*/
defined( 'ABSPATH' ) || exit;
class DDHH_JM_Tag_Job_Contact_Email extends \Elementor\Core\DynamicTags\Tag {
public function get_name(): string {
return 'ddhh-job-contact-email';
}
public function get_title(): string {
return 'Kontakt-E-Mail';
}
public function get_group(): array {
return array( DDHH_JM_Elementor_Tags::GROUP_SLUG );
}
public function get_categories(): array {
return array(
\Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY,
\Elementor\Modules\DynamicTags\Module::URL_CATEGORY,
);
}
public function render(): void {
$value = get_post_meta( get_the_ID(), 'job_contact_email', true );
echo esc_html( $value );
}
}

View File

@@ -0,0 +1,44 @@
<?php
/**
* Elementor dynamic tag: Bewerbungsfrist (job_deadline).
*
* Formats the stored Y-m-d date as DD.MM.YYYY for display.
*
* @package DDHH_Job_Manager
*/
defined( 'ABSPATH' ) || exit;
class DDHH_JM_Tag_Job_Deadline extends \Elementor\Core\DynamicTags\Tag {
public function get_name(): string {
return 'ddhh-job-deadline';
}
public function get_title(): string {
return 'Bewerbungsfrist';
}
public function get_group(): array {
return array( DDHH_JM_Elementor_Tags::GROUP_SLUG );
}
public function get_categories(): array {
return array( \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY );
}
public function render(): void {
$raw = get_post_meta( get_the_ID(), 'job_deadline', true );
if ( empty( $raw ) ) {
return;
}
$timestamp = strtotime( $raw );
if ( false === $timestamp ) {
echo esc_html( $raw );
return;
}
echo esc_html( date_i18n( 'd.m.Y', $timestamp ) );
}
}

View File

@@ -0,0 +1,32 @@
<?php
/**
* Elementor dynamic tag: Standort (job_location).
*
* @package DDHH_Job_Manager
*/
defined( 'ABSPATH' ) || exit;
class DDHH_JM_Tag_Job_Location extends \Elementor\Core\DynamicTags\Tag {
public function get_name(): string {
return 'ddhh-job-location';
}
public function get_title(): string {
return 'Standort';
}
public function get_group(): array {
return array( DDHH_JM_Elementor_Tags::GROUP_SLUG );
}
public function get_categories(): array {
return array( \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY );
}
public function render(): void {
$value = get_post_meta( get_the_ID(), 'job_location', true );
echo wp_kses_post( $value );
}
}

View File

@@ -0,0 +1,64 @@
<?php
/**
* Elementor dynamic tag: Logo (job_logo).
*
* Extends Data_Tag to return image data (id + url) for use in
* Image widgets and other image-accepting controls.
*
* @package DDHH_Job_Manager
*/
defined( 'ABSPATH' ) || exit;
class DDHH_JM_Tag_Job_Logo extends \Elementor\Core\DynamicTags\Data_Tag {
public function get_name(): string {
return 'ddhh-job-logo';
}
public function get_title(): string {
return 'Logo';
}
public function get_group(): array {
return array( DDHH_JM_Elementor_Tags::GROUP_SLUG );
}
public function get_categories(): array {
return array( \Elementor\Modules\DynamicTags\Module::IMAGE_CATEGORY );
}
protected function register_controls(): void {
$this->add_control(
'fallback',
array(
'label' => 'Fallback',
'type' => \Elementor\Controls_Manager::MEDIA,
)
);
}
public function get_value( array $options = array() ): array {
$image_id = get_post_meta( get_the_ID(), 'job_logo', true );
if ( $image_id ) {
$url = wp_get_attachment_image_url( $image_id, 'full' );
if ( $url ) {
return array(
'id' => (int) $image_id,
'url' => $url,
);
}
}
$fallback = $this->get_settings( 'fallback' );
if ( ! empty( $fallback['id'] ) ) {
return $fallback;
}
return array(
'id' => 0,
'url' => '',
);
}
}

View File

@@ -0,0 +1,41 @@
<?php
/**
* Elementor dynamic tag: Art (job_type).
*
* Maps raw select values to German display labels.
*
* @package DDHH_Job_Manager
*/
defined( 'ABSPATH' ) || exit;
class DDHH_JM_Tag_Job_Type extends \Elementor\Core\DynamicTags\Tag {
private const LABELS = array(
'vollzeit' => 'Vollzeit',
'teilzeit' => 'Teilzeit',
'ehrenamt' => 'Ehrenamt',
);
public function get_name(): string {
return 'ddhh-job-type';
}
public function get_title(): string {
return 'Art';
}
public function get_group(): array {
return array( DDHH_JM_Elementor_Tags::GROUP_SLUG );
}
public function get_categories(): array {
return array( \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY );
}
public function render(): void {
$raw = get_post_meta( get_the_ID(), 'job_type', true );
$label = self::LABELS[ $raw ] ?? $raw;
echo esc_html( $label );
}
}