What I Am Trying To DO
I am using a plugin called Comments Evolved which aggregates comments that are tabbed from Faceook, G+, and WordPress native.
I am trying to replace the native comments_number number with the number from the plugin's aggregate count.
The Problem
I want to do this via functions.php but I am having trouble as it seems to only be pulling the Facebook comments count. I suspect my filter has not worked and hence it's only pulling what WordPress native would pull.
What I've Tried
Currently I am using this filter:
// Replace native comment count with Comments Evolved comment in native comments_number function
function comments_evolved_number() {
$number = comments_evolved_get_total_count();
}
apply_filters('comments_number', 'comments_evolved_number');
but it doesn't seem to be doing the trick as it only shows the number of comments in the Facebook tab.
In my index.php, I am using this to pull the comments:
<?php comments_number( 'Say somethin\'!', '1 comment', '% comments' ) ?>
I've also tried add_filter but that seems to do nothing as the comments aren't output at all. I've searched everywhere, forums, WordPress codex, plugin GitHub, and even looked through similar threads dealing with Disqus comments, but I can't find the reason my filter is failing.
What am I doing wrong?
UPDATE 1
This seems to work:
function wpse_comments_evolved_number( $count )
{
// Override the comment count
if( function_exists( 'comments_evolved_get_total_count' ) )
$count = comments_evolved_get_total_count();
// We must then return the value:
return $count;
}
add_filter( 'get_comments_number', 'wpse_comments_evolved_number');
...but on testing, it seems that it does Not pull the Facebook comment count, though it pulls and aggregates all the rest:
Comments Evolved constructs comments_evolved_get_total_count() like this:
function comments_evolved_get_total_count() {
$total_count = 0;
$wordpress_count = comments_evolved_get_wordpress_count();
//$wordpress_count = get_comments_number();
$gplus_count = comments_evolved_get_gplus_count();
$trackback_count = comments_evolved_get_trackback_count();
$facebook_count = comments_evolved_get_facebook_count();
$disqus_count = comments_evolved_get_disqus_count();
$total_count = $total_count + $wordpress_count + $gplus_count + $trackback_count + $facebook_count + $disqus_count;
return $total_count;
}
//add_filter('get_comments_number', 'comments_evolved_get_total_count', 4269);
The Facebook comments_evolved_get_facebook_count() is constructed like this:
function comments_evolved_get_facebook_count($url = "") {
if(empty($url)){ $url = get_permalink(); }
$link = 'https://graph.facebook.com/?ids=' . urlencode($url);
$link_body = wp_remote_retrieve_body(wp_remote_get($link));
$json = json_decode($link_body);
return $json->$url->comments;
}
I don't see any errors in that and in other places it pulls the correct Facebook count (I think -- not sure).
What did work but doesn't seem efficient/satisfactory
function comment_count_agg() {
$total_count = 0;
//$wordpress_count = comments_evolved_get_wordpress_count();
$wordpress_count = get_comments_number();
$gplus_count = comments_evolved_get_gplus_count();
$trackback_count = comments_evolved_get_trackback_count();
$facebook_count = comments_evolved_get_facebook_count();
$disqus_count = comments_evolved_get_disqus_count();
$total_count = $total_count + $wordpress_count + $gplus_count + $trackback_count + $facebook_count + $disqus_count;
return $total_count;
}
add_filter('comments_evolved_get_total_count', 'comment_count_agg', 4270);
add_filter('get_comments_number', 'comments_evolved_get_total_count', 4271);
...though I am not exactly sure why.
I tried it this way because (a) I figured something in the plugin is messing with the aggregate count before the filter is applied and (b) because I thought maybe the priorities were somehow an issue.
UPDATE 2
I've actually tried both above methods on 2 different sites. On 1 site, everything works perfectly with either method.
On site 2, it fails to pull in the Facebook count towards the whole aggregate count. Any ideas?
This seems to work:
function wpse_comments_evolved_number( $count )
{
// Override the comment count
if( function_exists( 'comments_evolved_get_total_count' ) )
$count = comments_evolved_get_total_count();
// We must then return the value:
return $count;
}
add_filter( 'get_comments_number', 'wpse_comments_evolved_number');
However, on one site that I've tried it, the Facebook count is not being pulled in. On another, everything works perfectly.
Thanks guys, your discussion helps me to hide the total number of comments header by using get_comments_number hook from the frontend as well as I hide all comments by comments_array hook.
// Hide comments counter
add_filter( 'get_comments_number', 0);
// Hide existing comments
add_filter('comments_array', '__return_empty_array', 10, 2);
// Remove the comment form
add_filter( 'comments_open', '__return_false' );
Related
I read an article on Google that says for good SEO it is best that the size of the slug in the URL is limited to 5 words.
As I use WordPress the link is assigned automatically to the article title. To redo all the links with just 5 words I would have to spend months editing all the links on my blog.
Would it be possible to do this automatically? There is some function or code for that. I found this code and added it to the function page of my theme and had no results.
See the code:
function pm_limit_slugs_length($uri) {
$max_words = 5; // If any part of URI contains more than 5 words, the slug will be limited to first 5 words
$new_title = '';
$slugs = explode('/', $uri);
for($i=0, $count = count($slugs); $i < $count; $i++) {
$slug = $slugs[$i];
$words = explode('-', $slug);
$new_title .= "/";
if(count($words) > $max_words) {
$new_title .= implode("-", array_slice($words, 0, $max_words));
} else {
$new_title .= $slug;
}
}
// Remove trailing slashes
$new_title = trim($new_title, "/");
return $new_title;
}
add_filter('permalink_manager_filter_default_post_uri', 'pm_limit_slugs_length', 99);
add_filter('permalink_manager_filter_default_term_uri', 'pm_limit_slugs_length', 99);
I found the code here: https://permalinkmanager.pro/docs/filters-hooks/how-to-limit-the-number-of-words-in-wordpress-permalinks/
How can I use it to limit the Wordpress slug size to 5 words?
First, a note on whether it is worthwhile to do this:
There are literally 100s of factors that affect SEO. You are not expected to implement all of them, and many will not have a big influence overall. In my opinion, doing this is most likely not going to have any significant effect, and it only makes things more difficult for you.
More importantly, to have any influence on SEO the slug should include your keywords, and if you change them programmatically, there is no way to ensure the slug will include keywords, so you could even do more harm than good.
FYI, a few versions ago, WP was changed to implement this limit on slugs and then very quickly changed back. That would suggest to me that it might not be very useful or practical.
However if you still want to do this:
Limiting the words in new slugs
The code in your question is from this article, right?: How to limit the number of words in WordPress permalinks or slugs?
The first example - that you used - is for use with their plugin. The next example (included below) will work in Wordpress without the plugin. This can be added into your functions.php.
UPDATE: I have incorporated the code to Automatically Remove Short Words From URL into this function to remove short words less than 3 characters, see updated function below.
<?php
/**
* Trim native slugs
*/
function pm_trim_native_slug($slug, $post_ID, $post_status, $post_type, $post_parent) {
global $wpdb;
$max_words = 5; // Limit the number of words to 5; This value can be changed.
$words = explode('-', $slug);
/* UPDATED CODE TO REMOVE SHORT WORDS */
$min_word_length = 2;
foreach ($words as $k => $word) {
if (strlen($word) <= $min_word_length)
unset($words[$k]);
}
/* END OF UPDATED CODE FOR SHORT WORDS */
if(count($words) > $max_words) {
$slug = implode("-", array_slice($words, 0, $max_words));
// Make the slugs unique
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
$post_name_check = $wpdb->get_var($wpdb->prepare($check_sql, $slug, $post_ID));
if($post_name_check) {
$suffix = 2;
do {
$alt_post_name = _truncate_post_slug($slug, 200 - (strlen($suffix) + 1)) . "-$suffix";
$post_name_check = $wpdb->get_var($wpdb->prepare($check_sql, $alt_post_name, $post_type, $post_ID, $post_parent));
$suffix++;
} while ($post_name_check);
$slug = $alt_post_name;
}
}
return $slug;
}
add_filter('wp_unique_post_slug', 'pm_trim_native_slug', 99, 5);
Note that this only works on new slugs, you still need to regenerate the old slugs, or write code to go through the existing slugs to update them.
Updating existing slugs
You can add this function to your functions.php to get all your slugs, call the function above to generate a new slug, and then update it in the DB:
function limit_all_existing_slugs(){
// get all posts
$posts = get_posts( array ( 'numberposts' => -1 ) );
foreach ( $posts as $post ){
// create the new slug using the pm_trim_native_slug function
$new_slug = pm_trim_native_slug($post->post_name,
$post->ID,
$post->post_status,
$post->post_type,
$post->post_parent);
// only do the update if the new slug is different
if ( $post->post_name != $new_slug ){
wp_update_post(
array (
'ID' => $post->ID,
'post_name' => $new_slug
)
);
}
}
}
Note that the code above is my own and is untested, so make sure you try it out in a test environment first.
How to use this function
To update all the existing slugs, you only want to call this function once on demand, instead of automatically (otherwise it will update the slugs everytime your functions.php loads). You can do that in an external script outside of WP by creating a separate standalone page as follows:
<?php
include('wp-load.php'); //Include the wp-load.php file
define('WP_USE_THEMES', false); //We don't need the theme files
echo "<p>About to update all slugs...</p>";
limit_all_existing_slugs();
echo "<p>...DONE</p>";
?>
Right so this seems to have been asked a few times but I cannot seem to find definitive working answer.
Currently I am trying to limit my post title and post excerpt on my WP website.
I have managed to trim the titles by character using
function custom_trim_my_title( $title ) {
if ( strlen( $title ) >= 72 && ! is_singular() ) {
$title = substr( $title, 0, 72 ) . '...';
return $title;
}
return $title;
}
add_filter( 'the_title', 'custom_trim_my_title' );
And that seems to be working okay but I can't seem to get it to work for the excerpt.
I was using this word count:
function custom_excerpt_length( $length ) {
return 20;
}
add_filter( 'excerpt_length', 'custom_excerpt_length', 999 );
But the longer words still made it look messy so I need a character count and have tried this:
add_filter('the_excerpt','excerpt_char_limit');
function excerpt_char_limit($e){
return substr($e,0,50);
}
But it doesn't seem to work.
Any help would be great.
Try using
add_filter('the_excerpt','excerpt_char_limit',999);
instead. It is just in case if some other filter prevents your filter. (999 means executing later than other filters)
I asked this question on WP Stackexchange already but did not get any answers. So let me try here. Wordpress Stackexchange
Is there a way to remove the Pagination in the Wordpress Menu Editor?
I have something like 200 categories in my blog and customising menus seems to be tricky when you have to click through it to find the desired category.
I know there's a plugin that "removes" the pagination for PAGES but I could not find anything to remove the pagination for the CATEGORIES.
I tried to find something in the Wordpress Admin PHP files or even nav-menus.php but did not get lucky.
Link to Problem
Ok after reading through the source code I found that the number of categories returned in the edit menu section is hardcoded to 50 on line 613 of \wp-admin\includes\nav-menu.php
// Paginate browsing for large numbers of objects.
$per_page = 50;
$pagenum = isset( $_REQUEST[$taxonomy_name . '-tab'] ) && isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 1;
$offset = 0 < $pagenum ? $per_page * ( $pagenum - 1 ) : 0;
In order to override the default of 50 per page you can set the number to '' to instruct the query to return all categories. Add the following code to your functions.php file.
add_filter( 'get_terms_args', 'show_all_categories_admin_nav_menu', 10, 2);
function show_all_categories_admin_nav_menu( $args, $taxonomies ) {
if( reset($taxonomies) === 'category' ) {
$args['number'] = '';
}
return $args;
}
If you set the number to blank it still shows the pagination even though it's showing all the categories.
There's also a filter called terms_clauses that exists in which you can remove the SQL LIMIT clause from the query but this didn't seem to have any affect on the query.
add_filter('terms_clauses', 'modify_terms_clauses', 10, 3);
function modify_terms_clauses( $clauses, $taxonomies, $args ) {
if( reset($taxonomies) === 'category' ) {
$clauses['limits'] = '';
}
return $clauses;
}
My Woocommerce website shows 3 columns of products in every loop page.
I'm making some custom landing page where i want to show the loop of products in 4 column instead of 3.
I tryed with this code inside function.php:
add_filter('loop_shop_columns', 'loop_columns');
if (!function_exists('loop_columns')); {
function loop_columns() {
if (is_page(91040)){
return 4;
}else{
return 3;
}
}
}
without success.
Is there a way to have in a single or specific page a different number of column compared to the others?
If you are using woothemes theme or any other theme which is already utlisiing the loop_columns filter, then you need to override that with two things, by removing the if !function exit condition, and also adding pririty to filter high enough like 999 so it is applied at the last:
e.g.
// Override theme default specification for product # per row
function loop_columns() {
return 5; // 5 products per row
}
add_filter('loop_shop_columns', 'loop_columns', 999);
You may adjust the function as per you needs like adding page template conditional as you have in your original code.
Source:
https://docs.woothemes.com/document/change-number-of-products-per-row/ Second headline
I solved the issue. The problem was in the is_page function. It can't get the correct ID so i have found a workaround:
function loop_columns() {
global $woocommerce;
$url = explode('?', 'http://'.$_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"]);
$ID = url_to_postid($url[0]);
if ($ID == 91040){
return 4;
}else{
return 3;
}
}
add_filter('loop_shop_columns', 'loop_columns', 999);
I spent a lot of brain matter trying to control the number of columns in a custom template. I am new to WooCommerce and Wordpress so am on a learngin curve. However, I started off with:
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
wc_get_template_part( 'content', 'product' );
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->
When applied as a template it gave me a custom loop that I could fiddle with. However, from there I wanted 5 columns and just could not figure it out. I tried all the things Google could throw up such as filers and such. However, I finally discovered that the above snippet starts off with the
<ul class="products">
tag. All I did was dd the appropriate colum class:
<ul class="products columns-5">
This might require additional thinking regarding the responsive aspects, but it crosses the immediate barrier of controlling columns with that snippet. However, it does actually seem to respond quite well.
nearly finished my wp plugin for an estate agent,
I spidered the site for 404's etc, i noticed that my property details pages were spider'd in which all 45 page titles were : ( details | sitename ) (page titles are shown dynamicly from an ID being passed via querystring)
now I've got my nice urls fixed, urls look like this...
wpsite.com/details/20043/property+for+sale+in+this+area
In Which...
propid = 20043
propname = property+for+sale+in+this+area
both of these are querystring values which are used to re-write the urls.
'query_vars' => array('propid', 'propname'),
'rules' =>
array( '(.+?)/([^/]+)/([^/]+)/?$' => 'index.php?pagename=$matches[1]&propid=$matches[2]&propname=$matches[3]' )
);
Now when the property details page is loaded im trying to hook into the wordpress filter
wp_title but this isnt working the way i expected..
this is the code im using to generate the titles
function wp_myplugin_property_title()
{
$wp_acquaint_id = get_option("wp_system_id");
$propid = get_query_var('propid');
if(isset($propid)){
$seotitle = wp_myplugin_seo_title($propid);
}else{
$seotitle = "TEST Title";
}
return $seotitle;
}
if( is_page('details') ){
add_filter('wp_title', wp_myplugin_property_title, 100);
}
the function used within that function: wp_myplugin_seo_title($propid) generates the actual title i want to use...
function wp_myplugin_seo_title($propid)
{
$wp_acquaint_id = get_option("wp_acquaint_id");
$xml = wp_myplugin_get_property($propid);
foreach($xml->PropertiesDataSet->Properties as $node) {
include('xml_loop.php');
if($bedrooms==0){ }else{ $seo_title.= $bedrooms." bedroom "; }
$seo_title.= wp_myplugin_get_property_type($type_id)." "; //ie:flat
$seo_title.= str_replace("(","",$street);
$seo_title.= " ".$town." | ".get_bloginfo('name');
}
return $seo_title;
}
Im finding that with the if(is_page()) in place around the filter the page title dosnt change and if i remove the is_page, the prop details page title works fine but!!!
while on the property listing page the page title is looping through all the properties on that page and producing a page title around 1000 char long..!
I have been hunting around for a better way to deal with this but any help would be great..
Cheers
Marty
ps: currently running wordpress seo by Yoast!
thats why ive set the priority as 100 in the add_filter just to see if it would overwrite the title..
Using is_page in functions.php doesn't work, as it runs before wp knows what page it's going to render, or even if it's a page to begin with. Stick the is_page() inside the function, and it should work. Like:
function wp_myplugin_property_title()
{
if( is_page('details') ){
$wp_acquaint_id = get_option("wp_system_id");
$propid = get_query_var('propid');
if(isset($propid)){
$seotitle = wp_myplugin_seo_title($propid);
}else{
$seotitle = "TEST Title";
}
return $seotitle;
}
}
add_filter('wp_title', wp_myplugin_property_title, 100);