This website uses cookies to personalize your experience. By using this website you agree to our cookie policy.

Forum Replies Created

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • in reply to: Spam in Search statistics #57156
    info_piT4info_piT4
    Participant

    You cannot access this content.

    in reply to: Double result category in live results #56369
    info_piT4info_piT4
    Participant

    You cannot access this content.

    in reply to: Double result category in live results #56365
    info_piT4info_piT4
    Participant

    You cannot access this content.

    in reply to: Double result category in live results #56360
    info_piT4info_piT4
    Participant

    Nope, scroll down in the live results (don’t know if you can see it in the video, but here we go)

    in reply to: wp-admin search? #55898
    info_piT4info_piT4
    Participant

    Ah bummer, thanks for replying so quickly though!

    in reply to: Creating a results page (not live filtering), sorted #55362
    info_piT4info_piT4
    Participant

    You cannot access this content.

    in reply to: Cannot find option to translate ¨Results From..” #55340
    info_piT4info_piT4
    Participant
    in reply to: Creating a results page (not live filtering), sorted #55338
    info_piT4info_piT4
    Participant

    You cannot access this content.

    in reply to: Creating a results page (not live filtering), sorted #55319
    info_piT4info_piT4
    Participant

    Question. 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.

    in reply to: Creating a results page (not live filtering), sorted #55273
    info_piT4info_piT4
    Participant

    I got an error when posting my code, so I hope you can see the message above

    in reply to: Creating a results page (not live filtering), sorted #55261
    info_piT4info_piT4
    Participant

    Double entry

    • This reply was modified 9 months, 2 weeks ago by info_piT4info_piT4. Reason: Double
    in reply to: Creating a results page (not live filtering), sorted #55260
    info_piT4info_piT4
    Participant

    Ok 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.

    in reply to: Creating a results page (not live filtering), sorted #55194
    info_piT4info_piT4
    Participant

    Well, 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 gebruiken

    global $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 😉

    in reply to: Creating a results page (not live filtering), sorted #55178
    info_piT4info_piT4
    Participant

    Thank 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 .

Viewing 14 posts - 1 through 14 (of 14 total)