I have a custom post type called 'property' with an archive of '/property'.
Within this I use the standard 'tag' taxonomy to apply a tag of 'sold' to sold properties.
I would like to add a simple filter on the archive pages whereby a user can click a button called 'Exclude Sold' and this would display the same 'property' archive but without any posts/properties containing the 'sold' tag. This needs to reload the page when the user clicks the button.
e.g. if the standard 'property' archive is:
domain.com/property
Then the exclude would look something like: (this would show all the properties WITHOUT the 'Sold' tag)
domain.com/property/?&tag=NOTsold
Ideally I need this to append the current URL being viewed so that it works for any other term archives too (I have other taxonomies under the post type for location, and more...), and search pages too.
e.g.
Search example: (this would show all the apartments WITHOUT the 'Sold' tag)
domain.com/property/?s=apartments&tag=NOTsold
Location taxonomy example: (this would show all the properties in london WITHOUT the 'Sold' tag)
domain.com/property/london/?&tag=NOTsold
It would be great if this was also reversible so that once excluded, the button could change to 'Include Sold' and if clicked this would remove the filter (reload the page when button is clicked, without the filter)
John Cotton answers:
I assume you know how to make the links?
If so, then all you need at the top of your archive page (prior to your loop) is some code like this:
global $wp_query;
$tag = array();
if( isset($_GET['NOTsold']) ) {
$tag = array( 'tag__not_in' => array( 1 ) ); // change for your sold tag id
}
query_posts(array_merge( $wp_query->query, $tag ) );
John Cotton comments:
The array_merge is important in that it will retain any other parameters set by the current page.
robster comments:
Hi John,
The function is working but it doesn't seem to append the URL for a search for some reason - any ideas?
Other archives (tags, taxonomies, etc.) seem to be working just fine and the ?NOTsold is added to the end of the current URL when the button is clicked, but for a search, the URL is stripped and the ?NOTsold is added to the base URL - domain.com?NOTsold
My current link is:
<a href="?NOTsold" title="Exclude Sold" alt="Exclude Sold">Exclude Sold</a>
And the full function I have:
function sold_filter() {
global $wp_query;
$tag = array();
if( isset($_GET['NOTsold']) ) {
$tag = array( 'tag__not_in' => array( 33 ) ); // change for your sold tag id
}
query_posts(array_merge( $wp_query->query, $tag ) );
}
add_action('thesis_hook_before_html', 'sold_filter');
Also when the function is active, how would I display the opposite button?
e.g. a conditional statement something like "if url contains 'NOTsold', show 'Include Sold' button, otherwise show Exclude Sold button"
John Cotton comments:
<blockquote>The function is working but it doesn't seem to append the URL for a search for some reason - any ideas?</blockquote>
Yes - the search is a post. Change $_GET to $_REQUEST.
I should really have written
if( $_REQUEST['tag'] == 'NOTsold' ) {
to match your original querystring (and better reflect the convention of name/value pairs in the querystring).
<blockquote>Also when the function is active, how would I display the opposite button?
</blockquote>
You could put a wrapper around your button code to again test the request value and then just not add the tag/NOTsold parameter as - without it - the query posts will just return the default results ie those with everything in.
JC
robster comments:
Hi John,
if( $_REQUEST['tag'] == 'NOTsold' ) {
Doesn't seems to be working at all.
Rob
John Cotton comments:
<blockquote>Doesn't seems to be working at all.</blockquote>
Have you still got this style of link:
<a href="?NOTsold" title="Exclude Sold" alt="Exclude Sold">Exclude Sold</a>
If so, it should be
<blockquote>if( $_REQUEST['NOTsold'] ) {</blockquote>
but you would be better with links like this:
<a href="?tag=NOTsold" title="Exclude Sold" alt="Exclude Sold">Exclude Sold</a>
robster comments:
Thanks John,
Just about got this working now. Only thing i'm struggling with is the "Include Sold" button.
Is there a simple way to create links so that the link would strip the current URL of the "?NOTsold"...?
John Cotton comments:
<blockquote>Is there a simple way to create links so that the link would strip the current URL of the "?NOTsold"...?</blockquote>
I'm not sure what you mean....
The current url (ie in the address bar) is the one that's been requested so unless you redirect the user then that's what they will see. Links in your page (ie one to having solds back in) having little to do with the current address unless they are relative ones.
Just don't add the query string on for the "back to solds" list.
I suspect what your really getting at is a better way to handle the URLs. If it were me, I'd create custom urls like
domain.com/property/all
domain.com/property/unsold
etc so that I get some SEO value as well as making it tidy and clear to the user.
But that's another question.... :)
robster comments:
Hi John,
Sorry was just confusing the issue/myself!
Thanks for your help!
Francisco Javier Carazo Gil answers:
Hi Robster,
You can use tag_not_in, i. e.:
<?php
$args=array(
'showposts'=>10,
'offset'=>11,
'tag__in' => array('21'),
'tag__not_in' => array('20'),
);
query_posts($args);
while (have_posts()) : the_post(); ?>
STUFF
<?php endwhile; ?>
Kannan C answers:
<blockquote>The function is working but it doesn't seem to append the URL for a search for some reason - any ideas?</blockquote>
You should display the url by fetching the current url
in wordpress way,
<?php if(is_search()) echo '<a href="?s='.get_search_query().'¬sold">Exclude</a>'; ?>
Gabriel Reguly answers:
Hi Robster,
Why do you need to show sold properties? It is for admin only?
My approach would be addressing it at post status level
register_post_status( 'sold', array(
'label' => __( 'Sold', 'wp-imovel' ),
'protected' => true,
'show_in_admin_all' => true,
'show_in_admin_status_list' => true,
'show_in_admin_all_list' => true,
'hierarchical' => true,
'public' => true,
'label_count' => _n_noop('Vendido <span class="count">(%s)</span>', 'Vendidos <span class="count">(%s)</span>' ),
) );
Does it make sense to you?
Regards,
Gabriel