Is there any way to exclude a category from wp_get_archives? I'm trying to show the months in the sidebar, but I want to exclude the posts that are not blog entries.
$catID = get_cat_id('Projects');
$variable = wp_get_archives('type=monthly&show_post_count=1);
echo $variable;
Use this if you want to include only specific categories for wp_get_archive function in your functions.php of your theme directory
add_filter( 'getarchives_where', 'customarchives_where' );
add_filter( 'getarchives_join', 'customarchives_join' );
function customarchives_join( $x ) {
global $wpdb;
return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
}
function customarchives_where( $x ) {
global $wpdb;
$includes= '14'; // category id to include
return $x . " AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id = '$includes'";
}
You can write a filter in your functions.php file which will change wp_get_archive function's default behavior.
add_filter( 'getarchives_where', 'customarchives_where' );
add_filter( 'getarchives_join', 'customarchives_join' );
function customarchives_join( $x ) {
global $wpdb;
return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
}
function customarchives_where( $x ) {
global $wpdb;
$exclude = '1'; // category id to exclude
return $x . " AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id NOT IN ($exclude)";
}
Ran into this problem in a project but never found a solution online -- mine isn't the prettiest PHP, but it does the trick.
This is a play off the filter suggested by Katie, which I ran across in few support forums as well. This goes in your functions.php:
add_filter( 'getarchives_where', 'customarchives_where' );
add_filter( 'getarchives_join', 'customarchives_join' );
function customarchives_join( $x ) {
global $wpdb;
return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)
INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
}
function customarchives_where( $x ) {
global $wpdb;
$categories = get_terms( 'taxonomy-name', 'orderby=id' );
$includeIds;
$i = 0;
foreach($categories as $category) {
if($i != 0) $includeIds .= ',';
$includeIds .= $category->term_id;
$i++;
}
return $x . " AND $wpdb->term_taxonomy.taxonomy = 'taxonomy-name'
AND $wpdb->term_taxonomy.term_id IN ($includeIds)";
}
In the second function, swap taxonomy-name for the name of your actual custom taxonomy.
All the IDs of terms in your custom taxonomy are captured in a string; the rest operates the same as the original function -- only that list of categories from your custom taxonomy are included in the wp_get_archives() list. You can also tweak the code to exclude them as well (first example above).
If you only want one instance of the wp_get_archives() list to do this, just skip the top two lines of code in your functions.php that apply the filters. Then, when you use the wp_get_archives() tag, apply the filters before it, and remove them afterwards:
<?php
add_filter( 'getarchives_where', 'customarchives_where' );
add_filter( 'getarchives_join', 'customarchives_join' );
wp_get_archives();
remove_filter( 'getarchives_where', 'customarchives_where' );
remove_filter( 'getarchives_join', 'customarchives_join' );
?>
wp_get_archives() does not have a mechanism to exclude based on category -- it's purely for time-based archives (yearly, monthly, daily, weekly) or "every post" archives: postbypost or post by post ordered by post title.
There are different ways to work with category archives: WordPress › Support » Limit archives to category / date archives for category
I use Clean Archives Reloaded WordPress › Clean Archives Reloaded « WordPress Plugins and exclude categories around line 200:
// Get a simple array of all posts
$rawposts = get_posts( 'numberposts=-1&category=-4,-6,-7,-9' );
You might want to look in to get_categories and lean towards your own custom solution. While this may cost you a little more time and work; you will indeed get the upshot of having full control over what you're trying to achieve.
Place the code below just after
This code is working for me already :)
<?php
if ( $wp_query->is_archive ){
$wp_query->query_vars["cat"] = 14; // only the category that you want to inlcude
$wp_query->query_vars["posts_per_page"] = 10; // for number of posts you want
$wp_query->get_posts();}
?>
Can you use a filter hook on pre_get_posts instead?
I know something like this works for is_author, is_home, and is_feed...
function exclude_stuff($query) {
if ( $query->is_author) {
$query->set('cat', '-4, -142');
}
return $query;
}
add_filter('pre_get_posts', 'exclude_stuff');
depends on whether you can do it for something like is_archive or is_monthly
You would drop that in a php file with a plugin header:
<?php
/*
* Plugin Name: exclude some stuff
* Description: blah
* Author: blah
* Plugin URI: blah
* Version: 0.9
* =======================================================================
*/
Put the function here
?>
Then upload it to your Plugins directory and activate it.
There isn't an official way of doing this. But i tried and tested a lot of code block and only this one worked for me.
add_filter( 'getarchives_where', 'customarchives_where' );
add_filter( 'getarchives_join', 'customarchives_join' );
function customarchives_join( $x ) {
global $wpdb;
return $x . " INNER JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id) INNER JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)";
}
function customarchives_where( $x ) {
global $wpdb;
$include = 'your_category_id'; // category id to include
return $x . " AND $wpdb->term_taxonomy.taxonomy = 'category' AND $wpdb->term_taxonomy.term_id IN ($include)";
}
Replace your_category_id with an original id of your post category and the code will work.
Related
I'm developing a WordPress plugin in which I have created custom posts and used metadata to link them together.
On the admin side, I want to be able to filter posts list using those relations. I guess I would need to use INNER JOIN but I don't know how.
For now, all I have is:
add_filter( 'parse_query', 'mypostsfilteringfunction' );
function mypostsfilteringfunction( $query ){
// if post_type matches :
// then I need to be able to add innerjoin into $query
}
A achieve my goal by doing :
add_filter( 'parse_query', 'mypostsfilteringfunction' );
function mypostsfilteringfunction( $query ){
// if post_type matches :
add_filter( 'posts_join', 'myplugin_addjointorequest' );
add_filter( 'posts_where', 'myplugin_addwheretorequest' );
add_filter( 'posts_request', 'myplugin_sqlprint' ); // for printing result
}
function myplugin_addjointorequest ($join){
$join .= 'INNER JOIN ...';
return $join;
}
function myplugin_addwheretorequest ($where){
$where .= 'AND ...';
return $where;
}
function myplugin_sqlprint( $request ) {
echo $request;
return $request;
}
Is there a way to exclude a post from all of Wordpress' RSS feeds (the default one as well as tags, categories, and search feeds)?
Assuming you do not want to use plugins like THIS ONE or THIS, you have many ways :
One is to assign a category for the posts you would like to exclude and then you can just change the URL of the RSS link like so :
http://www.mydomain.com/feed?cat=-x,-y,-z
You can also FILTER with a function :
function o99_my_rss_filter($query) {
if ($query->is_feed) {
$query->set('cat','-7'); //Put category ID - here it is : 7
}
return $query;
}
add_filter('pre_get_posts','o99_my_rss_filter');
The point is that you will need to assign SOMETHING (tag, custom field, category) to identify what to exclude , assuming that you do not want always to add the ID to exclude from the query.
The easiest is by category as demonstrated above .
** Edit I **
Just for the sake of it - (I still recommend the cetegory method) r
Even if I dislike custom-fields when they are overused - this is another way that change the query by assigning a custom field :
function o99_my_rss_filter_by _field( $where, $wp_query = NULL ) {
global $wpdb;
if ( !$wp_query ) global $wp_query;if ( $wp_query->is_feed ) {
$posts = get_posts( array( 'meta_key' => 'norss' ) );
if ( $posts ) {
foreach( $posts as $post ) {
$exclude .= $post->ID . ',';
}
}
$exclude = substr( $exclude,0, strlen( $exclude )-1 );
$where .= ' AND $wpdb->posts.ID NOT IN ( ' . $exclude . ')';
}
return $where;
}
add_filter( 'posts_where', 'o99_my_rss_filter_by _field', 1, 4 );
I was wondering if there is a way using WP_Query (get_posts, etc) to return posts with an ID greater than one that is provided..
I've been through the WordPress codex and missed any reference to querying posts related to a post ID, if it's even possible without a custom query.
Since it doesn't seep possible to pass it through with the arguments, I've tried writing a method that modifies the posts_where filter but that doesn't seem to work either..
add_filter( 'posts_where', 'filter_since_id');
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
// Do Stuff
endwhile;
remove_filter('posts_where' , 'filter_since_id');
...
function filter_since_id($where = ''){
$where .= " AND ID > 3'";
return $where;
}
Clarified so that someone passing through can grab and go:
add_filter( 'posts_where', 'filter_since_id');
function filter_since_id($where = ''){
$where .= " AND ID > 3";
return $where;
}
I'm sorting my posts alphabetically by Title, like so:
<?php
{
$posts = get_posts($query_string .
'&orderby=title&order=asc&posts_per_page=-1');
}
get_template_part( 'loop', 'category' );
?>
I'd like to exclude articles such as "the", "a", and "an" from the sort.
What would be the best way to accomplish this?
Thanks!
I don't know any simple way to do that but you can do this,
For achieving this you need to add a custom meta field to the post. Name it mytitle (say).
For the new posts you add, it is simple, you have to add your modified title(removing a, an, the from the title) in the mytitle custom field in the add posts page.
For old posts it is a bit tricky, you have to write a php code to retrieve the titles of the post remove 'a','an','the' from them using php preg_replace and add it to the postmeta table of your wordpress database using something like this:
<?php //inside loop
$query=INSERT INTO xyz_postmeta (post_id, meta_key, meta_value) VALUES ($postid, 'mytitle' $title);
$wpdb->query('$query'); ?>
where $postid is the post id inside the loop and $title is your modified title.
Now you have updated all the previous posts with custom mytitle field.
Now to display, you have to use a custom loop (not the loop included in the theme).
Here is how you can make a basic custom loop to display posts sorted in order of mytitle.
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'mytitle'
AND wposts.post_type = 'post'
AND wposts.post_status = 'publish'
ORDER BY wpostmeta.meta_value ASC
";
Now you can execute the query by any means you want. Wordpres provides various methods to do so. Here's a link
For example you can do something like this
$pageposts = $wpdb->get_results($querystr, OBJECT);
foreach ( $pageposts as $pagepost )
{
echo $pagepost->post_title;
//do other stuff to display content, meta etc..
}
You can actually achieve this by manipulating the ORDERBY clause using the posts_orderby_request filter, and using TRIM to ignore articles "the", "a", and "an". Here's an example:
<?php
add_filter( 'posts_orderby_request', 'myproject_title_sort', 10, 2 );
/**
* Ignore opening articles when sorting by Title.
*
* #param string $orderby Order by parameter.
* #param WP_Query $query WP Query object.
*
* #return string
*/
function myproject_title_sort( $orderby, $query ) {
global $wpdb;
// Be sure to add a condition that matches your criteria (post type, archive, etc).
// In this example, we bail early if it's an Admin query, or not a main query.
if ( is_admin() || ! $query->is_main_query() ) {
return $orderby;
}
// This is another check to see if we're on a particular post type archive.
if ( ! $query->is_post_type_archive( 'my-post-type' ) ) {
return $orderby;
}
$title_col = $wpdb->posts . '.post_title';
// Check if we are sorting by post_title.
// You may need to use a separate `pre_get_posts` filter to sort by "title" if not already doing so.
if ( false === strpos( $orderby, $title_col ) ) {
return $orderby;
}
$ignore = "TRIM( LEADING 'the ' FROM LOWER( TRIM( LEADING 'a ' FROM LOWER( TRIM( LEADING 'an ' FROM LOWER( $title_col ) ) ) ) ) )";
$orderby = str_replace( $title_col, $ignore, $orderby );
return $orderby;
}
hello again from a far far away place.
you know i`m trying to list all of terms from a custom taxonomy , when i use below code :
$terms = get_terms($taxonomy , 'hide_empty=0');
print_r($terms);
$count = count($terms);
if ( $count > 0 ){
echo "<ul>";
foreach ( $terms as $term ) {
echo "<li>" . $term->name . "</li>";
}
echo "</ul>";
wp return a crazy error that says : INVALID TAXONOMY :
WP_Error Object
(
[errors] => Array
(
[invalid_taxonomy] => Array
(
[0] => Invalid Taxonomy
)
)
[error_data] => Array
(
)
)
it is very interesting that you know , when i use above code in single.php, i have not see any error and it works fine.
somebody please help me !
Resolved
I am trying to use:
get_terms( 'event_category', array('hide_empty'=>FALSE) );
to use my admin theme option and face same problem when using:
add_action( 'init', 'register_features_taxonomy_event_category' );
But now its resolved using:
add_action( 'after_setup_theme', 'register_features_taxonomy_event_category' );
get_terms return invalid taxonomy error because:
you have a custom taxonomy registered in the "init" hook
so in the wp-admin it doesn´t work -> your taxonomy is registered after you call "get_term"
https://wordpress.stackexchange.com/questions/13480/get-terms-return-errors/13482#13482
Oh my ... i solve this by a crazy solution temporary.look below :
function load_terms($taxonomy){
global $wpdb;
$query = 'SELECT DISTINCT
t.name
FROM
`wp-cls`.wp_terms t
INNER JOIN
`wp-cls`.wp_term_taxonomy tax
ON
`tax`.term_id = `t`.term_id
WHERE
( `tax`.taxonomy = \'' . $taxonomy . '\')';
$result = $wpdb->get_results($query , ARRAY_A);
return $result;
}
As you can see i use a query, but i cant apply this plugin to my programming team.i still awaiting for a correct solution/usage for get_terms function in wordpress plugins.
regards.
Nothing really to add but to make it clear: get_terms()doesn't work in "admin_init" action hook!
I did like bizzr3. Just put my code here because I was a bit confuse with bizzr3's code:
function load_terms($taxonomy){
global $wpdb;
$query = 'SELECT DISTINCT
t.name
FROM
wp_terms t
INNER JOIN
wp_term_taxonomy tax
ON
tax.term_id = t.term_id
WHERE
( tax.taxonomy = \'' . $taxonomy . '\')';
$result = $wpdb->get_results($query , ARRAY_A);
return $result;
}
then just call load_terms() in your "admin_init" function:
//get all terms from taxonomy Category
$terms = load_terms('category');
and thanks, works like a charm.
I know I'm late to the party.
To optimise bizzr3's code just a bit; You should use the $wpdb object properties for your table names, as "wp_" is just the default but it could change from site to site. Using the object property you make sure it should work for other WordPress sites as well if they have a different table prefix.
function load_terms( $taxonomy ){
global $wpdb;
$query = "SELECT DISTINCT
t.name
FROM
{$wpdb->terms} t
INNER JOIN
{$wpdb->term_taxonomy} tax
ON
tax.term_id = t.term_id
WHERE
( tax.taxonomy = '{$taxonomy}')";
$result = $wpdb->get_results( $query , ARRAY_A );
return $result;
}
Also changed the single quotes to double quotes to use {$variables}