Úprava live results searchu v Elementore

Problém Elementor search widgetu je ten, že hľadá v názve, contente a možno aj metadátach každého postu. A ešte väčší problém je ten, že tieto výsledky považuje za rovnocenné. Ak by sme teda dali hľadať písmeno „a“, tak nájde všetky posty, lebo v každom poste asi bude písmeno „a“. No a to je hlúposť. 

Príklad z praxe

Mám klienta, ktorý predáva parochne a príslušenstvo. Do príslušenstva patrí kondicionér napríklad. O kondicionéri sa však hovorí aj pri každej parochni (aký kondicionér je na daný produkt vhodný), a tak keď niekto chce vyhľadať kondicionér, namiesto toho, aby mu relevantne podhodilo ako prvé kondicionéry, mu podhadzuje parochne, v ktorých sa hovorí o kondicionéri. No a to, samozrejme, nechceme. 

Riešenie

Riešením je teda vybodnúť sa na default search engine Elementora a spraviť si to po svojom. Na to použijeme custom query ID.

Vyhľadávanie nastavíme len pre produkty (to sa inak dá aj v nastaveniach toho widgetu) a potom neberieme všetko bezhlavo rad-radom ako to databáza servíruje, ale pekne krásne si zoradíme relevantnosť:

  1. Najrelevantnejší je názov produktu. Nachádza sa v ňom slovo „kondicionér“, či nie? Ak áno, máme prvý výsledok, ak nie, ideme o patro níž…
  2. Potom pozrieme excerpt, aj keď priznám sa, že excerpty pri produktoch rozhodne neriešim. 
  3. No a napokon pozrieme content, čiže popis produktu. Ak sa tu nachádza slovo „kondicionér“, tak máme ďalší výsledok, ale až pod tým, ktorý je relevantnejší
				
					add_action( 'elementor/query/lava_custom_search', function( $query ) {

    // ✔️ LEN produkty
    $query->set( 'post_type', ['product'] );
    $query->set( 'post_status', 'publish' );
    $query->set( 'ignore_sticky_posts', true );

    // ==========================
    // VÁŽENÁ RELEVANCIA
    // ==========================

    add_filter( 'posts_orderby', function( $orderby, $wp_query ) use ( $query ) {

        if ( $wp_query !== $query ) {
            return $orderby;
        }

        global $wpdb;

        $search = $wp_query->get( 's' );
        if ( empty( $search ) ) return $orderby;

        $search = esc_sql( $search );

        return "
            (
                CASE
                    WHEN {$wpdb->posts}.post_title LIKE '%{$search}%' THEN 100
                    WHEN {$wpdb->posts}.post_excerpt LIKE '%{$search}%' THEN 50
                    WHEN {$wpdb->posts}.post_content LIKE '%{$search}%' THEN 10
                    ELSE 0
                END
            ) DESC
        ";

    }, 10, 2 );

    // ==========================
    // SEARCH SCOPE
    // ==========================

    add_filter( 'posts_search', function( $search, $wp_query ) use ( $query ) {

        if ( $wp_query !== $query ) {
            return $search;
        }

        global $wpdb;

        $terms = $wp_query->get( 'search_terms' );
        if ( empty( $terms ) ) return $search;

        $sql = [];
        foreach ( $terms as $term ) {
            $term = esc_sql( $wpdb->esc_like( $term ) );
            $sql[] = "
                (
                    {$wpdb->posts}.post_title LIKE '%{$term}%'
                    OR {$wpdb->posts}.post_excerpt LIKE '%{$term}%'
                    OR {$wpdb->posts}.post_content LIKE '%{$term}%'
                )
            ";
        }

        return ' AND ' . implode( ' AND ', $sql );

    }, 10, 2 );

});

				
			

Nebudem sa tu hrať na hrdinu a zatĺkať, rovno sa priznám, že tento kód za mňa vyprdla AI. Sám by som to písal… čo ja viem… deň? A takto mám hotové a funkčné riešenie za 20 minút (vysvetľovanie chatu gptu, implementácia, testovanie).

Určite to ocení najmä klient, ktorý zaplatí za túto úpravu 13€ (20 minút) a nie 320€ (ak by som na tom robil celý deň). 

Podobné články

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *