Wiki

für WordPress-Entwickler

Anleitungen, Snippets und mehr…

Eine Suche im Theme integrieren

Hier werde ich erläutern, wie ich eine Basic-Suche im Theme verwirklicht habe.

Zur Unterstützung habe ich das PlugIn Relevanssi in der kostenlosen Version installiert und aktiviert. Dieses PlugIn indexiert auch ACF-Feldgruppen, die ich für die Erstellung meiner Blöcke benutze.

searchforms.php

Hier erstelle ich mir eine Funktion zur Darstellung des Suchformulares. Dieses Formular kann ich dann über den Shortcode <?php echo do_shortcode(‚[search_form_2]‘); ?> an allen relevanten Stellen im Theme einbinden.

/**
 * Searchform 2 (Used in Menü and Search-Result))
 * Shortcode: echo do_shortcode('[search_form_2]');
 * @return string
 */
function search_form_2_shortcode() {
	return '<form style="top: 5px; position: relative;" role="search" method="get" class="search-form-2" action="' . esc_url(home_url('/')) . '">
				<label>
					<span class="screen-reader-text">' . _x('Suche nach:', 'label for search field', 'hbdev') . '</span>
					<input type="search" class="search-field" placeholder="' . esc_attr_x(' Search …', 'placeholder', 'hbdev') . '" value="' . get_search_query() . '" name="s" autocomplete="off"/>
				</label>
				<button type="submit" class="search-submit"></button>
			</form>';
}
add_shortcode('search_form_2', 'search_form_2_shortcode');

search.php

Dies ist das Template für die Ergebnis-Seite der Suche. In diesem Fall arbeite ich mit Hooks und Actions. Die eigentlichen Template-Dateien entfallen also. Etwas CSS habe ich unten angefügt, damit die Einbindung in ein eigenes Theme leichter fällt. Im Produktivbetrieb, sollte das Styling aber ausgelagert werden.

<?php
/**
 * The template for displaying search results pages
 *
 * @link https://developer.wordpress.org/themes/basics/template-hierarchy/#search-result
 *
 * @package hbdev
 */

get_header();
?>

<section id="primary" class="content-area hg-white pd-100">
	<main id="main" class="site-main">

		<?php if ( have_posts() ) : ?>
			<div class="container-fluid gutter flexible_content px-24">
                <?php if ( ICL_LANGUAGE_CODE == 'de' ) : ?>
                    <h1 style="margin-bottom: 30px;">Ihre Suchergebnisse</h1>
				<?php else: ?>
                    <h1 style="margin-bottom: 30px;">Your Search-Results</h1>
                <?php endif; ?>
				<div>
					<?php /* get_search_form(); */ ?>
					<?php echo do_shortcode('[search_form_2]'); ?>
				</div>

				<div class="search-results-count" style="margin-top: 5px; margin-bottom: 50px;">
					<?php
					global $wp_query;
					$total_results = $wp_query->found_posts;

					if ( ICL_LANGUAGE_CODE == 'de' ) :
						printf(
							esc_html__( '%s Ergebnisse gefunden', 'hbdev' ),
							'<strong>' . esc_html( $total_results ) . '</strong>'
						);
					else:
						printf(
							esc_html__( '%s results found', 'hbdev' ),
							'<strong>' . esc_html( $total_results ) . '</strong>'
						);
					endif;

					?>
				</div>

				<?php
				/* Start the Loop */
				while ( have_posts() ) :
					the_post();

					/**
					 * Run the loop for the search to output the results.
					 * If you want to overload this in a child theme then include a file
					 * called content-search.php and that will be used instead.
					 */
					do_action( 'hbdev_searchcontent' );

				endwhile;

				// Pagination
				the_posts_pagination( array(
					'mid_size'  => 0,
					'prev_text' => __( '<', 'hbdev' ),
					'next_text' => __( '>', 'hbdev' ),
				) ); ?>

			</div>

		<?php else :

			do_action( 'hbdev_no_results' );

		endif;
		?>

	</main><!-- #main -->
</section><!-- #primary -->

<?php
get_footer();
?>

<style>
    .search-results-count {
        font-size: 16px;
    }
    .pagination {
        justify-content: center;
    }
    a.prev {
        margin-right: 10px;
    }
    a.next {
        margin-left: 10px;
    }
    .next, .prev, .dots, .page-numbers, .current {
        color: #454545;
        text-decoration: none;
    }
    .current {
        font-weight: bold;
        display: unset;
        border: none;
    }
</style>

Das hier sind meine, für die Suchfunktion relevanten, Hooks und Actions:

