• Hi All,

    i’m looking for two pieces of code that can help me with the following:

    I got posts and pages with a custom menu. These posts/pages got a custom template activated. The templates contains the menu for the specific posts and pages. This way i can order pages/posts in two different categories.

    Now i like to change the search function; the search output should be based on the active custom menu category.

    I named menu 1: Benelux and menu 2: International

    1: First peace of code needs to be for the searchform.php
    The code should look at the current active menu(category) and the search result should be based on the active menu.

    If the menu is for example “Benelux” then the search result should only display pages/posts from the custom taxonomy that i made <input type=”hidden” name=”location” value=”benelux” />
    Or if the active menu is “International” then display pages/posts from the custom taxonomy <input type=”hidden” name=”location” value=”international” />

    I found the following code to get the menu category…not sure if this is useful..

    (wp_nav_menu( array(
        'menu' => 'benelux'
    ) )

    2: Second peace of code is needed for the search.php (header).
    Because if the output should work correctly than we also need to change the menu for this search result page. Default the search.php uses the main menu.

    So the following code needs to see if the pages/post contain taxonomy benelux or international and change the menu accordingly.

    It would just be really awesome if this is possible.

    Greatings,
    Taro

Viewing 15 replies - 1 through 15 (of 152 total)
  • Moderator bcworkz

    (@bcworkz)

    I’m not able to offer precise code, but I can tell you what needs to happen with simple examples.

    Code pages like searchform.php that are included in other code pages (usually with get_template_part()), cannot directly know what page has included it. You need to help it out. One way is on the main template set a constant or static variable that establishes the template’s purpose in PHP namespace. Then on the search form, set the hidden field’s value to that same constant.

    For example, on benelux.php there would be define('REGION', 'benelux');
    Then on searchform.php you would have this: <input type="hidden" name="location" value="<?php echo REGION; ?>" />

    On the results page, you can get the taxonomy term of a custom taxonomy like so: get_query_var('my-taxonomy-slug'); . Thus you could output the associated menu with

    wp_nav_menu( array(
        'menu' => get_query_var('my-taxonomy-slug'),
    )

    Of course the constant value needs to be carefully coordinated with taxonomy terms and menu names, or some sort of equivalence measure needs to be used, such as a lookup array or switch/case structure.

    When you start modifying theme templates you should create a child theme to contain your custom code so it is protected when the theme is updated.

    Thread Starter Taro

    (@sicktb)

    I think there is one problem with this option.

    If i for example search for “event” than i get 2 posts with the word event in it. But one post has the template <?php define(‘REGION’, ‘benelux’); ?> in it and the other template has <?php define(‘REGION’, ‘international’); ?> in it.

    If i change the results page (search.php) and associate it with an menu… it can’t choose…

    info:
    the theme uses <?php get_template_part( ‘content’, ‘search’ ); ?>

    I use a switch/case structure for all menus/templates on pages/posts

    Child theme active ??

    Moderator bcworkz

    (@bcworkz)

    Yes, I see. Some refinement is needed. Use PHP’s defined() function to check for REGION being defined before attempting to output the search form’s hidden field. The code that constructs the search query then should not use region as a criteria if the ‘location’ parameter is missing because the chosen region is not yet known.

    The region is only known once a post with the proper single template is chosen. Once it is known, then future searches are restricted by region because REGION is defined.

    I’m not completely sure this solution fits your intended user experience or not. If not, please explain further and I’ll try to think of a solution.

    Thread Starter Taro

    (@sicktb)

    I think the function “REGION” is based on; example if your from the USA then you get a certain output etc

    But the category that i use “Benelux” and “International” could also be “cars” and “bikes”. Or maybe i just don’t understand the function REGION yet…

    The code that constructs the search query then should not use region as a criteria if the ‘location’ parameter is missing because the chosen region is not yet known.

    The menu category is already known. When i’m on a page with the “Benelux” menu active. And use the search option in the widget it can already define the current menu. When the search results are loaded on the search result page. I should stay on the previous defined menu(category).

    Moderator bcworkz

    (@bcworkz)

    Maybe a defined REGION constant is not the best approach. I’m not fully comprehending how your user experience is supposed to work. I do know that a search query cannot directly know what menu is loaded unless there is some common element like a defined constant. But there’s many ways to have a common element, such as cookies, globals, static variables, transients, session variables and so forth.

    I personally question if it’s ideal to “auto-detect” a search parameter. As a user, I think I’d rather have the option of selecting the search region, by way of a dropdown field for example. You could still have code that auto-selects the current region so users can ignore the field if they want to. With a visible field they then know that their search is restricted to the shown region, and they always have the option of selecting a different region or searching all regions if they’re so inclined.

    Thread Starter Taro

    (@sicktb)

    I think it’s easier if i would send you a preview link. But i can’t post it here. Can i send you a mail or got skype? My skype is Taro van Gelderop.

    Isn’t the the common element the menu category?

    The drop down field is not an option. I don’t want the user to change easily back to a other part of the website. They can select benelux or international from the home page only.

    Moderator bcworkz

    (@bcworkz)

    OK, you don’t like my idea. That’s fine, it’s your site after all. None of my business anyway ??

    I meant there is no function like get_menu_category() for use in the form fields. However, what ever code establishes which menu is displayed can also establish the search parameter, it’s just a matter of how to manage the data between the menu output and the form output. Widgets have limited variable scope, but any of the common elements I mentioned earlier could work.

    In a set template like benelux.php, establishing the search parameter is straight forward. It’s your example of mixed search results that I don’t understand. If you have mixed results then the region has not been established yet. How is the region established? By viewing a particular post? Whatever it is, some common element should be set at that time so that same element can determine the search parameter. If that element is not set, the the region has not been established and the region form field should not be output.

    I’m not convinced a demo link will help much because I can’t see the PHP, but who knows? Skype doesn’t work well for me, I have significant connectivity issues. You can send a message to my gmail account, the username is similar to mine here, but different: bcworks — a ‘s’ instead of ‘z’. But lets keep our discussion here, we never know what might help someone else landing here through search results. I’ll be away for a couple days now, so any further response from me will not be any time soon.

    Moderator bcworkz

    (@bcworkz)

    Hi Taro,

    I’m back, as you can see. I took a look at your site. Thanks for the link, it was helpful! (And now I see why you hated my other idea ?? ) It appears to me that the region always appears in the URL. If that is the case, it should be available in the main query object. You should dump out the object to confirm this. If true, you can get the main query when the search form is output with get_query_object(). Be sure the object returned is really the main query with $query->is_main_query(). It should be. If not, some other code doing a custom query neglected to restore the main query when it was finished. I’m not sure where in the query the region would occur, you can determine that when you dump out the query object.

    If that approach should fail for some reason, go back to the store the region in some common element approach. You can set that element’s value on the entry page where the user selects which ‘site’ they want to enter. Or perhaps with code placed on whatever the next page is.

    Thread Starter Taro

    (@sicktb)

    Hi Bcworkz,

    i have to split your reply in to steps. I’m not a php programmer, and it’s hard for me to understand.

    It appears to me that the region always appears in the URL. If that is the case, it should be available in the main query object. You should dump out the object to confirm this.

    I tryed to dump out the object with:

    <?php
     $queried_object = get_queried_object();
     var_dump( $queried_object );
     ?>

    this is what i get on a page with the benelux template:
    object(WP_Post)#279 (24) { [“ID”]=> int(2027) [“post_author”]=> string(1) “1” [“post_date”]=> string(19) “2015-10-23 07:32:45” [“post_date_gmt”]=> string(19) “2015-10-23 07:32:45” [“post_content”]=> string(7070) ”

    Moderator bcworkz

    (@bcworkz)

    Ah crap. My bad. We need the current query not queried object. My apologies.

    On a template file this should work:

    global $wp_query;
    echo '<pre>';
    if ( $wp_query->is_main_query()) vardump( $wp_query );
    echo '</pre>';

    The <pre> tags just format the output nicely so you don’t need to look at page source to see the proper format.

    Thread Starter Taro

    (@sicktb)

    Im getting the following: (changed vardump to var_dump)

    pastebin

    Thread Starter Taro

    (@sicktb)

    There is more code on the site. But i rather not copy it here. It’s in on benelux/about page

    Moderator bcworkz

    (@bcworkz)

    vardump! Arrrgh. Sometimes I can’t seem to get anything right ??

    Anyway, it appears the only region reference currently is $query->query->pagename. You can extract the region part by using explode(). You could get the region to show up as a query var by using add_rewrite_rule() to pickup the first permalink term and rewrite it as an URL parameter. If you do that, use the ‘query_vars’ filter to add your query var to the whitelist so it shows up in the query_var terms.

    Thread Starter Taro

    (@sicktb)

    ok i made a test page (link/benelux/sample)

    <?php
    global $wp_query;
    echo ‘benelux : ‘ . $wp_query->query_vars[‘benelux’];
    ?>

    that is not working… I got no clue where to start changing code or what kind of code i need. I found some pages with snippet of code…

    Rewrite rule

    and this

    Moderator bcworkz

    (@bcworkz)

    There’s several elements involved. Most of it goes on functions.php or on some plugin code page. The first element is the rewrite rule. Your current URL is something like example.com/benelux/page-name/ . The rewrite goal is to transform that URL into example.com/index.php?pagename=page-name&region=benelux

    The rewrite rule could be something like add_rewrite_rule('^([^/]*)/([^/]*)/?','index.php?pagename=$matches[2]&region=$matches[1]','top'); (untested). Call this from a callback to the ‘init’ action. Toggle your permalink settings to none, then back again to force the rules to regenerate.

    In order for $wp_query->query_vars['region'] to work, ‘region’ needs to be whitelisted with the ‘query_vars’ filter. If your callback collects the passed array with $vars, just do $vars[] = 'region'; before returning the modified array.

    That all sets things up so you can output the form field with something like this:

    global $wp_query;
    $region = $wp_query->is_main_query()? $wp_query->get('region') :'';
    echo "<input type='hidden' name='region' value='$region'>":

    Then whatever code processes the form submittal needs to get the region value from $_POST['region'] and use it to construct a proper search query. Exactly how this is done depends on how the region for any given post is stored. If it’s as a category, the query could be something like this:

    $args = array(
      's' => $_POST['s'],
      'category_name' => $_POST['region'],
    );
    $posts = get_posts( $args );

    In practice you would never use $_POST in an arguments array. Every form field must be validated and sanitized before it is used. Before that you need to be sure the parameter even exists with isset() and if the field is due to user input, use stripslashes() just in case their content includes quotes or apostrophes, like one that occurs in O'Reilly.

Viewing 15 replies - 1 through 15 (of 152 total)
  • The topic ‘Search result based on menu category’ is closed to new replies.