最近站点 BuddyPress 升级到了最新的1.9版本,发现凡是文章里边插入的邮件地址,因为里边带了@符号,一律被系统自动解释成了 @mention 功能,这个足够不人性化,来回尝试了多种方法想不修改 BuddyPress 核心文件,直接通过加载一些filter之类的代码到bp-custom.php里边,最终没有合适的方案,只能直接修改核心文件,具体方法如下:

找到 /wp-content/plugins/buddypress/bp-activity 里边的bp-activity-functions.php,打开找到第63行,有这段代码的地方 function bp_activity_find_mentions( $content ) { 这个函数就是用来查找所有文章内容里边凡是带上@符号的文字,都会自动转换为 @mention 功能链接,于是思路来了,这个函数里边给它添加一个条件判断,让它仅仅在 BuddyPress 页面才执行此操作,不就解决问题了,于是在此函数里边加入以下判断语句:

// Added by Eastern Design Studio
if ( !bp_is_blog_page() ) {
此处放置该函数的原有代码!
}

保存上传以后,顺利测试通过,但是这个方法最大的缺点就是修改了 BuddyPress 的核心文件,一旦下次升级了 BuddyPress 插件以后,此Hack就自动失效了,但目前只能用这个方法来临时适用以下,持续跟踪其他方法中。

有玩过facebook的一定会facebook的内容自动加载印象深刻,而默认 BuddyPress Activity Stream 则没有自动加载内容的功能,每次需要点击 Load more 才能载入更多的内容,用户体验并不好,那么是否可以像facebook一样实现滚动到底部的时候自动加载内容呢?答案是100%肯定的,而且非常简单,实现方法如下:

新建一个文件取名为 activity-loader.js 并且放置在模版目录的 _inc 文件夹里边,并且插入如下代码:

jQuery(document).ready( function() {
 var jq=jQuery;
 var is_activity_loading=false;//we use it to make sure that we don not try to send the request again and again
 
//let us check on window scroll event
 jq(window).scroll(function() {
 //find the visible load more button
 //since bp does not move load more, we need to find the last one which is visible
 var load_more_btn=jq(".load-more:visible");
 //if there is no visible button, there are no mor activities, let us retrn
 if(!load_more_btn.get(0))
 return;
 
 //find the offset of the button
 var pos=load_more_btn.offset();
 
 //if the window height+scrollTop is greater than the offset top, we have reached the button, let us load more activity
 
 if(jq(window).scrollTop() + jq(window).height() > pos.top ) {
 
 load_more_activity();
 }
 
 });
 
 /**
 * The routine loads more activity
 * We call it whenever we reach at the bottom of the activity listing
 *
 */
 function load_more_activity(){
 //check if activity is loading, means is there already a request doing this
 //if yes, just return and let the other request handle it
 if(is_activity_loading)
 return false;
 
//so, it is a new request, let us set the var to true
 is_activity_loading=true;
 //add loading class to load more
 //theme authors may need to change the selector if there theme has a different id
 //I am doing it for bp-default/derivative themes
 //change #content to whatever you have named it in your theme
 jq("#content li.load-more").addClass('loading');
 
 if ( null == jq.cookie('bp-activity-oldestpage') )
 jq.cookie('bp-activity-oldestpage', 1, {
 path: '/'
 } );
 
var oldest_page = ( jq.cookie('bp-activity-oldestpage') * 1 ) + 1;
 
//send the ajax request
 jq.post( ajaxurl, {
 action: 'activity_get_older_updates',
 'cookie': encodeURIComponent(document.cookie),
 'page': oldest_page
 },
 function(response)
 {
 jq(".load-more").hide();//hide any load more button
 jq("#content li.load-more").removeClass('loading');//theme authors, you may need to change it
 
 //update cookie
 jq.cookie( 'bp-activity-oldestpage', oldest_page, {
 path: '/'
 } );
 
 //and append the response
 jq("#content ul.activity-list").append(response.contents);
 
//since we are done, let us set the state that activity has loaded
 
 is_activity_loading=false;
 }, 'json' );
 
return false;
 }
 
});//end of dom ready

然后在模版目录里边的functions.php里边插入如下代码:

function bp_activity_autoloader_inc_js(){
//you can change get_stylesheet_directory_uri() to get_tmplate_directory_uri() if you are author of a parent theme and want to include it in parent theme and not in the child theme.
 wp_enqueue_script('activity-auto-loader', get_stylesheet_directory_uri().'/_inc/activity-loader.js',array('jquery'));//should we make it dependent on 'dtheme-ajax-js'?
}
add_action('bp_enqueue_scripts','bp_activity_autoloader_inc_js',30);

保存上传覆盖即可,前台测试一下你会发现效果很不错,搞定收工。

如何解决此类冲突呢?

最近在优化WordPress的过程当中,发现BuddyPress载入的global.js里边包含的 jQuery easing 脚本与其他很多常用的 Slideshow Gallery, Easy Nivo Slider等插件水火不相容,两者无论如何都无法共存,这样就得取舍了,要么卸载BuddyPress,要么抛弃Slideshow,但是这两种显然都不是理想的解决方案,那么换个思路试试看,如何能让两者不一起出现,于是找到了一款很不错的插件:Plugin Organizer 通过这款插件可以控制任意一个页面需要载入哪些插件,不要载入哪些插件,这样我只需要把分别需要用到BuddyPress和SlideShow的页面完全独立开来,让他们彼此没有碰到一块的机会就不会出现冲突了,当然这个解决方案还是不够完美,实际操作过程中发现,如果把BuddyPress等插件通过该插件进行全局的不载入,然后到实际BuddyPress的页面再单独载入,不过问题来了,进行了全局的排除,那么势必对所有要用到的页面都得挨个去定义载入,尽管这个插件可以进行网址子目录的包含之类的功能,但是假设新建了很多不同的Group和Forum等的时候,就变得很不可控了,毕竟BuddyPress类的站点,好多都是在用她来搭建一个全局的社会化站点,现在因为有插件的冲突,我们人为的去阻止了这个全局化,肯定不是一个理想方案。

我们都知道WordPress站点BuddyPress化以后,新增了很多全站的功能,比如站内短信互动,动态跟踪等特性,如果对BuddyPress进行全局的不载入,那么这些功能都只能放弃了,因此对于大多数用BuddyPress来做社会化站点的情况来说,这个方案直接pass了,那么我们再换个思路来设法解决这个问题,也就是既然提示的是jQuery easing的冲突,那么我们是否可以把jQuery easing从BuddyPress的global.js里边剥离出来,单独将这个js载入到具体涉及要用到jQuery easing的页面,而据我检测发现,要用到这个模块的也就是很少的几个地方,比如activity的发布表单,如果没了jQuery easing,这个表单就失效了,还有几个地方也都类似,那么就好办了,我们直接把这个模块剥离出来,然后把这个存成一个单独的jquery-easing.js的文件,载入到专门用来载入到BuddyPress核心页面的头部header-buddypress.php里边,这样其他非buddypress页面就完美实现了两者的共存,经测试完全可行。

总结

这个教程主要以思路为主,不直接将里边的代码贴出来,事实上好多时候授人与鱼,不如授人予渔,直接贴代码出来仅仅可以解决一个实际的问题,而我们都知道,WordPress和BuddyPress的版本经常更新,插件也是,兼容性问题千变万化,如果不能举一反三,很难实际的解决问题。

这两天一个客户的项目涉及BuddyPress中上传png透明头像时候,变成了黑色背景的问题,通过研究和google搜索找到了如下解决方案,原因是WordPress的裁切函数写得不够兼容,有效的代码如下:

function wp_crop_image( $src_file, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $src_abs = false, $destfilename = false ) {
if ( is_numeric( $src_file ) ) // Handle int as attachment ID
$src_file = get_attached_file( $src_file );

$src = wp_load_image( $src_file );

if ( !is_resource( $src ))
return $src;

$dst = wp_imagecreatetruecolor( $dst_w, $dst_h );

if ( $src_abs ) {
$src_w -= $src_x;
$src_h -= $src_y;
}

list($width, $height, $orig_type) = getimagesize( $src_file );

if (function_exists(‘imageantialias’))
imageantialias( $dst, true );

imagecopyresampled( $dst, $src, 0, 0, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h );

imagedestroy( $src ); // Free up memory

// if ( ! $dst_file )
// $dst_file = str_replace( basename( $src_file ), ‘cropped-‘ . basename( $src_file ), $src_file );

// convert from full colors to index colors, like original PNG.
if ( IMAGETYPE_PNG == $orig_type && !imageistruecolor( $dst ) )
imagetruecolortopalette( $dst, false, imagecolorstotal( $dst ) );

if ( IMAGETYPE_GIF == $orig_type ) {
if ( !imagegif( $dst, $destfilename ) )
return new WP_Error(‘resize_path_invalid’, __( ‘Resize path invalid’ ));
} elseif ( IMAGETYPE_PNG == $orig_type ) {
if ( !imagepng( $dst, $destfilename ) )
return new WP_Error(‘resize_path_invalid’, __( ‘Resize path invalid’ ));
} else {
if ( !imagejpeg( $dst, $destfilename, apply_filters( ‘jpeg_quality’, 90, ‘wp_crop_image’ ) ) )
return new WP_Error(‘resize_path_invalid’, __( ‘Resize path invalid’ ));
}

//$dst_file = preg_replace( ‘/\\.[^\\.]+$/’, ‘.jpg’, $dst_file );

//if ( imagejpeg( $dst, $dst_file, apply_filters( ‘jpeg_quality’, 90, ‘wp_crop_image’ ) ) )
// return $dst_file;
// else
// return false;
}