Plugin 1.3 Dynamic Tags, faq_ueberschrift, quadratische Bilder, Bausteine aus dem Text

This commit is contained in:
2026-09-22 12:00:31 +02:00
parent f713b3b9dd
commit 54bd0b02a9
11 changed files with 351 additions and 157 deletions

View File

@@ -162,3 +162,15 @@
padding: 16px 18px;
}
}
/* ---------- Uebersicht: quadratisches Beitragsbild als 16:9-Kachel ----------
Gehoert NICHT ins Einzelbeitrag-Template, sondern ins Loop-Item bzw. die
Archivseite. Im Bild-Widget unter Erweitert die CSS-Klasse
"skrift-kachelbild" setzen. Das Motiv sitzt mittig, der Zuschnitt nimmt
oben und unten nur Hintergrund weg. */
.skrift-kachelbild img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
object-position: center;
}

View File

@@ -1,8 +1,8 @@
<?php
/**
* Plugin Name: Skrift Ratgeber Felder
* Description: Meta-Felder fuer Ratgeberartikel (kurzantwort, faq, cta_ziel, stand_datum) mit Eingabebox im Editor, Shortcodes und Elementor-Widgets, die das FAQ-Feld automatisch als Umschalter ausgeben.
* Version: 1.2.0
* Description: Meta-Felder fuer Ratgeberartikel (kurzantwort, faq, faq_ueberschrift, cta_ziel, stand_datum) mit Eingabebox im Editor, Shortcodes, Elementor-Widgets fuer FAQ und Kurzantwort sowie Dynamic Tags fuer Lesezeit, FAQ-Ueberschrift und Stand.
* Version: 1.3.0
* Author: Lucas Orth
*
* Ablage: wp-content/mu-plugins/skrift-ratgeber-felder.php
@@ -30,6 +30,14 @@ add_action( 'init', function () {
'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,
@@ -92,6 +100,7 @@ function skrift_ratgeber_metabox( $post ) {
$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 );
$faq = get_post_meta( $post->ID, 'faq', true );
if ( ! is_array( $faq ) ) {
$faq = array();
@@ -125,6 +134,11 @@ function skrift_ratgeber_metabox( $post ) {
</p>
</div>
<p>
<label for="skrift_faq_ueberschrift">FAQ-Ueberschrift</label>
<input type="text" id="skrift_faq_ueberschrift" name="skrift_faq_ueberschrift" class="widefat" value="<?php echo esc_attr( $faq_u ); ?>" placeholder="Leer lassen fuer den Standardtext aus Elementor">
</p>
<label>FAQ</label>
<div id="skrift-faq-liste">
<?php foreach ( $faq as $i => $e ) : ?>
@@ -183,6 +197,7 @@ add_action( 'save_post_post', function ( $post_id ) {
}
update_post_meta( $post_id, 'kurzantwort', wp_kses_post( wp_unslash( $_POST['skrift_kurzantwort'] ?? '' ) ) );
update_post_meta( $post_id, 'faq_ueberschrift', sanitize_text_field( wp_unslash( $_POST['skrift_faq_ueberschrift'] ?? '' ) ) );
update_post_meta( $post_id, 'cta_ziel', esc_url_raw( wp_unslash( $_POST['skrift_cta_ziel'] ?? '' ) ) );
update_post_meta( $post_id, 'stand_datum', skrift_ratgeber_datum( sanitize_text_field( wp_unslash( $_POST['skrift_stand_datum'] ?? '' ) ) ) );
@@ -297,6 +312,40 @@ function skrift_kurzantwort_html( $post_id = 0 ) {
return '<div class="skrift-kurzantwort">' . wp_kses_post( wpautop( do_shortcode( $text ) ) ) . '</div>';
}
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 ) {
@@ -560,3 +609,114 @@ add_action( 'elementor/widgets/register', function ( $widgets_manager ) {
$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() );
} );