I'm going to be using add_role() and $role->add_cap() to set up a new custom role and attach a new capability to existing roles.

I'm wondering where the best place to do this is? Obviously I can do it straight inside functions.php and be done with it. But is this the best practice? Do I only need to do this on admin_init? or should I do it on init?

I'm not entirely sure what the best practices are around using init action hooks rather than just dropping a direct function call inside functions.php.

thanks for your input!

2 Answers 2


When adding a role and capabilities you only need to run the code once since the roles and capabilities are saved to the database when using add_role or ->add_cap functions so just like Andy said you can use after_setup_theme for this kind of action but add some kind of check so it only runs once, like register_activation_hook or using options:


function my_add_role_function(){
    $roles_set = get_option('my_roles_are_set');
        add_role('my_role', 'my_roleUser', array(
            'read' => true, // True allows that capability, False specifically removes it.
            'edit_posts' => true,
            'delete_posts' => true,
            'upload_files' => true 
  • 1
    Thanks for this. Is it true that add_role or add_cap ALWAYS leverages the database? When I dug into the source code it seemed this was not always the case - ie: in most of the methods of WP_Roles, there's a check for if ($this->use_db), which makes me think that there is the possibility that roles might not be always stored in the DB.
    – Tom Auger
    Commented Apr 7, 2011 at 14:25
  • Also, rather than setting a flag using options, which doesn't strike me as particularly scalable, is there not a way to simply query whether the role has been created? Failing that, what harm would it do to re-define the role if it's already there? Would you get a duplicate role or would it just ignore? Looking again at capabilities.php I see this under add_role: if ( isset( $this->roles[$role] ) ) return; which seems to indicate that it won't duplicate the role so no harm done.
    – Tom Auger
    Commented Apr 7, 2011 at 14:28
  • Not sure what you mean but the defualt is $use_db = true; in the WP_Roles class. and as for setting a flag using options , it is an example, you can use register_activation_hook but the idea is that your code would only run once and that way you save yourself the time of excution.
    – Bainternet
    Commented Apr 7, 2011 at 15:30
  • I've never seen this through, but it strikes me that it might make sense to put role changes into a plugin and then take advantage of the activation/deactivation hooks to trigger the changes just once. Has anyone ever gone down that route?
    – mrwweb
    Commented Jun 19, 2013 at 20:51
  • @mrwweb that should work just fine as well
    – Bainternet
    Commented Jun 19, 2013 at 22:06

For plugins, I have had success using plugins_loaded for this. For themes, I would use after_setup_theme.

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.