0

I would like to restrict access to specific pages in the admin area to only the admin role (and / or specific users). There appears to be no shortage of answers on how to do this using the page ID's - but I can't seem to find any examples of how to do this with a page slug.

Extended explanation: I have a list of pages (slugs are: login, logout, lostpassword, register, and resetpass) that I utilize across multiple websites in order to create corresponding pages that match the rest of the theme. But these are pages that are never directly edited and their presence to editors, contributors, etc. is unnecessary, possibly confusing, and certainly not anything I would want them to try and edit or delete.

Since page ID's can vary from site to site, it would be handy to have a function that I could simply copy and paste and not have to worry about it. Thank you for taking the time to read this question and for any answers that might be contributed!

6
  • 2
    This was already answered here: wordpress.stackexchange.com/questions/14964/… - note that it defines user roles by capability (current_user_can). If there's something specific you don't get about the answer, be more specific, and someone can probably provide a full-fledged "Answer."
    – CK MacLeod
    Commented Apr 10, 2017 at 17:05
  • Maybe I'm missing something, but I don't see how the answer in your link applies to my question. I'm trying to prevent certain pages from appearing in the list of pages (based on the page slug, not the ID), unless you're an administrator role. Perhaps I need to add clarification to my question? This is closer to what I'm trying to do: wordpress.stackexchange.com/questions/13528/… But that example uses ID's - not the page slug. Also, I would say "!is_admin()" instead of "is_admin()", but you probably get the idea. Commented Apr 11, 2017 at 19:22
  • Sorry - I misread your question (or didn't read it closely enough). I think one good method would be to derive the id using get_page_by_path(), if that doesn't work for you for some reason, just provide the code you're starting with, and maybe I (or someone!) can write a "real" answer for you.
    – CK MacLeod
    Commented Apr 11, 2017 at 21:07
  • Thanks again for taking the time to respond! There's a number of examples of how to do this using the ID. A simple and straight forward approach seems to be, from my limited knowledge, found here: wordpress.stackexchange.com/questions/13528/… From my testing, with a little modification, this works nicely. Commented Apr 12, 2017 at 21:56
  • So are you saying you need an example of deriving and using the ID, or that you're all set?
    – CK MacLeod
    Commented Apr 12, 2017 at 22:01

1 Answer 1

1

So following from the comment discussion, a sufficient answer on another StackEx question goes like this:

add_filter( 'parse_query', 'exclude_pages_from_admin' );
function exclude_pages_from_admin($query) {
    global $pagenow,$post_type;
    if (is_admin() && $pagenow=='edit.php' && $post_type =='page') {
        $query->query_vars['post__not_in'] = array('21','22','23');
    }
}

The only part that's terribly important to us is the array of post IDS.

The problem is that a post on a given installation can have the identical slug, but will normally have a different ID.

So, what if we create an array of the to-be-excluded post slugs:

$excludeds = array( 'login', 'logout', 'lostpassword', 'register', 'resetpass' );

foreach ( $excludeds as $excluded ) {

        $excluded_IDs[] = get_page_by_path( $excluded )->ID;

}

This ought to work from installation to installation assuming identically slugged posts/pages:

add_filter( 'parse_query', 'exclude_pages_from_admin_by_slug' );

function exclude_pages_from_admin_by_slug( $query ) { 

    global $pagenow, $post_type;

    //set the array of to be excluded slugs
    $excludeds = array( 'login', 'logout', 'lostpassword', 'register', 'resetpass' );

    //get array of IDs from array of slugs
    foreach ( $excludeds as $excluded ) {

        $excluded_IDs[] = get_page_by_path( $excluded )->ID;

    }

    if ( is_admin() && $pagenow=='edit.php' && $post_type =='page' ) {

        //exclude those IDs from query
        $query->query_vars['post__not_in'] = $excluded_IDs;

    }

}

Can't vouch for the entirety of the code from testing, and obviously it was meant to answer a different question. Since we don't have alternative code to go on, the only interest here is a model for deriving an array of to-be-excluded IDs and employing it.

4
  • As written, the code you provided threw a PHP error saying "Parse error: syntax error, unexpected end of file in..." I rewrote the code, using your idea and the base sample from the other question and it works! I also changed ( is_admin() ) to ( !is_admin) so that the pages show up for admins, but nobody else. Here's the code that works as intended: pastebin.com/qgtmVuiU Commented Apr 15, 2017 at 7:26
  • Ooops! Forgot a closing bracket... I guess I should fix... Was really just trying to demo the array, since I didn't think you were actually going to use the function as is.
    – CK MacLeod
    Commented Apr 15, 2017 at 7:31
  • Will fix it tomorrow when I'm at a regular keyboard. Too hard on phone.
    – CK MacLeod
    Commented Apr 15, 2017 at 7:33
  • Corrected... There should be a big gray check mark under the up/down vote arrows for you when you're logged in. Click that (please ;) ). I guess the objective isn't really all that common or of a really common type, but the main idea is just PHP + a single WP function, so my demonstration was probably a little over-elaborate.
    – CK MacLeod
    Commented Apr 15, 2017 at 16:31

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.