Forum Replies Created
-
AuthorPosts
-
info_piT4
ParticipantYou cannot access this content.
info_piT4
ParticipantYou cannot access this content.
info_piT4
ParticipantYou cannot access this content.
info_piT4
ParticipantNope, scroll down in the live results (don’t know if you can see it in the video, but here we go)
info_piT4
ParticipantAh bummer, thanks for replying so quickly though!
info_piT4
ParticipantYou cannot access this content.
info_piT4
Participantinfo_piT4
ParticipantYou cannot access this content.
info_piT4
ParticipantQuestion. Is it possible to place the settings box ([wpdreams_asp_settings id=8 element='div']) on the search.php but not show it on the front page? Or do I need to create two search instances for this?
I already tried <?php echo do_shortcode(‘[wpdreams_asp_settings id='.intval(BG_ASP_INSTANCE_ID).'element="div"]‘); ?> in search.php
But that doesn’t show anything, and the turning the settings by default on on the front page is of course going to result in displaying the settings on default on the front page.Sorry if this is a silly question.
info_piT4
ParticipantI got an error when posting my code, so I hope you can see the message above
August 21, 2025 at 11:58 am in reply to: Creating a results page (not live filtering), sorted #55261info_piT4
ParticipantDouble entry
-
This reply was modified 9 months, 2 weeks ago by
info_piT4. Reason: Double
August 21, 2025 at 11:57 am in reply to: Creating a results page (not live filtering), sorted #55260info_piT4
ParticipantOk made some changes, I still need to let my colleague test it, but maybe someone with xstore and asp can use it as a base.
It also has the suggested keywords now. it uses the first suggestion, and searches with it. if there are results it should display them, if not, it should say no results.functions.php
// ===== Ajax Search Pro: gedeelde instellingen ===== if ( ! defined('BG_ASP_INSTANCE_ID') ) { define('BG_ASP_INSTANCE_ID', 8); } /*CHANGE THE 8 TO YOUR INSTANCE ID */ /* ---------- Shortcodes renderers ---------- */ add_shortcode('asp_categories', function () { global $asp_cats; if (empty($asp_cats) || !is_array($asp_cats)) return ''; ob_start(); ?> <ul class="asp-cat-list"> <?php foreach ($asp_cats as $c): $name = isset($c->title) ? $c->title : ''; $link = isset($c->link) ? $c->link : '#'; $thumb = isset($c->image) ? $c->image : ''; ?> <li class="asp-cat-item"> <a href="<?php echo esc_url($link); ?>"> <?php if ($thumb): ?><img src="<?php echo esc_url($thumb); ?>" alt="<?php echo esc_attr($name); ?>"><?php endif; ?> <span><?php echo esc_html($name); ?></span> </a> </li> <?php endforeach; ?> </ul> <?php return ob_get_clean(); }); add_shortcode('asp_products', function () { global $asp_products; if (empty($asp_products) || !is_array($asp_products)) return ''; ob_start(); ?> <div class="asp-products-grid"> <?php foreach ($asp_products as $p): $title = isset($p->title) ? $p->title : ''; $link = isset($p->link) ? $p->link : '#'; $img = isset($p->image) ? $p->image : ''; $price_html = ''; if (!empty($p->id) && function_exists('wc_get_product')) { $obj = wc_get_product((int)$p->id); if ($obj) $price_html = $obj->get_price_html(); } ?> <a class="asp-product-card" href="<?php echo esc_url($link); ?>"> <?php if ($img): ?><img src="<?php echo esc_url($img); ?>" alt="<?php echo esc_attr($title); ?>"><?php endif; ?> <h3><?php echo esc_html($title); ?></h3> <?php if ($price_html): ?><div class="asp-price"><?php echo wp_kses_post($price_html); ?></div><?php endif; ?> </a> <?php endforeach; ?> </div> <?php return ob_get_clean(); }); add_shortcode('asp_pages_posts', function () { global $asp_pages; if (empty($asp_pages) || !is_array($asp_pages)) return ''; ob_start(); ?> <ul class="asp-pages-list"> <?php foreach ($asp_pages as $pg): $title = isset($pg->title) ? $pg->title : ''; $link = isset($pg->link) ? $pg->link : '#'; ?> <li><a href="<?php echo esc_url($link); ?>"><?php echo esc_html($title); ?></a></li> <?php endforeach; ?> </ul> <?php return ob_get_clean(); }); add_shortcode('asp_other', function () { global $asp_other; if (empty($asp_other) || !is_array($asp_other)) return ''; ob_start(); ?> <ul class="asp-other-list"> <?php foreach ($asp_other as $o): $title = isset($o->title) ? $o->title : ''; $link = isset($o->link) ? $o->link : '#'; ?> <li><a href="<?php echo esc_url($link); ?>"><?php echo esc_html($title); ?></a></li> <?php endforeach; ?> </ul> <?php return ob_get_clean(); }); /* ---------- Resultaat-splitsing voor tabs (client-side ASP run) ---------- */ add_filter('asp_results', function($results, $search_id){ if ((int)$search_id !== (int)BG_ASP_INSTANCE_ID) return $results; if (!wp_doing_ajax()) return $results; // alleen live overlay vullen if (empty($results)) { // Niets doen -> niet per ongeluk server-side arrays leegmaken return $results; } global $asp_cats, $asp_products, $asp_pages, $asp_other; $asp_cats = $asp_products = $asp_pages = $asp_other = []; foreach ($results as $r) { $pt = isset($r->post_type) ? $r->post_type : ''; $tx = isset($r->taxonomy) ? $r->taxonomy : ''; if ($tx === 'product_cat' || $pt === 'product_cat') { $asp_cats[] = $r; } elseif ($pt === 'product') { // optioneel: if (empty($r->image)) { ..thumbnail ophalen.. } $asp_products[] = $r; } elseif (in_array($pt, ['page','post'], true)) { $asp_pages[] = $r; } else { $asp_other[] = $r; } } return $results; }, 10, 2); /* ---------- DEBUG helper (enkelvoudig!) ---------- */ $GLOBALS['bg_asp_debug'] = []; if ( ! function_exists('bg_dbg') ) { function bg_dbg($k, $v){ $GLOBALS['bg_asp_debug'][$k] = $v; } } /* ---------- (Optioneel) suggested phrases cache voor debugging ---------- */ $GLOBALS['bg_asp_suggested'] = []; add_filter('asp_suggested_phrases', function($phrases, $search_id){ $phrases = is_array($phrases) ? array_values(array_filter(array_map('trim', $phrases))) : []; $GLOBALS['bg_asp_suggested'][(int)$search_id] = $phrases; return $phrases; }, 10, 2); /* ---------- Kandidaten generator (NL heuristics) ---------- */ function bg_asp_candidates($orig){ $w = mb_strtolower(trim((string)$orig)); $c = []; if ($w !== '') $c[] = $w; // NL heuristics if (preg_match('~kosten$~u', $w)) { $c[] = preg_replace('~kosten$~u', 'ing', $w); // bezorgkosten -> bezorging $c[] = preg_replace('~kosten$~u', 'en', $w); // bezorgkosten -> bezorgen $c[] = 'verzendkosten'; $c[] = 'verzending'; } if (strpos($w, 'bezorg') !== false) { $c[] = 'bezorging'; $c[] = 'bezorgen'; } // 1e woord als laatste fallback $parts = preg_split('~\s+~u', $w, -1, PREG_SPLIT_NO_EMPTY); if (!empty($parts)) $c[] = $parts[0]; // Uniek + schoon $c = array_values(array_unique(array_filter(array_map('trim', $c)))); return $c; } /* ---------- Server-side ASP-run (vult óók tabs) ---------- */ // ===================== Server-side ASP-run (vult óók tabs) ===================== function bg_asp_run_fallback_query($phrase){ $phrase = trim((string)$phrase); $out_ids = []; global $asp_cats, $asp_products, $asp_pages, $asp_other; $asp_cats = is_array($asp_cats) ? $asp_cats : []; $asp_products = is_array($asp_products) ? $asp_products : []; $asp_pages = is_array($asp_pages) ? $asp_pages : []; $asp_other = is_array($asp_other) ? $asp_other : []; try { if (class_exists('\\WPDRMS\\ASP\\Query\\SearchQuery')) { $sq = new \WPDRMS\ASP\Query\SearchQuery([ 's' => $phrase, '_ajax_search' => false, 'posts_per_page' => 50 ], (int)BG_ASP_INSTANCE_ID); $rows = isset($sq->posts) && is_array($sq->posts) ? $sq->posts : []; foreach ($rows as $res) { $d = isset($res->asp_data) ? $res->asp_data : (object)[]; $id = isset($d->id) ? (int)$d->id : (isset($res->ID) ? (int)$res->ID : 0); $ct = isset($d->content_type) ? $d->content_type : ''; $pt = isset($d->post_type) ? $d->post_type : ( $id ? get_post_type($id) : '' ); $tx = isset($d->taxonomy) ? $d->taxonomy : ''; // Termen (categorieën) if ($ct === 'term' || $tx === 'product_cat' || $pt === 'product_cat') { $link = ($tx && $id && function_exists('get_term_link')) ? get_term_link($id, $tx) : '#'; if (!is_wp_error($link) && $link) $d->link = $link; $asp_cats[] = (object)[ 'id'=>$id,'title'=>$d->title ?? '','link'=>$d->link ?? '#','image'=>$d->image ?? '', 'post_type'=>$pt,'taxonomy'=>$tx ]; continue; } // Producten (robuster): direct product óf variatie → parent $is_product = ($pt === 'product' || $pt === 'product_variation'); if (!$is_product && $id) { $gpt = get_post_type($id); $is_product = ($gpt === 'product' || $gpt === 'product_variation'); $pt = $pt ?: $gpt; } if ($is_product) { // map variatie → parent voor de Woo-loop if (function_exists('wc_get_product')) { $p = wc_get_product($id); if ($p && $p->is_type('variation')) { $parent_id = $p->get_parent_id(); if ($parent_id) $id = (int)$parent_id; } } $asp_products[] = (object)[ 'id'=>$id,'title'=>$d->title ?? ( $id ? get_the_title($id) : '' ), 'link'=>$d->link ?? ( $id ? get_permalink($id) : '#' ), 'image'=>$d->image ?? '','post_type'=>'product','taxonomy'=>'' ]; if ($id) $out_ids[] = $id; continue; } // Pagina/bericht if (in_array($pt, ['page','post'], true)) { $asp_pages[] = (object)[ 'id'=>$id,'title'=>$d->title ?? ( $id ? get_the_title($id) : '' ), 'link'=>$d->link ?? ( $id ? get_permalink($id) : '#' ), 'image'=>$d->image ?? '','post_type'=>$pt,'taxonomy'=>'' ]; continue; } // Overige $asp_other[] = (object)[ 'id'=>$id,'title'=>$d->title ?? '','link'=>$d->link ?? '#', 'image'=>$d->image ?? '','post_type'=>$pt,'taxonomy'=>$tx ]; } } } catch (\Throwable $e) { /* optioneel loggen */ } // Laat Woo de zichtbaarheid bepalen: filter IDs naar zichtbare + unieke $out_ids = bg_wc_filter_visible_products($out_ids); // Eventuele kale WP zoekfallback op producten (optioneel) if (empty($out_ids)) { $wpq = new WP_Query([ 'post_type' => 'product', 'post_status' => ['publish'], 's' => $phrase, 'posts_per_page' => 50, 'fields' => 'ids' ]); $out_ids = bg_wc_filter_visible_products( is_array($wpq->posts) ? $wpq->posts : [] ); } return ['ids' => $out_ids, 'filled' => !empty($out_ids)]; } function bg_asp_fill_tabs_from_wd_asp(){ if (!function_exists('wd_asp')) return; $results = (isset(wd_asp()->results) && method_exists(wd_asp()->results, 'getResults')) ? wd_asp()->results->getResults() : []; if (empty($results) || !is_array($results)) return; global $asp_cats, $asp_products, $asp_pages, $asp_other; $asp_cats = is_array($asp_cats) ? $asp_cats : []; $asp_products = is_array($asp_products) ? $asp_products : []; $asp_pages = is_array($asp_pages) ? $asp_pages : []; $asp_other = is_array($asp_other) ? $asp_other : []; foreach ($results as $r) { $obj = (object)[ 'id' => isset($r->id) ? (int)$r->id : 0, 'title' => isset($r->title) ? $r->title : '', 'link' => isset($r->link) ? $r->link : '#', 'image' => isset($r->image) ? $r->image : '', 'post_type' => isset($r->post_type) ? $r->post_type : '', 'taxonomy' => isset($r->taxonomy) ? $r->taxonomy : '' ]; if ($obj->taxonomy === 'product_cat' || $obj->post_type === 'product_cat') { $asp_cats[] = $obj; } elseif ($obj->post_type === 'product') { $asp_products[] = $obj; } elseif (in_array($obj->post_type, ['page','post'], true)) { $asp_pages[] = $obj; } else { $asp_other[] = $obj; } } } function bg_wc_filter_visible_products(array $ids){ if (!function_exists('wc_get_product')) return array_values(array_unique(array_map('intval',$ids))); $out = []; foreach (array_unique(array_map('intval', $ids)) as $id) { $p = wc_get_product($id); if (!$p) continue; // Variatie -> parent if ($p->is_type('variation')) { $parent_id = $p->get_parent_id(); if ($parent_id) { $p = wc_get_product($parent_id); if (!$p) continue; $id = $parent_id; } } if (method_exists($p, 'is_visible') ? $p->is_visible() : true) { $out[] = $id; } } return array_values(array_unique($out)); } /* ---------- Main hijack van resultatenpagina ---------- */ add_action('pre_get_posts', function($q){ if ( is_admin() || !$q->is_main_query() || !is_search() ) return; if ((int)($_GET['asp_active'] ?? 0) !== 1 || (int)($_GET['p_asid'] ?? 0) !== (int)BG_ASP_INSTANCE_ID) return; if (!function_exists('wd_asp')) return; unset($GLOBALS['bg_asp_predicted']); // reset melding $orig = isset($_GET['s']) ? trim((string)$_GET['s']) : ''; $q->set('post_type', 'product'); // 1) live ASP results → IDs $ids = []; if (isset(wd_asp()->results) && method_exists(wd_asp()->results, 'getResults')) { foreach ((array) wd_asp()->results->getResults() as $r) { if (!empty($r->id) && (($r->post_type ?? '') === 'product' || ($r->post_type ?? '') === 'product_variation')) { $ids[] = (int)$r->id; } } } $ids = bg_wc_filter_visible_products($ids); if (!empty($ids)) { $q->set('post__in', $ids); $q->set('orderby', 'post__in'); if (function_exists('bg_asp_fill_tabs_from_wd_asp')) bg_asp_fill_tabs_from_wd_asp(); return; } // 2) server-side run op ORIGINELE term $base = bg_asp_run_fallback_query($orig); if (!empty($base['ids'])) { $q->set('post__in', $base['ids']); $q->set('orderby', 'post__in'); return; } // 3) kandidaten (alleen als origineel niets oplevert) foreach (bg_asp_candidates($orig) as $cand) { if (mb_strtolower($cand) === mb_strtolower($orig)) continue; $out = bg_asp_run_fallback_query($cand); if (!empty($out['ids'])) { $q->set('post__in', $out['ids']); $q->set('orderby', 'post__in'); $GLOBALS['bg_asp_predicted'] = ['original' => $orig, 'used' => $cand]; return; } } // 4) nog niets $q->set('post__in', [0]); }, 20); /* ---------- Zoek-LIKE uitzetten als we post__in sturen ---------- */ add_filter('posts_search', function($search, $q){ if ( $q->is_main_query() && $q->is_search() && $q->get('post_type') === 'product' && !empty($q->get('post__in')) ) { return ''; // Laat post__in leidend zijn } return $search; }, 20, 2); // 1) Sla de keyword suggestions op in een global add_filter('asp/suggestions/keywords', function($keywords, $phrase){ global $asp_suggestions; $asp_suggestions = $keywords; // eerste suggestie bewaren return $keywords; }, 10, 2); // 2) Controleer bij een search.php render of er geen resultaten zijn, en trigger fallback add_action('template_redirect', function() { if (!is_search()) return; if (!defined('BG_ASP_INSTANCE_ID')) return; global $asp_products, $asp_cats, $asp_pages, $asp_other, $asp_suggestions; // Safeguard arrays $asp_products = is_array($asp_products) ? $asp_products : []; $asp_cats = is_array($asp_cats) ? $asp_cats : []; $asp_pages = is_array($asp_pages) ? $asp_pages : []; $asp_other = is_array($asp_other) ? $asp_other : []; // Check: geen resultaten in alle tabs $total_results = count($asp_products) + count($asp_cats) + count($asp_pages) + count($asp_other); if ($total_results > 0) return; // resultaten, niks doen // Check: hebben we een suggestie? if (empty($asp_suggestions) || !is_array($asp_suggestions)) return; $first_suggestion = trim($asp_suggestions[0]); if (!$first_suggestion) return; // Redirect naar dezelfde zoekpagina met nieuw zoekwoord $url = add_query_arg('s', urlencode($first_suggestion), home_url('/')); // Optioneel: forceer ASP active en instance $url = add_query_arg([ 'asp_active' => 1, 'p_asid' => BG_ASP_INSTANCE_ID ], $url); wp_safe_redirect($url); exit; });search.php
<?php /** * search.php — Tabs met Ajax Search Pro splitsing * - Producten-tab: gebruikt standaard Woo/XStore archive loop (met wrappers) * - Andere tabs: eenvoudige weergave via gesplitste ASP-globals */ defined('ABSPATH') || exit; get_header(); if ( ! defined('BG_ASP_INSTANCE_ID') ) define('BG_ASP_INSTANCE_ID', 8); global $asp_cats, $asp_products, $asp_pages, $asp_other; // Query markers $search_query = get_search_query(); $p_asid = isset($_GET['p_asid']) ? (int) $_GET['p_asid'] : 0; $asp_active = isset($_GET['asp_active']) ? (int) $_GET['asp_active'] : 0; $use_asp = ($asp_active === 1 && $p_asid === (int)BG_ASP_INSTANCE_ID); // Safeguards $asp_cats = is_array($asp_cats) ? $asp_cats : []; $asp_products = is_array($asp_products) ? $asp_products : []; $asp_pages = is_array($asp_pages) ? $asp_pages : []; $asp_other = is_array($asp_other) ? $asp_other : []; // Bepaal welke tabs zichtbaar zijn global $wp_query; $has_wc_products = $use_asp && isset($wp_query) && (int)$wp_query->post_count > 0; $show_products = $has_wc_products; $show_cats = !empty($asp_cats); $show_pages = !empty($asp_pages); $show_other = !empty($asp_other); // Eerste actieve tab $active_tab = $show_products ? 'products' : ($show_cats ? 'cats' : ($show_pages ? 'pages' : ($show_other ? 'other' : 'none'))); ?> <div class="custom-search-tabs-container"> <div class="container"> <div class="search-header"> <h1 class="search-title"> <?php echo $search_query ? sprintf( esc_html__('Zoekresultaten voor: “%s”', 'xstore-child'), esc_html($search_query) ) : esc_html__('Zoekresultaten', 'xstore-child'); ?> </h1> <div class="search-form-wrapper"> <?php echo do_shortcode('[wpdreams_ajaxsearchpro id='.intval(BG_ASP_INSTANCE_ID).']'); ?> </div> </div> <?php if ( isset($_GET['debug']) && current_user_can('manage_options') ) : ?> <pre style="white-space:pre-wrap;background:#111;color:#eee;padding:12px;margin:12px 0;max-height:60vh;overflow:auto;"> <?php global $wp_query, $asp_cats, $asp_products, $asp_pages, $asp_other; $dump = [ 'GET' => $_GET, 'BG_ASP_INSTANCE_ID' => defined('BG_ASP_INSTANCE_ID') ? BG_ASP_INSTANCE_ID : null, 'use_asp' => isset($use_asp) ? $use_asp : null, 'wp_query->post_count' => isset($wp_query) ? (int)$wp_query->post_count : null, 'wp_query->found_posts' => isset($wp_query) ? (int)$wp_query->found_posts : null, 'asp_products_count' => is_array($asp_products) ? count($asp_products) : null, 'asp_cats_count' => is_array($asp_cats) ? count($asp_cats) : null, 'asp_pages_count' => is_array($asp_pages) ? count($asp_pages) : null, 'asp_other_count' => is_array($asp_other) ? count($asp_other) : null, 'bg_asp_predicted' => $GLOBALS['bg_asp_predicted'] ?? null, 'bg_asp_suggested' => $GLOBALS['bg_asp_suggested'] ?? null, 'bg_asp_debug' => $GLOBALS['bg_asp_debug'] ?? null, 'bg_asp_force_ids' => $GLOBALS['bg_asp_force_ids'] ?? null, ]; print_r($dump); ?> </pre> <?php endif; ?> <?php if ( ! empty($GLOBALS['bg_asp_predicted']) ) : ?> <p class="asp-predicted-note"> <?php printf( esc_html__('Geen exacte matches voor “%1$s”. We tonen resultaten voor “%2$s”.', 'xstore-child'), esc_html($GLOBALS['bg_asp_predicted']['original']), esc_html($GLOBALS['bg_asp_predicted']['used']) ); ?> </p> <?php endif; ?> <?php if (!$use_asp): ?> <p class="asp-inactive-note"><?php esc_html_e('Ajax Search Pro is niet actief voor deze aanvraag (asp_active=1 & p_asid ontbreken).', 'xstore-child'); ?></p> <?php get_search_form(); ?> <?php else: ?> <div class="custom-tabs"> <ul class="tab-titles" role="tablist"> <?php if ($show_products): ?> <li class="tab-title <?php echo ($active_tab==='products'?'active':''); ?>" data-tab="tab-products" role="tab"><?php esc_html_e('Producten','xstore-child'); ?></li> <?php endif; ?> <?php if ($show_cats): ?> <li class="tab-title <?php echo ($active_tab==='cats'?'active':''); ?>" data-tab="tab-cats" role="tab"><?php esc_html_e('Categorieën','xstore-child'); ?></li> <?php endif; ?> <?php if ($show_pages): ?> <li class="tab-title <?php echo ($active_tab==='pages'?'active':''); ?>" data-tab="tab-pages" role="tab"><?php esc_html_e('Pagina’s','xstore-child'); ?></li> <?php endif; ?> <?php if ($show_other): ?> <li class="tab-title <?php echo ($active_tab==='other'?'active':''); ?>" data-tab="tab-other" role="tab"><?php esc_html_e('Overige','xstore-child'); ?></li> <?php endif; ?> </ul> <div class="tab-panels"> <?php if ($show_products): ?> <div id="tab-products" class="tab-pane <?php echo ($active_tab==='products'?'active':''); ?>"> <?php // === Render producten o.b.v. ASP-IDs, met Woo pagination === // 1) Verzamel ASP product IDs in ASP-volgorde $asp_ids = []; foreach ($asp_products as $r) { if (!empty($r->id)) $asp_ids[] = (int) $r->id; } // 2) Als er niets is, toon nette no-products if (empty($asp_ids)) { do_action('woocommerce_before_main_content'); do_action('woocommerce_no_products_found'); do_action('woocommerce_after_main_content'); } else { // 3) Paginering en query $paged = max(1, get_query_var('paged') ? (int) get_query_var('paged') : (isset($_GET['paged']) ? (int) $_GET['paged'] : 1)); $per_page = (int) apply_filters('loop_shop_per_page', 12); // sluit aan op Woo instelling/filter $args = [ 'post_type' => 'product', 'post__in' => $asp_ids, 'orderby' => 'post__in', 'posts_per_page' => $per_page, 'paged' => $paged, ]; $q = new WP_Query($args); // 4) Woo loop-context en render do_action('woocommerce_before_main_content'); // Zorg dat Woo weet dat dit een "search-like" loop is if (function_exists('wc_set_loop_prop')) { wc_set_loop_prop('is_search', true); wc_set_loop_prop('current_page', $paged); wc_set_loop_prop('per_page', $per_page); wc_set_loop_prop('total', (int) $q->found_posts); } if ($q->have_posts()) { // Tijdelijk de global $wp_query wisselen zodat Woo pagination en hooks goed werken global $wp_query; $old_wp_query = $wp_query; $wp_query = $q; do_action('woocommerce_before_shop_loop'); woocommerce_product_loop_start(); while ($q->have_posts()) { $q->the_post(); if (get_post_type() !== 'product') continue; wc_get_template_part('content', 'product'); } woocommerce_product_loop_end(); do_action('woocommerce_after_shop_loop'); // pagination etc. // Herstel globals wp_reset_postdata(); $wp_query = $old_wp_query; } else { do_action('woocommerce_no_products_found'); } do_action('woocommerce_after_main_content'); } ?> </div> <?php endif; ?> <?php if ($show_cats): ?> <div id="tab-cats" class="tab-pane <?php echo ($active_tab==='cats'?'active':''); ?>"> <ul class="asp-cat-list"> <?php foreach ($asp_cats as $c): $name = isset($c->title) ? $c->title : ''; $link = isset($c->link) ? $c->link : '#'; $thumb = isset($c->image) ? $c->image : ''; ?> <li class="asp-cat-item"> <a href="<?php echo esc_url($link); ?>"> <?php if ($thumb): ?><img src="<?php echo esc_url($thumb); ?>" alt="<?php echo esc_attr($name); ?>"><?php endif; ?> <span><?php echo esc_html($name); ?></span> </a> </li> <?php endforeach; ?> </ul> </div> <?php endif; ?> <?php if ($show_pages): ?> <div id="tab-pages" class="tab-pane <?php echo ($active_tab==='pages'?'active':''); ?>"> <ul class="asp-pages-list"> <?php foreach ($asp_pages as $pg): ?> <li><a href="<?php echo esc_url(isset($pg->link)?$pg->link:'#'); ?>"><?php echo esc_html(isset($pg->title)?$pg->title:''); ?></a></li> <?php endforeach; ?> </ul> </div> <?php endif; ?> <?php if ($show_other): ?> <div id="tab-other" class="tab-pane <?php echo ($active_tab==='other'?'active':''); ?>"> <ul class="asp-other-list"> <?php foreach ($asp_other as $o): ?> <li><a href="<?php echo esc_url(isset($o->link)?$o->link:'#'); ?>"><?php echo esc_html(isset($o->title)?$o->title:''); ?></a></li> <?php endforeach; ?> </ul> </div> <?php endif; ?> </div> </div> <?php endif; ?> </div> </div> <?php // Klein tabs-script inline add_action('wp_footer', function(){ ?> <script> (function(){ var wrap = document.querySelector('.custom-tabs'); if(!wrap) return; var titles = wrap.querySelectorAll('.tab-title'); var panes = wrap.querySelectorAll('.tab-pane'); function activate(id){ titles.forEach(function(t){ t.classList.toggle('active', t.getAttribute('data-tab')===id); }); panes.forEach(function(p){ p.classList.toggle('active', p.id===id); }); } titles.forEach(function(t){ t.addEventListener('click', function(e){ e.preventDefault(); activate(this.getAttribute('data-tab')); }); }); })(); </script> <?php }, 5); get_footer();And CSS
body.search .sidebar-enabled.sidebar-left { display: none !important; } /* Maak content breder als sidebar weg is */ body.search .container.sidebar-mobile-off_canvas.content-page { max-width: 100% !important; padding-left: 15px; padding-right: 15px; } body.custom-search-page .col-md-9.col-md-push-3 { width: 100% !important; float: none !important; } body.is-search-page .col-md-3.col-md-pull-9.sidebar-enabled.sidebar.sidebar-left { display: none !important; } .custom-tabs { margin-top: 1.5rem; } .custom-tabs .tab-titles { display:flex; gap:1rem; list-style:none; padding:0; margin:0 0 1rem; border-bottom:1px solid rgba(0,0,0,.08); } .custom-tabs .tab-title { padding:.5rem 0; cursor:pointer; position:relative; color:inherit; opacity:.7; } .custom-tabs .tab-title.active { opacity:1; } .custom-tabs .tab-title.active::after { content:""; position:absolute; left:0; right:0; bottom:-1px; height:2px; background: currentColor; } .custom-tabs .tab-panels .tab-pane { display:none; } .custom-tabs .tab-panels .tab-pane.active { display:block; } .asp-cat-list, .asp-pages-list, .asp-other-list { list-style:none; padding:0; margin:0; } .asp-cat-item { display:flex; align-items:center; gap:.5rem; margin:0 0 12px; } .asp-cat-item img { width:40px; height:40px; object-fit:cover; border-radius:4px; }As always, test it, change it, improve it. Do not blindly use it haha. Maybe someone can use it as their base to make their own template.
info_piT4
ParticipantWell, made a first attempt, with the help of your lovely knowledgebase and ai question input field. And a bit of my AI assistant to clean it up and help me.
I made a search.php
<?php get_header(); global $asp_cats, $asp_products, $asp_pages, $asp_other; $search_query = get_search_query(); $p_asid = isset($_GET['p_asid']) ? (int) $_GET['p_asid'] : 0; $asp_active = isset($_GET['asp_active']) ? (int) $_GET['asp_active'] : 0; // Alleen ASP gebruiken als markers kloppen (pas 8 aan als jouw instance anders is) $use_asp = ($asp_active === 1 && $p_asid === 8); // Safeguards $asp_cats = is_array($asp_cats) ? $asp_cats : []; $asp_products = is_array($asp_products) ? $asp_products : []; $asp_pages = is_array($asp_pages) ? $asp_pages : []; $asp_other = is_array($asp_other) ? $asp_other : []; ?> <div class="custom-search-results-container"> <div class="container"> <div class="search-header"> <h1 class="search-title"> <?php echo $search_query ? sprintf( esc_html__('Search Results for: "%s"', 'textdomain'), esc_html($search_query) ) : esc_html__('Search Results', 'textdomain'); ?> </h1> <div class="search-form-wrapper"> <?php echo do_shortcode('[wpdreams_ajaxsearchpro id=8]'); ?> </div> </div> <?php if (!$use_asp): ?> <p><?php _e('Ajax Search Pro is not active on this request (missing asp_active=1 & p_asid).', 'textdomain'); ?></p> <?php else: ?> <div class="search-results-columns"> <!-- LEFT: Categories --> <div class="search-col categories-col"> <?php if (!empty($asp_cats)): ?> <h2><?php _e('Product Categories', 'textdomain'); ?></h2> <ul class="category-list"> <?php foreach ($asp_cats as $c): ?> <?php $name = $c->title ?? ''; $link = $c->link ?? '#'; $thumb = $c->image ?? ''; ?> <li class="category-item"> <a href="<?php echo esc_url($link); ?>"> <?php if ($thumb): ?> <img src="<?php echo esc_url($thumb); ?>" alt="<?php echo esc_attr($name); ?>"> <?php endif; ?> <span><?php echo esc_html($name); ?></span> </a> </li> <?php endforeach; ?> </ul> <?php endif; ?> </div> <!-- RIGHT: Products + Pages --> <div class="search-col products-pages-col"> <?php if (!empty($asp_products)): ?> <h2><?php _e('Products', 'textdomain'); ?></h2> <div class="products-grid"> <?php foreach ($asp_products as $p): ?> <?php $title = $p->title ?? ''; $link = $p->link ?? '#'; $img = $p->image ?? ''; $price_html = ''; if (!empty($p->id) && function_exists('wc_get_product')) { $product_obj = wc_get_product((int)$p->id); if ($product_obj) $price_html = $product_obj->get_price_html(); } ?> <div class="product-card"> <a href="<?php echo esc_url($link); ?>"> <?php if ($img): ?> <img src="<?php echo esc_url($img); ?>" alt="<?php echo esc_attr($title); ?>"> <?php endif; ?> <h3><?php echo esc_html($title); ?></h3> <?php if ($price_html): ?> <div class="product-price"><?php echo wp_kses_post($price_html); ?></div> <?php endif; ?> </a> </div> <?php endforeach; ?> </div> <?php endif; ?> <?php if (!empty($asp_pages)): ?> <h2><?php _e('Pages & Posts', 'textdomain'); ?></h2> <ul class="pages-list"> <?php foreach ($asp_pages as $pg): ?> <li> <a href="<?php echo esc_url($pg->link ?? '#'); ?>"><?php echo esc_html($pg->title ?? ''); ?></a> </li> <?php endforeach; ?> </ul> <?php endif; ?> </div> </div><!-- /columns --> <?php if (!empty($asp_other)): ?> <div class="search-section other-results"> <h2><?php _e('Overige resultaten', 'textdomain'); ?></h2> <ul class="other-list"> <?php foreach ($asp_other as $o): ?> <li><a href="<?php echo esc_url($o->link ?? '#'); ?>"><?php echo esc_html($o->title ?? ''); ?></a></li> <?php endforeach; ?> </ul> </div> <?php endif; ?> <?php endif; ?> </div> </div> <?php get_footer(); ?>' The instance has ID 8 by the way put this in the functions.php// Zet deze op true als je een var_dump van de ASP-results wilt
add_filter(‘asp_results’, function($results, $id) {
if ($id != 8) return $results; // Alleen search instance ID 8 gebruikenglobal $asp_cats, $asp_products, $asp_pages, $asp_other;
$asp_cats = $asp_products = $asp_pages = $asp_other = [];foreach ($results as $r) {
// Categorieën
if (
(isset($r->taxonomy) && $r->taxonomy === ‘product_cat’) ||
(isset($r->post_type) && $r->post_type === ‘product_cat’)
) {
$asp_cats[] = $r;
continue;
}// Producten
if (isset($r->post_type) && $r->post_type === ‘product’) {
$asp_products[] = $r;
continue;
}// Pagina’s of blogposts
if (isset($r->post_type) && in_array($r->post_type, [‘page’, ‘post’], true)) {
$asp_pages[] = $r;
continue;
}// Rest = overige resultaten
$asp_other[] = $r;
}return $results; // Nodig zodat ASP verder werkt
}, 10, 2);’And CSS
`/* Custom Search Results Page Styles */
/* Container grid */
/* 2 kolommen lay-out */
.custom-search-results-container .search-results-columns {
display: grid;
grid-template-columns: 25% 1fr;
gap: 2rem;
align-items: start;
}/* Lists reset & basis */
.custom-search-results-container .category-list,
.custom-search-results-container .pages-list,
.custom-search-results-container .other-list {
list-style: none;
margin: 0;
padding: 0;
}/* Categorieën links */
.custom-search-results-container .category-item {
display: flex;
align-items: center;
gap: .5rem;
margin: 0 0 12px;
}
.custom-search-results-container .category-item img {
width: 40px; height: 40px;
object-fit: cover; border-radius: 4px;
}/* Product grid rechts */
.custom-search-results-container .products-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px,1fr));
gap: 1.5rem;
}
.custom-search-results-container .product-card img {
width: 100%; height: auto; display: block; border-radius: 4px;
}
.custom-search-results-container .product-card h3 {
font-size: 1rem; margin: .5rem 0 0;
}
.custom-search-results-container .product-price {
margin-top: .25rem;
}/* Secties spacing */
.custom-search-results-container .search-section { margin: 0 0 2rem; }
.custom-search-results-container .search-section h2 { margin: 0 0 1rem; }/* Overige resultaten klein & subtiel */
.custom-search-results-container .other-results { font-size: .9rem; color: #666; }
.custom-search-results-container .other-results h2 {
font-size: 1rem; margin-bottom: .5rem; color: #999;
}/* Responsief */
@media (max-width: 992px) {
.custom-search-results-container .search-results-columns {
grid-template-columns: 1fr;
}
}’Somehow my xstore theme kept going back to the normal wp results.
I still have to tweak it, and maybe I’ll put it back into an Elementor grid or loop.
It could also be that I made a mess of my code because a few full days of trying made me cross eyed.Sorry.I’m open for suggestions. this is on my staging by the way, not on production 😉
info_piT4
ParticipantThank you for your answer. I’m quite stubborn so I’ll try to make it work. Do you have working examples/sites of those who do made it work?
Thanks in advance for your time .
-
This reply was modified 9 months, 2 weeks ago by
-
AuthorPosts