'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'wp_kses_post',
'auth_callback' => 'skrift_ratgeber_meta_auth',
) );
register_post_meta( 'post', 'faq_ueberschrift', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'sanitize_text_field',
'auth_callback' => 'skrift_ratgeber_meta_auth',
) );
register_post_meta( 'post', 'cta_ziel', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'esc_url_raw',
'auth_callback' => 'skrift_ratgeber_meta_auth',
) );
register_post_meta( 'post', 'stand_datum', array(
'type' => 'string',
'single' => true,
'show_in_rest' => true,
'sanitize_callback' => 'skrift_ratgeber_datum',
'auth_callback' => 'skrift_ratgeber_meta_auth',
) );
// Feste Reihenfolge im Loop Grid, klein = weiter vorn. Schritte von 10 lassen Platz zum Einschieben.
register_post_meta( 'post', 'ratgeber_reihenfolge', array(
'type' => 'integer',
'single' => true,
'default' => 999,
'show_in_rest' => true,
'sanitize_callback' => 'absint',
'auth_callback' => 'skrift_ratgeber_meta_auth',
) );
register_post_meta( 'post', 'faq', array(
'type' => 'array',
'single' => true,
'default' => array(),
'show_in_rest' => array(
'schema' => array(
'type' => 'array',
'items' => array(
'type' => 'object',
'properties' => array(
'frage' => array( 'type' => 'string' ),
'antwort' => array( 'type' => 'string' ),
),
'additionalProperties' => false,
),
),
),
'auth_callback' => 'skrift_ratgeber_meta_auth',
) );
} );
function skrift_ratgeber_datum( $wert ) {
return preg_match( '/^\d{4}-\d{2}-\d{2}$/', (string) $wert ) ? $wert : '';
}
/* ------------------------------------------------------------------------
* 2. Eingabebox im Beitragseditor (Gutenberg und klassisch)
* --------------------------------------------------------------------- */
add_action( 'add_meta_boxes_post', function () {
add_meta_box(
'skrift_ratgeber',
'Ratgeber: Kurzantwort, CTA und FAQ',
'skrift_ratgeber_metabox',
'post',
'normal',
'high'
);
} );
function skrift_ratgeber_metabox( $post ) {
wp_nonce_field( 'skrift_ratgeber_speichern', 'skrift_ratgeber_nonce' );
$kurz = (string) get_post_meta( $post->ID, 'kurzantwort', true );
$cta = (string) get_post_meta( $post->ID, 'cta_ziel', true );
$stand = (string) get_post_meta( $post->ID, 'stand_datum', true );
$faq_u = (string) get_post_meta( $post->ID, 'faq_ueberschrift', true );
$rf = get_post_meta( $post->ID, 'ratgeber_reihenfolge', true );
$rf = ( '' === $rf ) ? 999 : (int) $rf;
$faq = get_post_meta( $post->ID, 'faq', true );
if ( ! is_array( $faq ) ) {
$faq = array();
}
?>
Zwei bis drei Saetze, Preise nur per [skrift_preis key="..."].
$e ) : ?>
Leere Fragen werden beim Speichern entfernt.
$frage,
'antwort' => wp_kses_post( $e['antwort'] ?? '' ),
);
}
update_post_meta( $post_id, 'faq', $faq );
} );
/* ------------------------------------------------------------------------
* 3. Ausgabe: gemeinsamer Renderer fuer Shortcode und Elementor-Widget
* --------------------------------------------------------------------- */
function skrift_faq_eintraege( $post_id = 0 ) {
$post_id = $post_id ? (int) $post_id : get_the_ID();
$faq = get_post_meta( $post_id, 'faq', true );
if ( ! is_array( $faq ) ) {
return array();
}
$raus = array();
foreach ( $faq as $e ) {
if ( ! empty( $e['frage'] ) ) {
$raus[] = $e;
}
}
return $raus;
}
function skrift_faq_basis_css() {
static $fertig = false;
if ( $fertig ) {
return '';
}
$fertig = true;
return '';
}
function skrift_faq_schema( $faq ) {
$fragen = array();
foreach ( $faq as $e ) {
$fragen[] = array(
'@type' => 'Question',
'name' => wp_strip_all_tags( $e['frage'] ),
'acceptedAnswer' => array(
'@type' => 'Answer',
'text' => wp_strip_all_tags( do_shortcode( $e['antwort'] ?? '' ) ),
),
);
}
return '';
}
function skrift_faq_html( $faq, $args = array() ) {
$args = wp_parse_args( $args, array(
'titel' => '',
'titel_tag' => 'h2',
'erste_offen' => false,
'schema' => true,
) );
if ( empty( $faq ) ) {
return '';
}
$tag = in_array( $args['titel_tag'], array( 'h2', 'h3', 'h4', 'div' ), true ) ? $args['titel_tag'] : 'h2';
$html = skrift_faq_basis_css() . '';
if ( '' !== $args['titel'] ) {
$html .= sprintf( '<%1$s class="skrift-faq__titel">%2$s%1$s>', $tag, esc_html( $args['titel'] ) );
}
foreach ( array_values( $faq ) as $i => $e ) {
$offen = ( $args['erste_offen'] && 0 === $i ) ? ' open' : '';
$html .= '
';
$html .= '' . esc_html( $e['frage'] ) . '
';
$html .= '' . wp_kses_post( wpautop( do_shortcode( $e['antwort'] ?? '' ) ) ) . '
';
$html .= ' ';
}
$html .= '
';
if ( $args['schema'] ) {
$html .= skrift_faq_schema( $faq );
}
return $html;
}
function skrift_kurzantwort_html( $post_id = 0 ) {
$post_id = $post_id ? (int) $post_id : get_the_ID();
$text = (string) get_post_meta( $post_id, 'kurzantwort', true );
if ( '' === trim( $text ) ) {
return '';
}
return '' . wp_kses_post( wpautop( do_shortcode( $text ) ) ) . '
';
}
function skrift_lesezeit_minuten( $post_id = 0, $wpm = 200 ) {
$post_id = $post_id ? (int) $post_id : get_the_ID();
$post = get_post( $post_id );
if ( ! $post ) {
return 1;
}
$text = do_shortcode( (string) $post->post_content ) . ' ' . (string) get_post_meta( $post_id, 'kurzantwort', true );
foreach ( skrift_faq_eintraege( $post_id ) as $e ) {
$text .= ' ' . $e['frage'] . ' ' . ( $e['antwort'] ?? '' );
}
$text = trim( wp_strip_all_tags( do_shortcode( $text ) ) );
$woerter = '' === $text ? 0 : count( preg_split( '/\s+/u', $text ) );
$wpm = max( 100, (int) $wpm );
return max( 1, (int) ceil( $woerter / $wpm ) );
}
function skrift_faq_ueberschrift( $post_id = 0, $standard = 'Häufige Fragen' ) {
$post_id = $post_id ? (int) $post_id : get_the_ID();
if ( empty( skrift_faq_eintraege( $post_id ) ) ) {
return '';
}
$u = trim( (string) get_post_meta( $post_id, 'faq_ueberschrift', true ) );
return '' !== $u ? $u : (string) $standard;
}
function skrift_stand_formatiert( $post_id = 0, $format = 'd.m.Y' ) {
$post_id = $post_id ? (int) $post_id : get_the_ID();
$s = (string) get_post_meta( $post_id, 'stand_datum', true );
if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $s ) ) {
$s = get_the_modified_date( 'Y-m-d', $post_id );
}
return date_i18n( $format ? $format : 'd.m.Y', strtotime( $s . ' 12:00:00' ) );
}
/* Shortcodes, z. B. fuer das Elementor-Shortcode-Widget oder klassische Themes */
add_shortcode( 'skrift_faq', function ( $atts ) {
$atts = shortcode_atts( array(
'titel' => '',
'erste_offen' => '0',
'schema' => '1',
'post_id' => 0,
), $atts, 'skrift_faq' );
return skrift_faq_html( skrift_faq_eintraege( $atts['post_id'] ), array(
'titel' => $atts['titel'],
'erste_offen' => '1' === (string) $atts['erste_offen'],
'schema' => '1' === (string) $atts['schema'],
) );
} );
/**
* Querverweis auf einen anderen Ratgeberartikel.
* [ratgeber_link slug="kaltakquise-per-brief"]Ankertext[/ratgeber_link]
* Veroeffentlichter Zielbeitrag: normaler Link auf den aktuellen Permalink.
* Noch nicht veroeffentlicht: nur der Ankertext, damit kein toter Link entsteht.
* Wer den Beitrag bearbeiten darf, sieht in der Vorschau einen gestrichelten
* Hinweis auf den noch fehlenden Zielartikel.
*/
add_shortcode( 'ratgeber_link', function ( $atts, $inhalt = '' ) {
$atts = shortcode_atts( array( 'slug' => '' ), $atts, 'ratgeber_link' );
$slug = sanitize_title( $atts['slug'] );
$text = '' !== trim( (string) $inhalt ) ? do_shortcode( $inhalt ) : $slug;
if ( '' === $slug ) {
return $text;
}
$ziel = get_posts( array(
'name' => $slug,
'post_type' => 'post',
'post_status' => array( 'publish', 'draft', 'pending', 'future', 'private' ),
'numberposts' => 1,
'suppress_filters' => true,
) );
if ( $ziel && 'publish' === $ziel[0]->post_status ) {
return '' . $text . '';
}
if ( is_user_logged_in() && current_user_can( 'edit_posts' ) ) {
$status = $ziel ? $ziel[0]->post_status : 'fehlt';
return '' . $text . '';
}
return $text;
} );
add_shortcode( 'skrift_kurzantwort', function ( $atts ) {
$atts = shortcode_atts( array( 'post_id' => 0 ), $atts, 'skrift_kurzantwort' );
return skrift_kurzantwort_html( $atts['post_id'] );
} );
/* ------------------------------------------------------------------------
* 4. Elementor-Widgets: Skrift FAQ und Skrift Kurzantwort
* Einmal ins Single-Post-Template (Theme Builder) setzen, dann zeigt
* jeder Beitrag automatisch seine eigenen Fragen.
* --------------------------------------------------------------------- */
function skrift_elementor_bearbeitungsmodus() {
if ( ! class_exists( '\Elementor\Plugin' ) ) {
return false;
}
$e = \Elementor\Plugin::$instance;
if ( isset( $e->editor ) && $e->editor->is_edit_mode() ) {
return true;
}
return isset( $e->preview ) && $e->preview->is_preview_mode();
}
add_action( 'elementor/widgets/register', function ( $widgets_manager ) {
if ( ! class_exists( '\Elementor\Widget_Base' ) ) {
return;
}
if ( ! class_exists( 'Skrift_FAQ_Widget' ) ) {
class Skrift_FAQ_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'skrift_faq';
}
public function get_title() {
return 'Skrift FAQ';
}
public function get_icon() {
return 'eicon-accordion';
}
public function get_categories() {
return array( 'general' );
}
public function get_keywords() {
return array( 'faq', 'fragen', 'skrift', 'akkordeon', 'umschalter', 'toggle' );
}
protected function register_controls() {
$C = '\Elementor\Controls_Manager';
$this->start_controls_section( 'inhalt', array( 'label' => 'Inhalt' ) );
$this->add_control( 'hinweis', array(
'type' => $C::RAW_HTML,
'raw' => 'Fragen und Antworten kommen aus dem Meta-Feld faq des jeweiligen Beitrags.',
) );
$this->add_control( 'erste_offen', array(
'label' => 'Erste Frage geoeffnet',
'type' => $C::SWITCHER,
'default' => '',
) );
$this->add_control( 'schema', array(
'label' => 'FAQ-Schema ausgeben',
'type' => $C::SWITCHER,
'default' => 'yes',
) );
$this->end_controls_section();
$this->start_controls_section( 'stil_frage', array( 'label' => 'Frage', 'tab' => $C::TAB_STYLE ) );
$this->add_group_control( \Elementor\Group_Control_Typography::get_type(), array(
'name' => 'frage_typo',
'selector' => '{{WRAPPER}} .skrift-faq__frage',
) );
$this->add_control( 'frage_farbe', array(
'label' => 'Farbe',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-faq__frage' => 'color: {{VALUE}};' ),
) );
$this->add_control( 'frage_farbe_offen', array(
'label' => 'Farbe geoeffnet',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-faq__eintrag[open] .skrift-faq__frage' => 'color: {{VALUE}};' ),
) );
$this->add_control( 'frage_hintergrund', array(
'label' => 'Hintergrund',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-faq__frage' => 'background-color: {{VALUE}};' ),
) );
$this->add_responsive_control( 'frage_innenabstand', array(
'label' => 'Innenabstand',
'type' => $C::DIMENSIONS,
'size_units' => array( 'px', 'em' ),
'selectors' => array( '{{WRAPPER}} .skrift-faq__frage' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ),
) );
$this->end_controls_section();
$this->start_controls_section( 'stil_antwort', array( 'label' => 'Antwort', 'tab' => $C::TAB_STYLE ) );
$this->add_group_control( \Elementor\Group_Control_Typography::get_type(), array(
'name' => 'antwort_typo',
'selector' => '{{WRAPPER}} .skrift-faq__antwort',
) );
$this->add_control( 'antwort_farbe', array(
'label' => 'Farbe',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-faq__antwort' => 'color: {{VALUE}};' ),
) );
$this->add_responsive_control( 'antwort_innenabstand', array(
'label' => 'Innenabstand',
'type' => $C::DIMENSIONS,
'size_units' => array( 'px', 'em' ),
'selectors' => array( '{{WRAPPER}} .skrift-faq__antwort' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ),
) );
$this->end_controls_section();
$this->start_controls_section( 'stil_eintrag', array( 'label' => 'Eintrag', 'tab' => $C::TAB_STYLE ) );
$this->add_group_control( \Elementor\Group_Control_Border::get_type(), array(
'name' => 'eintrag_rahmen',
'selector' => '{{WRAPPER}} .skrift-faq__eintrag',
) );
$this->add_control( 'eintrag_radius', array(
'label' => 'Eckenradius',
'type' => $C::DIMENSIONS,
'size_units' => array( 'px' ),
'selectors' => array( '{{WRAPPER}} .skrift-faq__eintrag' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; overflow: hidden;' ),
) );
$this->add_control( 'eintrag_hintergrund', array(
'label' => 'Hintergrund',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-faq__eintrag' => 'background-color: {{VALUE}};' ),
) );
$this->add_responsive_control( 'eintrag_abstand', array(
'label' => 'Abstand zwischen Eintraegen',
'type' => $C::SLIDER,
'size_units' => array( 'px', 'em' ),
'selectors' => array( '{{WRAPPER}} .skrift-faq__eintrag + .skrift-faq__eintrag' => 'margin-top: {{SIZE}}{{UNIT}};' ),
) );
$this->end_controls_section();
}
protected function render() {
$s = $this->get_settings_for_display();
$faq = skrift_faq_eintraege();
$bearbeiten = skrift_elementor_bearbeitungsmodus();
// Im Theme-Builder-Template gibt es keinen Beitrag mit FAQ,
// deshalb dort Platzhalter zum Gestalten.
if ( empty( $faq ) && $bearbeiten ) {
$faq = array(
array( 'frage' => 'Beispielfrage aus dem Feld faq', 'antwort' => 'Im Beitrag erscheinen hier die Antworten aus dem Meta-Feld faq.' ),
array( 'frage' => 'Zweite Beispielfrage', 'antwort' => 'Die Gestaltung legen Sie hier im Widget fest, sie gilt fuer alle Beitraege.' ),
array( 'frage' => 'Dritte Beispielfrage', 'antwort' => 'Beitraege ohne FAQ zeigen an dieser Stelle nichts an.' ),
);
}
echo skrift_faq_html( $faq, array( // phpcs:ignore WordPress.Security.EscapeOutput
'erste_offen' => 'yes' === ( $s['erste_offen'] ?? '' ),
'schema' => 'yes' === ( $s['schema'] ?? '' ) && ! $bearbeiten,
) );
}
}
}
if ( ! class_exists( 'Skrift_Kurzantwort_Widget' ) ) {
class Skrift_Kurzantwort_Widget extends \Elementor\Widget_Base {
public function get_name() {
return 'skrift_kurzantwort';
}
public function get_title() {
return 'Skrift Kurzantwort';
}
public function get_icon() {
return 'eicon-text';
}
public function get_categories() {
return array( 'general' );
}
public function get_keywords() {
return array( 'kurzantwort', 'skrift', 'zusammenfassung', 'box' );
}
protected function register_controls() {
$C = '\Elementor\Controls_Manager';
$this->start_controls_section( 'inhalt', array( 'label' => 'Inhalt' ) );
$this->add_control( 'hinweis', array(
'type' => $C::RAW_HTML,
'raw' => 'Der Text kommt aus dem Meta-Feld kurzantwort. Preis-Shortcodes darin werden aufgeloest.',
) );
$this->end_controls_section();
$this->start_controls_section( 'stil_box', array( 'label' => 'Box', 'tab' => $C::TAB_STYLE ) );
$this->add_group_control( \Elementor\Group_Control_Typography::get_type(), array(
'name' => 'box_typo',
'selector' => '{{WRAPPER}} .skrift-kurzantwort',
) );
$this->add_control( 'box_farbe', array(
'label' => 'Textfarbe',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-kurzantwort' => 'color: {{VALUE}};' ),
) );
$this->add_control( 'box_hintergrund', array(
'label' => 'Hintergrund',
'type' => $C::COLOR,
'selectors' => array( '{{WRAPPER}} .skrift-kurzantwort' => 'background-color: {{VALUE}};' ),
) );
$this->add_group_control( \Elementor\Group_Control_Border::get_type(), array(
'name' => 'box_rahmen',
'selector' => '{{WRAPPER}} .skrift-kurzantwort',
) );
$this->add_control( 'box_radius', array(
'label' => 'Eckenradius',
'type' => $C::DIMENSIONS,
'size_units' => array( 'px' ),
'selectors' => array( '{{WRAPPER}} .skrift-kurzantwort' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ),
) );
$this->add_responsive_control( 'box_innenabstand', array(
'label' => 'Innenabstand',
'type' => $C::DIMENSIONS,
'size_units' => array( 'px', 'em' ),
'selectors' => array( '{{WRAPPER}} .skrift-kurzantwort' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ),
) );
$this->end_controls_section();
}
protected function render() {
$html = skrift_kurzantwort_html();
if ( '' === $html && skrift_elementor_bearbeitungsmodus() ) {
$html = 'Platzhalter: Hier erscheint die Kurzantwort des jeweiligen Beitrags.
';
}
echo $html; // phpcs:ignore WordPress.Security.EscapeOutput
}
}
}
$widgets_manager->register( new Skrift_FAQ_Widget() );
$widgets_manager->register( new Skrift_Kurzantwort_Widget() );
} );
/* ------------------------------------------------------------------------
* 5. Elementor Dynamic Tags (Gruppe "Skrift")
* In jedem Text- oder Ueberschrift-Widget ueber das Symbol fuer dynamische
* Inhalte waehlbar. "Davor" und "Danach" stellt Elementor selbst bereit.
* --------------------------------------------------------------------- */
add_action( 'elementor/dynamic_tags/register', function ( $dynamic_tags ) {
if ( ! class_exists( '\Elementor\Core\DynamicTags\Tag' ) || ! method_exists( $dynamic_tags, 'register' ) ) {
return;
}
$dynamic_tags->register_group( 'skrift', array( 'title' => 'Skrift' ) );
if ( ! class_exists( 'Skrift_Tag_Lesezeit' ) ) {
class Skrift_Tag_Lesezeit extends \Elementor\Core\DynamicTags\Tag {
public function get_name() {
return 'skrift-lesezeit';
}
public function get_title() {
return 'Lesezeit';
}
public function get_group() {
return 'skrift';
}
public function get_categories() {
return array( \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY );
}
protected function register_controls() {
$this->add_control( 'wpm', array(
'label' => 'Woerter pro Minute',
'type' => \Elementor\Controls_Manager::NUMBER,
'default' => 200,
'min' => 100,
'max' => 400,
) );
$this->add_control( 'einheit', array(
'label' => 'Einheit',
'type' => \Elementor\Controls_Manager::TEXT,
'default' => ' Min.',
) );
}
public function render() {
$wpm = (int) $this->get_settings( 'wpm' );
$einheit = (string) $this->get_settings( 'einheit' );
echo esc_html( skrift_lesezeit_minuten( get_the_ID(), $wpm ? $wpm : 200 ) . $einheit );
}
}
}
if ( ! class_exists( 'Skrift_Tag_FAQ_Ueberschrift' ) ) {
class Skrift_Tag_FAQ_Ueberschrift extends \Elementor\Core\DynamicTags\Tag {
public function get_name() {
return 'skrift-faq-ueberschrift';
}
public function get_title() {
return 'FAQ-Ueberschrift';
}
public function get_group() {
return 'skrift';
}
public function get_categories() {
return array( \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY );
}
protected function register_controls() {
$this->add_control( 'standard', array(
'label' => 'Standardtext',
'type' => \Elementor\Controls_Manager::TEXT,
'default' => 'Häufige Fragen',
'description' => 'Gilt, wenn im Beitrag keine eigene FAQ-Ueberschrift gepflegt ist. Hat der Beitrag kein FAQ, bleibt die Ausgabe leer.',
) );
}
public function render() {
echo esc_html( skrift_faq_ueberschrift( get_the_ID(), (string) $this->get_settings( 'standard' ) ) );
}
}
}
if ( ! class_exists( 'Skrift_Tag_Stand' ) ) {
class Skrift_Tag_Stand extends \Elementor\Core\DynamicTags\Tag {
public function get_name() {
return 'skrift-stand';
}
public function get_title() {
return 'Stand-Datum';
}
public function get_group() {
return 'skrift';
}
public function get_categories() {
return array( \Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY );
}
protected function register_controls() {
$this->add_control( 'format', array(
'label' => 'Datumsformat',
'type' => \Elementor\Controls_Manager::TEXT,
'default' => 'd.m.Y',
'description' => 'PHP-Datumsformat, z. B. d.m.Y oder j. F Y',
) );
}
public function render() {
echo esc_html( skrift_stand_formatiert( get_the_ID(), (string) $this->get_settings( 'format' ) ) );
}
}
}
$dynamic_tags->register( new Skrift_Tag_Lesezeit() );
$dynamic_tags->register( new Skrift_Tag_FAQ_Ueberschrift() );
$dynamic_tags->register( new Skrift_Tag_Stand() );
} );
/* ------------------------------------------------------------------------
* Loop Grid: Sortierung ueber ratgeber_reihenfolge
* In Elementor im Loop Grid unter Abfrage > Abfrage-ID "skrift_ratgeber" eintragen.
* Kategorie-Filter aus dem Widget (Einschliessen nach Begriff) bleibt erhalten.
* Beitraege ohne Wert landen hinten, bei gleichem Wert entscheidet das Datum.
* --------------------------------------------------------------------- */
add_action( 'elementor/query/skrift_ratgeber', function ( $query ) {
$meta_query = (array) $query->get( 'meta_query' );
$meta_query[] = array(
'relation' => 'OR',
'rf_vorhanden' => array( 'key' => 'ratgeber_reihenfolge', 'type' => 'NUMERIC', 'compare' => 'EXISTS' ),
'rf_fehlt' => array( 'key' => 'ratgeber_reihenfolge', 'compare' => 'NOT EXISTS' ),
);
$query->set( 'meta_query', $meta_query );
$query->set( 'orderby', array( 'rf_vorhanden' => 'ASC', 'date' => 'DESC' ) );
} );
// Beitraege ohne Wert bekommen beim Speichern 999, damit sie in der Sortierung hinten stehen.
add_action( 'save_post_post', function ( $post_id ) {
if ( wp_is_post_revision( $post_id ) ) {
return;
}
if ( ! metadata_exists( 'post', $post_id, 'ratgeber_reihenfolge' ) ) {
update_post_meta( $post_id, 'ratgeber_reihenfolge', 999 );
}
}, 20 );