/**
 * Search-Hooks
 */
add_action( 'Hundebesitzer_searchcontent', 'hbdev_searchcontent', 10 );
add_action( 'hbdev_no_results', 'hbdev_no_results_content', 10 );
/**
 * Search-Actions
 */
function hbdev_searchcontent() {
    ?>
    <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <header class="entry-header">
			<?php the_title( sprintf( '<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>' ); ?>
        </header><!-- .entry-header -->

        <div class="entry-summary">
			<?php the_excerpt(); ?>
            <a href="<?php the_permalink(); ?>"><?php echo esc_url( get_permalink() ); ?></a>
        </div><!-- .entry-summary -->

    </article><!-- #post-<?php the_ID(); ?> -->


    <style>
        h2.entry-title {
            display: flex;
            margin-bottom: 9px;
            line-height: normal;
        }
        h2.entry-title a {
            color: #454545;
            font-size: 24px;
        }
        h2.entry-title a:hover {
            color: #E8E100;
        }
        .entry-summary {
            margin-bottom: 54px;
        }
        .entry-summary a {
            color: #454545;
        }
        .entry-summary a:hover {
            color: #E8E100;
        }
    </style>
    <?php
}

function hbdev_no_results_content() {
	?>
    <div class="container-no-result" style="margin-top: 50px; margin-bottom: 50px;">
		<?php if ( ICL_LANGUAGE_CODE == 'de' ) : ?>
            <h2>Keine Ergebnisse gefunden...</h2>
            <p><?php printf( esc_html__( 'Haben Sie sich möglicherweise vertippt?%sBitte versuchen Sie es mit einem anderen oder allgemeineren Suchbegriff.', 'hbdev' ), '<br>' ); ?></p>
		<?php else: ?>
            <h2>So results found...</h2>
            <p><?php printf( esc_html__( 'Did you perhaps mistype something?%sPlease try using a different or more general search term.', 'hbdev' ), '<br>' ); ?></p>
		<?php endif; ?>

        <?php echo do_shortcode('[search_form_2]'); ?>
    </div>

    <style>
        .container-no-result {
            padding-left: 7.8125rem;
            padding-right: 7.8125rem;
        }
        @media (max-width: 768px) {
            .container-no-result {
                padding-left: 30px !important;
                padding-right: 30px !important;
            }
        }
    </style>
<?php }

Auch hier gilt wieder: Im Produktivbetrieb „Hinfort mit dem Styling!“

Die Funktion hbdev_searchcontent() stellt die einzelnen Punkte in der Ergebnisliste zusammen. Während die Funktion hbdev_no_results_content() die Darstellung übernimmt, wenn die Suche zu keinem Ergebnis führt.

Menüeinbindung

Da ich gerne mit der Menüfunktion von WordPress arbeite, damit ich im Backend das Menü und seine Struktur selbst definieren kann, zeige ich hier noch die Einbindung des Suchfeldes in das Menü.

wp_nav_menu(
					array(
						'theme_location'  => 'mainv2',
						'menu_class'      => 'navbar-nav mr-0 ml-auto',
						'container_class' => 'navbar-new collapse navbar-collapse justify-content-end',
						'container_id'    => 'navbarTop',
						'items_wrap'      => '<ul class="%2$s">%3$s<li class="menu-item search-field nav-item">' . do_shortcode('[search_form_2]') . '</li></ul>',
						'fallback_cb'     => false,
						'li_class'        => 'nav-item',
					)
				);

Relevant ist das Attribut items_wrap.

Darstellung der Suchergebnisse

Damit in der Ergebnisliste das Excerpt eines Beitrages erscheinen kann, muß dieses in der functions.php für Seiten aktiviert werden.

/**
 * activates the_excerpt for pages
 * @return void
 */
function add_excerpt_to_pages() {
	add_post_type_support( 'page', 'excerpt' );
}
add_action( 'init', 'add_excerpt_to_pages' );

Zusätzliches Snippet

Die folgende Funktion fügt dem <a>-Tag im WordPress-Navigationsmenü automatisch die Klasse nav-link hinzu. Dies ist nützlich, wenn du Bootstrap oder andere CSS-Frameworks verwendest, die spezifische Klassen wie nav-link erfordern, um das Styling der Navigation zu steuern.

function Hundebesitzer_nav_menu_a_class( $classes ) {
	return preg_replace( '/<a /', '<a class="nav-link" ', $classes );
}
add_filter( 'wp_nav_menu', 'hbdev_nav_menu_a_class' );