Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPP only in current language (with WPML) #102

Closed
anou opened this issue Jan 27, 2016 · 10 comments
Closed

WPP only in current language (with WPML) #102

anou opened this issue Jan 27, 2016 · 10 comments
Assignees

Comments

@anou
Copy link

anou commented Jan 27, 2016

Hello,
The way WPML is supported, means that if a post doesn't have a translation, the original post is displayed...

If you want to display only post in the current language, I've made this little modification in wordpress-popular-posts.php, line 1857 private function __render_popular_post($p, $instance) :

Replace code from if ( defined('ICL_LANGUAGE_CODE') ... to closing bracket line 1878, just before $title = $this->_get_title($p, $instance);

with

if ( defined('ICL_LANGUAGE_CODE') && array_key_exists('wpml_object_id', $GLOBALS['wp_filter']) ) {
    $current_id = apply_filters( 'wpml_object_id', $p->id, get_post_type( $p->id ), false, ICL_LANGUAGE_CODE );
            $permalink = $current_id ? get_permalink( $current_id ) : false;
        } // Get original permalink
        else {
            $permalink = get_permalink($p->id);
        }

  if( $permalink ) { ...

and put the closing bracket just before the `return' statement :

...
} //end if($permalink)
return apply_filters('wpp_post', $content, $p, $instance);

This way only posts in the current language will be displayed.

I have a patch if needed.

And thanks for your work.

@chrisgrabinski
Copy link

Hey @anou,

I've tested your code on a project I am currently working on and encountered a possible bug.

While embedding the Popular Posts into a post results in the expected behaviour, embedding them into a static front page or a static posts page now only shows the original language posts.

I am using Polylang 1.8.1 with Wordpress Popular Posts 3.3.3 on Wordpress 4.4.2.

@PatrickD1985
Copy link

Is this feature still actively being looked into?
To give a quick pointer; https://wpml.org/wpml-hook/wpml_post_language_details/
Hope you are still looking into this.

@cabrerahector
Copy link
Owner

Hey @PatrickD1985,

I'm not actively working on this at the moment. Right now my focus is on ironing out a few minor bugs that popped out with the release of the 4.0.x series and will move on to adding new features / changes (4.1.x most likely) once I'm done with that. No ETA, of course.

@PatrickD1985
Copy link

Ah a shame. But I get it.
I will see what I can put together for this later on. On a multi language site this just needs to be dealt with accordingly.

@PatrickD1985
Copy link

PatrickD1985 commented Dec 27, 2017

I just came to a conclusion; The views currently are shared! Which makes sense because the item is actually the same entity but just in different languages. Views should account to both (jn my belief anyway) So to summarize an English post increases the amount for the original Dutch item. And vice versa.

Well I played around a bit. And have it working!!
Demo can be seem here; https://www.nintendoreporters.com/ and https://www.nintendoreporters.com/en/ (scroll to the bottom)

I will make a writeup for the WPP part (I suck at Github actually otherwise I would have done it that way) but it is pretty feasible to do this without too much hassle. And get back on this.

@cabrerahector
Copy link
Owner

cabrerahector commented Dec 27, 2017

The views currently are shared! Which makes sense because the item is actually the same entity but just in different languages.

That's correct. That was actually the initial thought I had when I first implemented multilingual support. And I still believe it's a valid point of view, as you said yourself it's the same entity.

On the other hand, for a few years now some people out there are (mis)using multilingual plugins to be able to have two "separate" sites without having to set up a multisite network or a separate single WordPress setup for each language. In this scenario it makes sense to also want to have WPP track views separatedly as well.

Well I played around a bit. And have it working!!

I will make a writeup for the WPP part (...) but it is pretty feasible to do this without too much hassle.

Looking forward to it :) All suggestions are welcome, and I'm sure others will appreciate your input as well.

@PatrickD1985
Copy link

PatrickD1985 commented Dec 27, 2017

For in the functions.php (yes keeping it there was easiest for now as I dislike doing direct edits in plugin files etc.

/*

  • Wordpress Popular Post - Custom HTML + WPML Support.
  • With this function, I can alter WPP's HTML output from my theme's functions.php.
  • This way, the modification is permanent even if the plugin gets updated.
  • Also this adds all that is needed to support WPML for any given language.
  • @param array $mostpopular
  • @param array $instance
  • @return string
    */
    function my_custom_popular_posts_html_list( $mostpopular, $instance ){

// Language defintions in case of WPML
$default_lang = apply_filters('wpml_default_language', NULL );
$current_lang = apply_filters( 'wpml_current_language', NULL );

$output = '

    ';

    // loop the array of popular posts objects
    foreach( $mostpopular as $popular ) {
    
    $stats = array(); // placeholder for the stats tag
    
    // Comment count option active, display comments
    if ( $instance['stats_tag']['comment_count'] ) {
    // display text in singular or plural, according to comments count
    $stats[] = '<span class="wpp-comments">' . sprintf(
      		_n( '1 comment', '%s comments', $popular->comment_count, 'wordpress-popular-posts' ),
      		number_format_i18n( $popular->comment_count )
      	) . '</span>';
    }
    
    // Pageviews option checked, display views
    if ( $instance['stats_tag']['views'] ) {
    
    // If sorting posts by average views
    if ($instance['order_by'] == 'avg') {
    // display text in singular or plural, according to views count
    $stats[] = '<span class="wpp-views">' . sprintf(
      			_n( '1 view per day', '%s views per day', intval($popular->pageviews), 'wordpress-popular-posts' ),
      			number_format_i18n( $popular->pageviews, 2 )
      		) . '</span>';
    } else { // Sorting posts by views
    // display text in singular or plural, according to views count
    $stats[] = '<span class="wpp-views">' . sprintf(
      			_n( '1 view', '%s views', intval($popular->pageviews), 'wordpress-popular-posts' ),
      			number_format_i18n( $popular->pageviews )
      		) . '</span>';
    }
    }
    
    // Author option checked
    if ( $instance['stats_tag']['author'] ) {
    $author = get_the_author_meta( 'display_name', $popular->uid );
    $display_name = '<a href="' . get_author_posts_url( $popular->uid ) . '">' . $author . '</a>';
    $stats[] = '<span class="wpp-author">' . sprintf( __( 'by %s', 'wordpress-popular-posts' ), $display_name ). '</span>';
    }
    
    // Date option checked
    if ( $instance['stats_tag']['date']['active'] ) {
    $date = date_i18n( $instance['stats_tag']['date']['format'], strtotime( $popular->date ) );
    $stats[] = '<span class="wpp-date">' . sprintf( __( 'posted on %s', 'wordpress-popular-posts' ), $date ) . '</span>';
    }
    
    // Category option checked
    if ( $instance['stats_tag']['category'] ) {
    $post_cat = get_the_category( $popular->id );
    $post_cat = ( isset( $post_cat[0] ) )
    ? '<a href="' . get_category_link( $post_cat[0]->term_id ) . '">' . $post_cat[0]->cat_name . '</a>'
    : '';
    
    if ( $post_cat != '' ) {
    $stats[] = '<span class="wpp-category">' . sprintf( __( 'under %s', 'wordpress-popular-posts' ), $post_cat ) . '</span>';
    }
    }
    
    // Build stats tag
    if ( !empty( $stats ) ) {
    $stats = '<div class="wpp-stats">' . join( ' | ', $stats ) . '</div>';
    }
    
    $excerpt = ''; // Excerpt placeholder
    
    // Excerpt option checked, build excerpt tag
    if ( $instance['post-excerpt']['active'] ) {
    
    $excerpt = get_excerpt_by_id( $popular->id );
    if ( !empty( $excerpt ) ) {
    $excerpt = '<div class="wpp-excerpt">' . $excerpt . '</div>';
    }
    
    }
    
    // Conditional checks for WPML
    if ($current_lang === $default_lang) {
    $post_permalink =  get_permalink($popular->id);
    $post_title =   $popular->title;
    } else {
    $translated = apply_filters( 'wpml_object_id', $popular->id, 'post' );
    $post_title =   get_the_title($translated);
    $post_permalink = get_permalink($translated);
    }
    
    $output .= "<li>";
        $output .= "<h2 class=\"entry-title\"><a href=\"" . $post_permalink . "\" title=\"" . esc_attr( $post_title ) . "\">" . $post_title . "</a></h2>";
        $output .= $stats;
        $output .= $excerpt;
        $output .= "</li>" . "\n";
    
    }
    
    $output .= '</ol>';
    

    return $output;
    }

    add_filter( 'wpp_custom_html', 'my_custom_popular_posts_html_list', 10, 2 );

Look for the Lines with WPML in the above

Now as for the most important thing, how to get Ajax to play along nicely. As noted due to some system setups of mine I had to use a different approach but the implementation should be fairly the same;

My original AJAX localize was;

wp_localize_script( 'mg-ajax-script', 'mg_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );

I changed that to this;

$ajax_url = admin_url( 'admin-ajax.php' );
$current_lang = apply_filters( 'wpml_current_language', NULL );
if ( $current_lang ) {
$ajax_url = add_query_arg( 'wpml_lang', $my_current_lang, $ajax_url );
}

wp_localize_script( 'mg-ajax-script', 'mg_ajax', array( 'ajax_url' => $ajax_url) );

Now the actual handling need to be dealth with.
We have to take action on the new paramets accordingly.

Intially my function was;

function mg_ajax_text(){
$data = $_POST['data'];
$return = array();
if( is_array( $data ) ){
foreach ( $data as $key => $text ) {
$return[$key] = do_shortcode( base64_decode( $text ) );
}
}
echo json_encode( $return );
exit;
}

Which I altered to

function mg_ajax_text(){
if ( isset( $_GET[ 'wpml_lang' ] ) ) {
do_action( 'wpml_switch_language', $_GET[ 'wpml_lang' ] ); // switch the content language
}
$data = $_POST['data'];
$return = array();
if( is_array( $data ) ){
foreach ( $data as $key => $text ) {
$return[$key] = do_shortcode( base64_decode( $text ) );
}
}
echo json_encode( $return );
exit;
}

And that is all there is to it.
At least depending on if you agree that a count for nl and en of the same item should be the same.
I do believe it is the best way to go in most scenario's.

Hope it helps anyone that is truly the reason I looked into it ... beside me wanting to be able to do it of course.

Edit ok the top part comes out a bit garbled with either code or quote blocks, So I have attached the function just in case.

function.php.zip

@iscueta
Copy link

iscueta commented Jan 9, 2018

Hi,
I have the same problem as you (it seems very popular issue), and I added the function. Everything is ok despite the fact that the posts are duplicated. And another question: where do we have to put ajax code?
Thanks a lot and sorry for my ignorance!

@PatrickD1985
Copy link

Hi well I am using a different AJAX approach opposed to the normal AJAX action by WPP.
So that was just an example. With the above the outcome should not generate items twice or anything (it does not change that behavior in any way from the normal WPP implementation).

If you could provide an example of what is happening that might help solve it,

@iscueta
Copy link

iscueta commented Apr 8, 2018

Hi there!
sorry for writting so late!
this is the website:
https://www.laramblabarcelona.com/en/barcelona-free-museums-day/
if you see the "Top Posts" sidebar, posts (only when is not wpml_default_language, which is spanish) are duplicated.
But I'm not sure what I must do, Do I have to add this new ajax javascript somewhere? where?
Thank you!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants