Goal/Information
I'm trying to set up a custom search field and custom search results page to display one category of pages. I need these results on a separate, custom search results page so I can customize how the results are displayed without affecting the default search.
For context, I'm setting up a gallery where the user can search for keywords and relevant pages will be displayed as a thumbnail grid, with each thumbnail linking to a page containing more information on the image.
Each page, containing the image and information, is set up as a page (not post) under the category images.
I'm not sure this is relevant, but in a previous project I've set the default search to exclude images pages with the following code in my functions.php (category ID is 30). I've tried removing this code and it didn't affect my problem described below.
/* Exclude a Category from Search Results */
add_filter( 'pre_get_posts' , 'search_exc_cats' );
function search_exc_cats( $query ) {
if( $query->is_admin )
return $query;
if( $query->is_search ) {
$query->set( 'category__not_in' , array( 30 ) ); // Cat ID
}
return $query;
}
What I've Tried
I'm still learning php and have spent many hours on this to no avail. Most recently I tried tweaking some code from this similar question.
My resultant custom search form looks like this:
<form class="search-form" action="<?php echo home_url( '/' ); ?>" method="get">
<input name="s" type="text" placeholder="Search Images" />
<input name="post_type" type="hidden" value="page" />
<input name="category_name" type="hidden" value="images" />
<input alt="Search" type="submit" value="Search" />
</form>
I've added the following code to the top of my search.php to attempt to redirect to another results page, in this case search-page.php, if the post type has been specified:
<?php
// store the post type from the URL string
$post_type = $_GET['post_type'];
// check to see if there was a post type in the
// URL string and if a results template for that
// post type actually exists
if ( isset( $post_type ) && locate_template( 'search-' . $post_type . '.php' ) ) {
// if so, load that template
get_template_part( 'search', $post_type );
// and then exit out
exit;
}
?>
Note: I took this directly from the similar question linked above.
I've duplicated search.php into search-page.php, removing the code above from the latter.
Problem
Now let's do a search in the custom form above for "marble" (a term featured in one of the image pages). The URL looks right (http://example.com/%3C?s=marble&post_type=page&category_name=images), but I get a 404. In addition, normal searches (those not in the custom form) now take me to a white page – not even a 404. When I remove the above code from functions.php, the default search works properly. (Custom search still 404s.)
Other Attempts
I've also read this guide from Smashing Magazine a few times – Building An Advanced WordPress Search With WP_Query – but can't quite pick out the information relevant to me.
I've tried a couple dozen other guides and questions, but most of them deal with searching for a specific post type alone (and not a category) or searching from a radio-button selection of categories. I haven't been able to scrape any working solutions from them.
Are there any tweaks to what I've tried – or completely different solutions altogether – that will help achieve the desired effect? Specifically, how to create a custom search form for one type of page category, leading to a customizable, separate search results page (independent from the default search results page).
Thanks in advance.
Related
I want to get the result in search.php include posts and products only, and the posts list will be display in POST tab, Products list in PRODUCT tab.
I tried to use this code for loop but it get all posts and products:
<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php endwhile;?>
<?php endif; ?>
You may want to try adding a post_type argument to the URL.
www.example.com?s=test&post_type=product (shows products)
www.example.com?s=test&post_type=page (shows pages)
This is not exactly what you are asking because this is 2 separate pages (not 1 page with 2 tabs). You can add a hidden input field to a form in order to have the browser automatically append the post type to the URL. Ie.
<form method="get" action="<?= get_bloginfo( 'url' ); ?>">
<input type="hidden" name="post_type" value="product">
<input type="text" name="s" value="<?= get_search_query(1); ?>" placeholder="Search Products...">
<button type="submit">Go</button>
</form>
To show 2 tabs on the same page, you can use search.php and ignore the main query, and simply write two of your own queries by accessing $_GET['s'] (the function, get_search_term(), also accesses $_GET['s'] but can also sanitize it). Alternatively, you could use a page template to write your own queries, showing search results on a different URL (you would have to modify all search forms to go here instead).
When you visit your websites home URL and add ?s= to the URL, WordPress knows to serve search.php and run a "main query" (using WP_Query) behind the scenes. The main query is what you are looping through when you call while( have_posts() ) etc.
Writing your own queries to show search results may make your code less compatible with plugins that modify the main query to show more meaningful search results. It depends on how they do the logic of whether or not to modify a specific query. For example, they may check that the query is a main query and that you are on the search.php page. When you write your own queries using WP_Query or get_posts(), it's not a main query anymore.
WP_Query (or get_posts() which calls WP_Query) should have an argument where you can specify the search term(s) and it may take care of parsing out all the different words and turning it into (somewhat) useful SQL. You should read the docs on WP_Query for more info.
Sorry this is not a full answer but perhaps it will lead you in the right direction.
I have added a custom taxonomy to Users - user categories.
Using the code below, I am able to output the custom taxonomies in each edit-user profile page:
function show_user_category( $user ) {
//get the terms that the user is assigned to
$assigned_terms = wp_get_object_terms( $user->ID, 'user_category' );
$assigned_term_ids = array();
foreach( $assigned_terms as $term ) {
$assigned_term_ids[] = $term->term_id;
}
//get all the terms we have
$user_cats = get_terms( 'user_category', array('hide_empty'=>false) );
echo "<h3>User Category</h3>";
//list the terms as checkbox, make sure the assigned terms are checked
foreach( $user_cats as $cat ) { ?>
<input type="checkbox" id="user-category-<?php echo $cat->term_id ?>" <?php if(in_array( $cat->term_id, $assigned_term_ids )) echo 'checked=checked';?> name="user_category[]" value="<?php echo $cat->term_id;?>"/>
<?php
echo '<label for="user-category-'.$cat->term_id.'">'.$cat->name.'</label>';
echo '<br />';
}
}
The code above simply displays a list of checkboxes, ordered by term_id.
Of course, I want to display them in the same way that custom taxonomy terms would be displayed in a custom post type (a scrollable list of checkboxes, with child terms indented and underneath their parent term). The code above does not display the terms in order of parents/children.
Is there a WP function I can pass my taxonomy & terms to, to create what I described in the paragraph above? Or do I have to do it manually?
Thanks
Short answer:
Yes, there are. They are called post_categories_meta_box() and post_tags_meta_box(), depending on the type of taxonomy you are using.
Long answer:
This is the sort of question that can be answered by inspecting the WP core code.
Here's the walk-through on how I did it to answer this question:
Editing a page in admin results in a url of wp-admin/post.php. So, inspect that file (post.php).
A quick search in that file for "tax" results in nothing, so we can at least look at the case 'edit' section, because we know we're doing an edit. And we can see it includes a file edit-form-advanced.php.
So, inspect that file (edit-form-advanced.php)
A quick search for "tax" gets into an area that looks promising.
Here we see they call get_taxonomy, and then that get_taxonomy object that is returned has a callback called meta_box_cb - so do a cross-file search for that. We find several instances, but the instance in taxonomy.php is the most promising (because of the file name), so lets look there.
It appears (around line 430 of taxonomy.php) that there's a pair of callback functions - post_categories_meta_box and post_tags_meta_box that WP core is using. Let's check them out - do a cross-file search for function post_categories_meta_box, and we find both of these functions exist in the file meta-boxes.php. The comments for the functions are excellent, and tell us what you are asking: "Display post categories form fields".
Armed with this information, we can ask Google, and we find the WP documentation for the functions:
post_categories_meta_box
and
post_tags_meta_box
This question is based on an unanswered question in Wordpress Development which has not gotten a solid answer.
I have a wordpress website which lists hotels. the url for a single hotel looks like:
/hotels/the-marriot-hotel
I also have a custom taxonomy for Locations, which allows me to browse the hotels in various locations, which works fine, the urls are like:
/Locations/Liverpool
For URL's like /hotels/* I would like to use a custom template, which I have done already and works fine.
The Problem
I also want to be able to drilldown the Locations taxonomy creating a breadcrumb type URL and also use a different template for the hotel page.
For Example, if a user is browsing /Locations/Liverpool and clicks the Marriot Hotel I would like it to click through to /Locations/Liverpool/the-marriot-hotel instead of /hotels/the-marriot-hotel and also use a slightly different template, which can also load a different sidebar and recommend other hotels in the area specific to the location slug in the URL
So basically I want two routes to a single post and a different template used based on the route used.
How would I go about implementing this?
What have I tried?
I've tried adding a new page and using a rewrite rule to point to it to be the locations hotel page.
I've tried adding a slug on the end of the /Locations/{location-slug} url and reading this in the page template and loading the hotel post instead of the list it doesn't seem to be working but also feels like a terrible hack anyway
An idea that I've had is to add a rewrite to the hotels/{slug} page and using code to detect the URL used and switch templates dynamically but I'm not sure this is the best approach
I have managed to get this working using the second method mentioned above (adding a rewrite to the locations landing page and checking for a query_var).
I will post the code below that I used but although this works and seems to be working very well, It does not feel like the best way of doing it. If someone know of a better way of doing this please post the answer.
I used this online post for reference.
Note: The listing page shows the list of hotels in the taxonomy in a side column down the side and shows the currently selected or a random one in the main content area. Which will explain how I am using the loop below.
function prefix_locations_rewrite_rule() {
add_rewrite_rule( 'Locations/([^/]+)/([^/]+)', 'index.php?locations=$matches[1]&hotel=$matches[2]', 'top' );
}
function prefix_register_query_var( $vars ) {
$vars[] = 'hotel';
return $vars;
}
function prefix_url_rewrite_templates() {
if ( get_query_var( 'hotel' ) && is_singular( 'hotel' ) ) {
add_filter( 'template_include', function() {
return get_template_directory() . '/taxonomy-locations.php';
});
}
}
add_action( 'template_redirect', 'prefix_url_rewrite_templates' );
add_filter( 'query_vars', 'prefix_register_query_var' );
add_action( 'init', 'prefix_locations_rewrite_rule' );
In my template file for the hotels landing page:
$hotelSlug = get_query_var( 'hotel', false);
if ( have_posts() ) {
while (have_posts()) : the_post();
if ($post->post_name == $hotelSlug) {
break;
}
endwhile;
}
This bit of code will iterate over the posts and if the hotel slug matches the query var it will break there so that the current post is the one we wanted.
We could just use a query here but as I already have a list of posts within the taxonomy I thought I'd just iterate over it. Below this I check to see if a specific hotel has been selected otherwise I show a random one from the list.
I am still to add additional logic and error handling to this code, I hope it helps someone with a similar issue
I have search.php in my WordPress theme, search result is generating fine using The Loop.
What I see is some post don't have content(blank post with title only), and they still appear in search result. Which is quite obvious, but I want only to list post which has some content.
If post don't have any content it should not list in Search Result even if its title has a Search Term.
I believe you won't need to see code to understand my concern. I tried searching for this answer on all known resources, nothing found exactly.
Down vote won't help me.
Inside your search loop try adding this:
global $post;
if ( $post->post_content != '' ) {
// Display this post because it has content.
} else {
// This post has empty content so do not display it.
}
i want to display my custom terms from tags, even the code is valid in front of me but it gives the fatal error i use this code
<p style="width:50%;float:left;">
<?php $dataTax = get_the_term_list($post->ID, 'genre', '', ', ', '');
$dataMeta = get_post_meta($postID, 'genre', true);
if ((!empty($dataTax)) || (!empty($dataMeta))){ ?>
<span class="data-info">Genre:<span itemprop="genre"></span></span>
<?php if ($dataTax != ""){
// strip links until we're ready to use the taxonomy pages in the future
echo strip_tags($dataTax);
} else {
echo $dataMeta;
}
} ?>
</p>
"genre" is my taxonmy ,i want to dispaly their values,but it give me this type of error
Genre:
Catchable fatal error: Object of class WP_Error could not be converted to string in
Any help plz
I think that's the problem - something to do with deleting custom taxonomies when there are links in the Nav Menu which link to/are related to those now-missing taxonomies.
I read a post somewhere describing the exact problem, and this guy had spent a considerable amount of time trying to fix the problem without success. In the end he had fixed it by resetting WP back to a clean state (I assume a default database), which will of course result in complete loss of site data.
I would imagine there's a fix by delving into the database, but I've not explored this as the error I had was none-critical (on a localhost test site).
I keep on getting this problem, or related problems. Basically it happens whenever I rename a custom taxonomy or custom posts. I'm using the Custom Post Type UI plugin, and I created a load of custom posts & taxonomies. I then decided to change the name of some of the taxonomies from sentence case to lowercase, and this is where it screwed various plugins (e.g. Query Multiple Taxonomies) and the wp-menu (Appearance / menu). When I changed the name of some of the taxonomies back, everything started working ok again (although had to delete the query multiple taxonomies widget, and add it back in again).
Bottom line seems to be, once you've created your custom posts/taxonomies, don't alter them.
Deleted a menu that you had created in another theme would somehow fix it if you done this.
Kinda lame solution, but works as a charm.
Some solutions from wordpress forums.
http://wordpress.org/support/topic/catchable-fatal-error-object-of-class-wp_error-could-not-be-converted-to-string-11
Replace line
echo strip_tags($dataTax);
with
print_r($dataTax);
and if you get something like: "WP_Error Object ( [errors]......"
check is "genre" a right name of $taxonomy