PHP
<?php
/**
* Shortcode: [news-slider]
* In functions.php einfügen oder als kleines Plugin verwenden.
*/
function news_slider_shortcode() {
$args = [
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => -1,
'ignore_sticky_posts' => false,
'orderby' => 'date',
'order' => 'DESC',
];
$query = new WP_Query( $args );
if ( ! $query->have_posts() ) {
return '';
}
// Sticky zuerst sortieren
$sticky_ids = get_option( 'sticky_posts' );
$stickies = [];
$regulars = [];
while ( $query->have_posts() ) {
$query->the_post();
$post = get_post();
if ( in_array( $post->ID, $sticky_ids ) ) {
$stickies[] = $post;
} else {
$regulars[] = $post;
}
}
wp_reset_postdata();
$posts = array_merge( $stickies, $regulars );
$total = count( $posts );
// Gutenberg Block-Rendering vorbereiten
if ( ! function_exists( 'render_block' ) ) {
require_once ABSPATH . 'wp-includes/blocks.php';
}
$svg_next = '<svg width="100%" height="100%" viewBox="0 0 100 177" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g transform="matrix(-1.93606,0,0,1.93606,235.82,-113.022)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,255.26,-94.242)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,275.661,-73.4043)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,295.039,-53.9325)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,314.553,-34.7509)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,293.866,-14.2368)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,273.823,5.27794)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,252.835,25.6766)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(-1.93606,0,0,1.93606,231.803,46.5381)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g></svg>';
$svg_prev = '<svg width="100%" height="100%" viewBox="0 0 100 177" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"><g transform="matrix(1.93606,0,0,1.93606,-135.819,-113.022)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-155.259,-94.242)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-175.66,-73.4043)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-195.038,-53.9325)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-214.552,-34.7509)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-193.865,-14.2368)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-173.822,5.27794)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-152.834,25.6766)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g><g transform="matrix(1.93606,0,0,1.93606,-131.802,46.5381)"><circle cx="115.274" cy="62.93" r="4.455" style="fill:white;"></circle></g></svg>';
$uid = 'ns-' . uniqid();
ob_start();
?>
<div class="news-slider" id="<?php echo esc_attr( $uid ); ?>" data-total="<?php echo $total; ?>">
<div class="news-slider__track">
<?php foreach ( $posts as $i => $post ) :
$GLOBALS['post'] = $post;
setup_postdata( $post );
$thumb_id = get_post_thumbnail_id( $post->ID );
$thumb_url = $thumb_id ? wp_get_attachment_image_url( $thumb_id, 'large' ) : '';
$content = apply_filters( 'the_content', $post->post_content );
$title = get_the_title( $post->ID );
?>
<div class="news-slider__slide<?php echo $i === 0 ? ' is-active' : ''; ?>" aria-hidden="<?php echo $i === 0 ? 'false' : 'true'; ?>">
<div class="news-slider__image" style="<?php echo $thumb_url ? 'background-image:url(' . esc_url( $thumb_url ) . ');' : ''; ?>"></div>
<div class="news-slider__content">
<h2 class="news-slider__title"><?php echo esc_html( $title ); ?></h2>
<div class="news-slider__body"><?php echo $content; ?></div>
</div>
</div>
<?php endforeach;
wp_reset_postdata(); ?>
</div>
<?php if ( $total > 1 ) : ?>
<button class="news-slider__btn news-slider__btn--prev" aria-label="Vorheriger Beitrag">
<?php echo $svg_prev; ?>
</button>
<button class="news-slider__btn news-slider__btn--next" aria-label="Nächster Beitrag">
<?php echo $svg_next; ?>
</button>
<div class="news-slider__pagination">
<?php for ( $i = 0; $i < $total; $i++ ) : ?>
<button class="news-slider__dot<?php echo $i === 0 ? ' is-active' : ''; ?>" data-index="<?php echo $i; ?>" aria-label="Beitrag <?php echo $i + 1; ?>"></button>
<?php endfor; ?>
</div>
<?php endif; ?>
</div>
<style>
.news-slider {
position: relative;
overflow: hidden;
}
.news-slider__track {
position: relative;
}
.news-slider__slide {
display: none;
align-items: stretch;
min-height: 450px;
}
.news-slider__slide.is-active {
display: flex;
}
.news-slider__image {
flex: 0 0 30%;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.news-slider__content {
flex: 0 0 70%;
padding: 32px 48px;
overflow: auto;
background: #a89968;
}
.news-slider__title {
margin-top: 0;
margin-bottom: 0.75rem;
color: #fff;
line-height: 1.2 !important;
}
.news-slider__body {
color: #fff;
}
.news-slider__body p {
color: #fff;
line-height: 1.2 !important;
}
.news-slider__btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 40px;
height: 80px;
background: transparent;
border: none;
cursor: pointer;
padding: 0;
z-index: 10;
}
.news-slider__btn--prev { left: 16px; }
.news-slider__btn--next { right: 16px; }
.news-slider__pagination {
display: flex;
justify-content: center;
gap: 8px;
margin-top: 1rem;
}
.news-slider__btn:hover,
.news-slider__btn:focus,
.news-slider__btn:focus-visible {
background: transparent;
box-shadow: none;
}
.news-slider__dot {
width: 12px;
height: 12px;
border-radius: 50%;
border: 2px solid currentColor;
background: transparent;
cursor: pointer;
padding: 0;
}
.news-slider__dot.is-active {
background: currentColor;
}
@media all and (max-width: 768px) {
.news-slider__slide {
flex-direction: column;
}
.news-slider__image {
flex: 0 0 250px;
height: 250px;
}
.news-slider__content {
padding: 24px;
}
.news-slider__btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 36px;
background: transparent;
border: none;
cursor: pointer;
padding: 0;
z-index: 10;
}
.news-slider__btn--prev { left: 0; }
.news-slider__btn--next { right: 0; }
}
</style>
<script>
(function() {
const slider = document.getElementById('<?php echo esc_js( $uid ); ?>');
if (!slider) return;
const slides = slider.querySelectorAll('.news-slider__slide');
const dots = slider.querySelectorAll('.news-slider__dot');
let current = 0;
const total = slides.length;
function goTo(index) {
slides[current].classList.remove('is-active');
slides[current].setAttribute('aria-hidden', 'true');
dots[current].classList.remove('is-active');
current = (index + total) % total;
slides[current].classList.add('is-active');
slides[current].setAttribute('aria-hidden', 'false');
dots[current].classList.add('is-active');
}
slider.querySelector('.news-slider__btn--prev').addEventListener('click', () => goTo(current - 1));
slider.querySelector('.news-slider__btn--next').addEventListener('click', () => goTo(current + 1));
dots.forEach(dot => dot.addEventListener('click', () => goTo(+dot.dataset.index)));
})();
</script>
<?php
return ob_get_clean();
}
add_shortcode( 'news-slider', 'news_slider_shortcode' );