如何使用PRE_GET_POSTS在我的多站点网络中查询另一个站点的帖子?

时间:2013-10-28 作者:Johan Nordström

我有一个多站点的网站网络,如果博客文章有一个带有站点名称的标记,那么应该显示彼此的博客内容。

为了收集网络中的所有帖子,我使用了SWT(Sitewide Tags)插件,因为它似乎是最有效的。我将所有帖子存储在主站点(博客id 1)中,并从我的其他站点查询主站点帖子表,以查找包含带有查询站点域名的标记的帖子。

我在页面模板中有工作代码(home.php) - 请参见下文-但我了解行动pre_get_posts 是应该做的,但我似乎不知道如何将表更改为查询。我是否应该加入行动posts_join?

如果我的解决方案似乎比它应该的复杂得多,请随意用其他建议抨击我:)

这是我当前的模板代码:

$tags = array(
    \'lundalogik-se\'
);
switch_to_blog(1);
$paged = ( get_query_var( \'paged\' ) ) ? get_query_var( \'paged\' ) : 1;
$wp_query = new WP_Query(array(
    \'post_status\' => \'publish\',
    \'paged\' => $paged,
    \'orderby\' => \'date\',
    \'order\' => \'desc\',
    \'tag\' => implode(",", $tags)
));

while (have_posts()) : the_post();
  [..]
如何在中重写此内容pre_get_posts?

注释;正如您看到的,我正在搜索的标记目前是静态的,这将更改为匹配查询站点的域名+ccTLD或稍后类似的内容

注2;我宁愿不使用switch_to_blog() 因为我读过,它很贵,但还没有找到在网络中查询其他博客的最佳实践。是否应该将表名设置为手动查询

我在这里、博客和Codex(WP\\u Query、pre\\u get\\u posts等)中读到了大多数涉及多站点查询的帖子,但几乎所有的帖子都谈到了使用switch\\u to\\u blog和restore\\u current\\u blog。

2 个回复
最合适的回答,由SO网友:Johan Nordström 整理而成

好的,作为参考,我最终实际使用了switch_to_blog()restore_current_blog(). 我没有找到任何用于查询多个表的引用(除了编写自己的表JOIN-语句)执行操作的源代码时pre_get_posts.

有人给了斯基普很多建议restore_current_blog() 为了节省CPU周期,但当我检查源代码时,我发现这会导致巨大的内存问题,因为restore_current_blog() 所做的是将最新插入的对象弹出到全局数组中,并且该数组将随着每个switch_to_blog() 那一个做不到restore_current_blog() 在…上

请随时查看源代码,并查看@user42826对此的回答,网址为https://wordpress.stackexchange.com/a/123516/14820.

对于那些感兴趣的人来说,我最终得到了站点列表和结果的瞬态,以节省CPU周期和DB性能。我只需要更新过时的数据(15分钟或更长时间)。仅包含以下相关功能位:

$site_transient = get_site_transient( \'multisite_site_list\');
if ($site_transient == false || LL_USE_TRANSIENTS == false) {
    $using_site_transient = false;

    // no cache available
    global $wpdb;

    // TODO: get prefix for wp tables
    $site_list = $wpdb->get_results($wpdb->prepare(\'SELECT * FROM nw_blogs WHERE public = %d AND deleted = %d ORDER BY blog_id\', 1, 0));

    // set transient
    set_site_transient(\'multisite_site_list\', $site_list, LL_TRANSIENT_EXPIRES);

} else {
    //log_msg("SITELIST - Transient found, using cached query..");
    $site_list = $site_transient;
    $using_site_transient = true;
}

//log_msg("$id - get_posts_from_network | tags: " . implode(",", $tags) . " | tag_slug__and: $lang_full");

$start = microtime(true);

// get blogpost transient, if existing
$post_transient = get_site_transient( \'limelight_recent_posts_\' . $hash);

// if not, do query and save result as a transient
if ($post_transient == false || LL_USE_TRANSIENTS == false) {
    $using_post_transient = false;
    $blogposts = array();

    foreach ($site_list as $site) {
        switch_to_blog($site->blog_id);
        $posts = get_posts(array(
            \'post_status\' => \'publish\',
            \'orderby\' => \'date\',
            \'order\' => \'desc\',
            \'tag\' => implode(",", $tags),
            \'tag_slug__and\' => array($lang_full)
        ));

        //log_msg("$id - get_posts_form_network | at site: $site->blog_id");

        foreach ($posts as $post) {

            //log_msg("$id - get_posts_form_network | at site: $site->blog_id | got post!");

            $post->human_post_date = human_time_diff(get_post_time(\'U\', false, $post->ID), current_time(\'timestamp\')) . \' \' . __(\'ago\', \'limelight\');

            if (isset($tagline_metabox)) {
                $meta = get_post_meta($post->ID, $tagline_metabox->get_the_id(), TRUE);
                $post->tagline = $meta[\'tagline_text\'];
            }

            if (!isset($post->tagline) || $post->tagline == \'\')
                $post->tagline = substr($post->post_title, 0, 20) . \'..\';

            $post->post_date_timestamp = strtotime($post->post_date);           

            //$post->blog_id = $site->blog_id;
            $post->blog_name = get_bloginfo(\'name\');
            $post->blog_url = get_bloginfo(\'wpurl\');
            $post->permalink = get_permalink($post->ID);
            $post->author_name = get_userdata($post->post_author)->display_name;
            //$data = get_userdata($post->post_author);

            $blogposts[] = $post;
        }
        restore_current_blog();
    }

    // sort blogposts by post_date_timestamp, descending
    array_sort_by_obj($blogposts, \'post_date_timestamp\', SORT_DESC);

    // pick five latest posts
    if (sizeof($blogposts) > 5) {
        $posts = array();
        for ($i = 0; $i <= 4; $i++) {
            $posts[$i] = $blogposts[$i];
        }
        $blogposts = $posts;
    }

    // set transient
    if (LL_USE_TRANSIENTS)
        set_site_transient(\'limelight_recent_posts_\' . $hash, $blogposts, LL_TRANSIENT_EXPIRES);

SO网友:Ashok Kumar Nath

请尝试以下操作:

add_filter( \'pre_get_posts\', \'get_post_from_main_blog\' );
function get_post_from_main_blog($query) {
    global $wpdb;
    $wpdb->posts = \'wp_posts\';
    return $query;
}
您可能需要将wp\\u posts更改为主博客的post表名称。

结束

相关推荐

WordPress MultiSite(MU)子目录url/slug/permarink可以更改吗?

我目前正在与WordPress Multisite(MU)、BuddyPress和Commons in a Box(CBOX)合作,围绕一个中心用户群创建一个网站,该网站允许用户组成群组,并创建与其群组相关的“群组博客”。我在这个问题上发布了关于这个确切情况的进一步详细信息here.然而,我想问一个更一般的问题,关于WordPress多站点安装的性质,除了初始站点或网络主页。我的问题是,是否可以更改默认的子目录url结构/文件夹。例如,Multisite当前的默认设置为site。com/blog/sub-