[\d]+)'])) { unset($endpoints['/wp/v2/users/(?P[\d]+)']); } return $endpoints; }); //LIMIT LOGIN ATTEMPTS function limit_login_attempts() { $max_login_attempts = 3; // Maximale Versuche $lockout_time = 15 * MINUTE_IN_SECONDS; // Sperrzeit in Minuten $login_attempts = get_transient('failed_login_' . $_SERVER['REMOTE_ADDR']); if ($login_attempts >= $max_login_attempts) { wp_die('Zu viele fehlgeschlagene Versuche. Bitte versuche es später erneut.'); } } function increase_failed_login_attempts() { $max_login_attempts = 3; // Maximale Versuche $lockout_time = 15 * MINUTE_IN_SECONDS; // Sperrzeit in Minuten $login_attempts = get_transient('failed_login_' . $_SERVER['REMOTE_ADDR']); if (!$login_attempts) { $login_attempts = 0; } set_transient('failed_login_' . $_SERVER['REMOTE_ADDR'], $login_attempts + 1, $lockout_time); } add_action('wp_login_failed', 'increase_failed_login_attempts'); add_action('init', 'limit_login_attempts'); //CSS AND JS function theme_assets() { //CSS wp_enqueue_style('main-style', get_stylesheet_uri()); wp_enqueue_style('theme-style', get_template_directory_uri() . '/assets/css/blocks.css', false, filemtime(get_stylesheet_directory() . '/assets/css/blocks.css'), 'all'); wp_enqueue_style('responsive-style', get_template_directory_uri() . '/assets/css/responsive.css', false, filemtime(get_stylesheet_directory() . '/assets/css/responsive.css'), 'all'); //JS wp_enqueue_script('default-script', get_template_directory_uri() . '/assets/js/default.js', [], filemtime(get_stylesheet_directory() . '/assets/js/default.js'), ['strategy' => 'defer', 'in_footer' => true]); } add_action('wp_enqueue_scripts', 'theme_assets'); //ADD SVG SUPPORT add_action('upload_mimes', 'add_file_types_to_uploads'); function add_file_types_to_uploads($file_types){ $new_filetypes = array(); $new_filetypes['svg'] = 'image/svg+xml'; $file_types = array_merge($file_types, $new_filetypes ); return $file_types; } //GUTENBERG function ghub_child_setup() { add_theme_support('editor-styles'); add_editor_style('assets/css/blocks.css'); add_editor_style('gutenberg/editor.css'); } add_action('after_setup_theme', 'ghub_child_setup'); function custom_gutenberg_scripts() { wp_enqueue_script('block-styles-script', get_template_directory_uri() . '/gutenberg/block.js', array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ), filemtime(get_stylesheet_directory() . '/gutenberg/block.js')); } add_action( 'enqueue_block_editor_assets', 'custom_gutenberg_scripts' ); //LAZY LOADING add_filter( 'the_content', 'force_lazy_loading_on_images' ); function force_lazy_loading_on_images( $content ) { // Sucht nach img-Tags, die noch kein loading-Attribut haben return preg_replace_callback( '/]*\bloading\s*=)[^>]+>/i', function ( $matches ) { return str_replace( ' Tag innerhalb des Button-Contents // Das sorgt dafür, dass onclick/title etc. direkt am Link landen $block_content = preg_replace( '/]*)>/i', '', $block_content, 1 ); } else { // 3. Standardlogik für alle anderen Blöcke (ins erste Tag) $block_content = preg_replace( '/<([a-z0-9\-]+)([^>]*)>/i', '<$1$2 ' . $attr_string . '>', $block_content, 1 ); } return $block_content; } add_filter( 'render_block', 'add_attribute_to_blocks', 10, 2 ); //REGISTER THEME BLOCKS function register_theme_blocks() { register_block_type( __DIR__ . '/blocks/openbox' ); //register_block_type( __DIR__ . '/blocks/togglebox' ); register_block_type( __DIR__ . '/blocks/togglebox', array( 'editor_script' => 'togglebox-block', 'render_callback' => function( $attributes, $content ) { // Regex: erste Headline (h1-h6) $first_heading = ''; if (preg_match('/<(h[1-6])[^>]*>(.*?)<\/\1>/is', $content, $matches)) { $first_heading = $matches[2]; } // ID aus Heading-Text generieren $togglebox_id = 'togglebox-content-' . sanitize_title($first_heading); // Ersten Heading-Block in Button wrappen $content = preg_replace_callback( '/<(h[1-6])([^>]*)>(.*?)<\/\1>/is', function($matches) use ($togglebox_id) { return sprintf( '<%1$s%2$s>', $matches[1], $matches[2], $togglebox_id, $matches[3] ); }, $content, 1 ); // .togglebox-content div bekommt die ID $content = preg_replace( '/]*)class="([^"]*togglebox-content[^"]*)"([^>]*)>/i', '', $content, 1 ); return $content; } ) ); } add_action( 'init', 'register_theme_blocks' ); //WEBSITE TITLE add_filter('pre_get_document_title', function($title) { $site_name = get_bloginfo('name'); // Startseite if (is_front_page() || is_home()) { return $site_name; } // Für Seiten, Beiträge, Archive $page_title = get_the_title(); // Seitentitel if (!$page_title) { // Fallback für Archive oder andere Seiten $page_title = single_post_title('', false); } // Sauberer Titel: Seitentitel | Website-Titel return $page_title . ' | ' . $site_name; }); //FAVICON function add_favicons() { ?> ' . "\n"; } } } add_action( 'wp_head', 'add_excerpt_as_meta_description', 5 ); //REMOVE FRONTEND ADMIN BAR add_filter('show_admin_bar', '__return_false'); //REMOVE COMMENT FUNCTIONALITY add_action('admin_init', function () { // Redirect any user trying to access comments page global $pagenow; if ($pagenow === 'edit-comments.php') { wp_safe_redirect(admin_url()); exit; } // Remove comments metabox from dashboard remove_meta_box('dashboard_recent_comments', 'dashboard', 'normal'); // Disable support for comments and trackbacks in post types foreach (get_post_types() as $post_type) { if (post_type_supports($post_type, 'comments')) { remove_post_type_support($post_type, 'comments'); remove_post_type_support($post_type, 'trackbacks'); } } }); add_filter('comments_open', '__return_false', 20, 2); // Close comments on the front-end add_filter('pings_open', '__return_false', 20, 2); add_filter('comments_array', '__return_empty_array', 10, 2); // Hide existing comments add_action('admin_menu', function () { remove_menu_page('edit-comments.php'); }); // Remove comments page in menu add_action('init', function () { if (is_admin_bar_showing()) remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60); }); // Remove comments links from admin bar //ALLOW EDITORS EDITING PRIVACY POLICY PAGE add_action('map_meta_cap', 'custom_manage_privacy_options', 1, 4); function custom_manage_privacy_options($caps, $cap, $user_id, $args) { if (!is_user_logged_in()) return $caps; $user_meta = get_userdata($user_id); if (array_intersect(['editor', 'administrator'], $user_meta->roles)) { if ('manage_privacy_options' === $cap) { $manage_name = is_multisite() ? 'manage_network' : 'manage_options'; $caps = array_diff($caps, [ $manage_name ]); } } return $caps; } //ADD ACTIVE CLASS TO NAVIGATION LINK add_filter( 'render_block', function( $block_content, $block ) { if ( 'core/navigation-link' === $block['blockName'] && is_page() ) { global $post; $parent_id = wp_get_post_parent_id( $post->ID ); if ( $parent_id && isset( $block['attrs']['id'] ) && intval( $block['attrs']['id'] ) === $parent_id ) { // Füge Klasse nur im
  • -Tag hinzu (nicht im ) $block_content = preg_replace( '/]*)class="([^"]*)"/', '/s', $custom_icon, $block_content ); } return $block_content; }, 10, 2 ); // RENDER BLOCK TAGS WITHOUT LINK function render_post_terms_without_links( $attributes, $content, $block ) { if ( empty( $block->context['postId'] ) ) { return ''; } $post_id = $block->context['postId']; $taxonomy = isset( $attributes['term'] ) ? $attributes['term'] : 'post_tag'; $terms = get_the_terms( $post_id, $taxonomy ); if ( ! $terms || is_wp_error( $terms ) ) { return ''; } $term_names = wp_list_pluck( $terms, 'name' ); return sprintf( '', esc_html( implode( ', ', $term_names ) ) ); } add_action( 'init', function() { unregister_block_type( 'core/post-terms' ); register_block_type( 'core/post-terms', array( 'render_callback' => 'render_post_terms_without_links', ) ); }); // ADD ID SLUG TO NEWS QUERY BLOCK add_filter( 'render_block_core/query', function( $block_content, $block ) { // Nur Frontend (keine Admin / REST / Cron) if ( is_admin() && ! wp_doing_ajax() ) { return $block_content; } if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { return $block_content; } // Ersetze alle
  • - Tags: falls class="post-123" vorhanden und noch keine id, id="{slug}" einfügen $result = preg_replace_callback( '/]*)>/i', function( $matches ) { $attrs = $matches[1]; // Wenn schon eine id vorhanden ist -> belassen if ( preg_match( '/\sid\s*=\s*[\'"]/i', $attrs ) ) { return ''; } // Prüfe auf class="... post-123 ..." if ( preg_match( '/\bpost-(\d+)\b/i', $attrs, $m ) ) { $post_id = (int) $m[1]; if ( $post_id > 0 ) { $slug = get_post_field( 'post_name', $post_id ); if ( $slug ) { return '
  • '; } } } // Fallback: global $post nutzen, wenn verfügbar global $post; if ( $post instanceof WP_Post ) { return '
  • '; } // nichts gefunden -> unverändert return ''; }, $block_content ); return $result; }, 10, 2 ); //CHANGE READ MORE URL TO NEWS PAGE AND ANCHOR add_filter( 'render_block_core/read-more', function( $block_content, $block ) { global $post; if ( ! $post instanceof WP_Post ) { return $block_content; } if ( get_post_type( $post ) !== 'post' ) { return $block_content; } // Zielseite mit Anker vorbereiten $slug = esc_attr( $post->post_name ); $target_page_slug = 'aktuelles'; $target_url = home_url( '/' . $target_page_slug . '/#' . $slug ); // Ersetze href im Read-More-Link $block_content = preg_replace( '/href=["\']([^"\']+)["\']/', 'href="' . esc_url( $target_url ) . '"', $block_content ); return $block_content; }, 10, 2 ); include_once('include/functions-schemaorg.php');