Each user has a user meta called profile_url chosen during registration. After user creation, a page with that slug is created and made private (the author of the page is the admin). The user in his front-end dashboard has the possibility to make this page public or private. When the page is private, the owner user cannot see it.

I would like to make the private page visible to the owner user.

The only way that came to mind is to add capabilities, like:

$ user = new WP_User ($ user_id);
$ user-> add_cap ('read_private_pages');

but I'd like to specify the page id, and I don't know if it's possible.

Thank you

  • So each user an actual page created for them? Whats on the page? Is it a page that they can update? Are they the author of the page when its created?
    – joshmoto
    Commented Apr 20, 2020 at 14:02
  • I'd probably change the code that makes the page private and rejects other users to allow the owner user? That's presumably where you'd put the capability check anyway?
    – Rup
    Commented Apr 20, 2020 at 14:02
  • But current_user_can() does accept arguments beyond the permission name, so you can pass the page ID into that when you're testing the permission for the private page. I'm not sure how you handle that inside the permissions mechanism though, except maybe through a user_has_cap hook that checks the argument.
    – Rup
    Commented Apr 20, 2020 at 14:05
  • @joshmoto the author of the page is the admin and yes, each user has a page with the name of user meta.
    – Vins
    Commented Apr 20, 2020 at 14:07
  • Ah ok, so the author is alway admin, id 1. Thats a shame. If the user was the author of their page that would be cleaner. But i'll drop you answer for both scenarios.
    – joshmoto
    Commented Apr 20, 2020 at 14:11

2 Answers 2


I assume you're using wp_insert_post() to create the private page for the user. The function returns the ID of the created page. You can use this ID as part of a custom capability you grant to the user.

// create the new $user

// create private page
$private_page_id = wp_insert_post( $postarr, $wp_error = false ); // returns id on success, 0 on failure
if ( $private_page_id ) {
  // grant custom cap
  $user->add_cap("can_access_{$private_page_id}", true);

When user tries to access the private page, use user_has_cap filter to check, if the user has the required custom cap and dynamically grant the private page reading capability.

add_filter('user_has_cap', 'user_can_access', 10, 4);
function user_can_access($allcaps, $caps, $args, $user) {
  $object = get_queried_object();
  // make sure we're on a post
  if ( ! is_a($object, 'WP_Post') ) {
    return $allcaps;
  // it should be a private page post 
  if ( 'page' !== $object->post_type || 'private' !== $object->post_status ) {
    return $allcaps;
  // does the user have the required access cap?
  $can_access = 'can_access_' . $object->ID;
  if ( isset( $allcaps[$can_access] ) && true === $allcaps[$can_access] ) {
    // if so, allow user to access the private content
    $allcaps['read_private_pages'] = true;
  return $allcaps;

New answer

OK another way round would be to use WP_Query.

You could create a page called Profile and create a file called page-profile.php

Then use the code below to get the current users page data (assuming you are just saving the post name, not the complete user url in the meta)

// if user is not logged in then return or redirect to login page
if(!is_user_logged_in()) wp_safe_redirect(wp_login_url());

// get the user id
$user_id = get_current_user_id();

// get the current user profile url
$profile_url = get_user_meta($user_id, 'profile_url');

// page query args
$args = [
    'post_status' => ['publish','private'],
    'pagename' => $profile_url

// create the query
$page = new WP_Query( $args );



<?php if ( $page->have_posts() ): ?>

    <?php while($page->have_posts()): $page->the_post() ?>

        <?php the_title()?>

    <?php endwhile; ?>

<?php endif; ?>



This means the user would always got to the url http://yoursite.com/profile to view their page.

User pagename if page but use name if custom post type in the WP Query.

  • Thanks, but I don't want to make the page public, I want to leave it private.
    – Vins
    Commented Apr 20, 2020 at 14:48
  • I don't think you can modify the global $post anyway. It's doesn't actually change the post to published, it's only a temporary thing in array. I'm just testing another idea.
    – joshmoto
    Commented Apr 20, 2020 at 14:50
  • Are you using a page template? For example, when the page is created, are you defining PHP template to use? We could just use WP Query.
    – joshmoto
    Commented Apr 20, 2020 at 14:52
  • yes, I use a page template
    – Vins
    Commented Apr 20, 2020 at 15:04
  • Try this, the code should be valid but not sure why it's being high lighted as wrong
    – joshmoto
    Commented Apr 20, 2020 at 15:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.