简体   繁体   中英

Changing the front page in WordPress based on whether the user is logged in or not

I'm building a plugin that helps users signup and login from the WordPress front-end, and also hides and shows resources based on whether or not the user is logged in.

One area I've gotten stuck on is how to change the homepage that's shown at the root domain based on the user's logged-in/logged-out status. In a theme template, this is easily achieved using this structure:

if ( is_user_logged_in() ) {
    // Logged-in user content
} else {
    // Logged-out user content
}

Because this is a plugin, however, I don't want site admin to have to mess around with their theme files. So far I've tried adding this this to dynamically rewrite the front page:

if ( is_user_logged_in() ) {
  $about = get_page_by_title( 'Front Page Logged In' );
  update_option( 'page_on_front', $about->ID );
  update_option( 'show_on_front', 'page' );
} else {
  $about = get_page_by_title( 'Front Page Logged Out' );
  update_option( 'page_on_front', $about->ID );
  update_option( 'show_on_front', 'page' );
}

The update_option functions work on their own, but wrapped in an if statement, throw a fatal error so the site doesn't load at all.

I've also tried using the add_rewrite_rule API to simply tell WordPress to treat the root domain as another page. This works when specifying a particular page, but I can't figure out how to make it work for the root (and only root) URL, and even if I could, it also doesn't work properly when wrapped in an if statement.

function add_my_rule() {
    if ( is_user_logged_in ) {
        add_rewrite_rule('test','index.php?pagename=loggedin','top');
    } else {
      add_rewrite_rule('test','index.php?pagename=loggedout','top');
    }
}
add_action('init', 'add_my_rule');

So just to recap, I need a way to display one page as the front page if a user is logged in, and a different one if they're logged out, from a plugin (not from the theme files). Any insights into how to make this work would be great appreciated!

Approach One

This should do the trick based on template files. You would still need to have the user add/build the templates or copy them over to the theme directory upon plugin activation.

add_filter( 'template_include', 'member_home' );
function member_home( $template ) {
    if ( is_home() || is_front_page() ){
        if ( is_user_logged_in() ) {
            return locate_template('home-member.php');
        } else {
            return get_home_template();
        }
    }
    return $template;
}

Approach Two

Here is another approach, using only a plugin. This assumes you have a templates/ directory in your plugin folder which contains the file member-home.php .

It does two things:

  • changes the 'home' template for logged in users, looking for that template in the active theme directory, fallback to the plugin included version
  • replaces the_content with any data you want (pulled the 'Hello World' post in this example)

You could also add a new page via register_activation_hook() and query that data in the set_home_content() function.

define('MYPLUGIN_PLUGIN_PATH', plugin_dir_path( __FILE__ ));
define('ACTIVE_THEME_PATH', get_stylesheet_directory());

add_action('plugins_loaded', 'myplugin_plugins_loaded');

function set_home_template( $template ){
    if ( is_home() || is_front_page() ){
        if ( is_user_logged_in() ){
            if( file_exists(ACTIVE_THEME_PATH.'templates/member-home.php') ) {
                return ACTIVE_THEME_PATH.'templates/member-home.php';
            } else {
                return MYPLUGIN_PLUGIN_PATH.'templates/member-home.php';
            }
        } else {
            return get_home_template();
        }
    }
    // Returns the template
    return $template;
}

function set_home_content( $content ){
    if ( is_home() || is_front_page() ){
        if ( is_user_logged_in() ){
            $args = array(
                'pagename' => 'hello-world',
                'posts_per_page' => 1
            );
            $posts = new WP_Query( $args );
            while ( $posts->have_posts() ) {
                $posts->the_post();
                $content = get_the_content();
            }
            wp_reset_postdata();
            // Returns the custom queried content
            return $content;
        }
    }
    // Returns the default content.
    return $content;
}

function myplugin_plugins_loaded() {
     add_filter( 'template_include', 'set_home_template' );
     add_filter( 'the_content', 'set_home_content', 10 );
}

That should give you some ideas but as you noted, there is probably no real 'automatic' solution. The user will still have to adapt the theme files/add pages or whatsoever. But that could be part of a great plugin documentation ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM