I want to override the admin/users page template when a plug in is installed.

Detail: On the user page domain.com/admin/user all the groups are listed in the sidebar area. I get this from the \vender\craftcms\cms\src\templates_layouts\cp.html file. I want to install/use use a custom template for the user page using a plug in.

What are the basics of overriding a admin template through a plugin?

Edit - More detail:

I have a plugin that creates a new controller exactly the way that is proposed in this post. The controller does two things (maybe more later):

1) On entries page it displays all the entries to a logged in user that was posted by them and others from their same group. It does not display entries that were posted by users in other groups.

2) On user page it displays only users from their own group. It does not display any other users from other groups.

On the users page all the groups are listed here:

enter image description here

It does not make sense to display all the groups here as the logged in user can only see or edit users in their own group.

I need to change what is displayed in the group listing area.

  • Basically you can overwrite the entire CP, If you want to create an entirely new interface in your CP you can do that as well. There is nothing you can't change/overwrite but we can't answer the question unless we know what you are trying to achieve in detail Commented May 26, 2018 at 20:58

1 Answer 1


There are multiple ways to achieve your goal, I think the most elegant one is to overwrite the default route /users with your custom one and replace the elementType

Things you need to do

  1. Change the default route to your template
  2. Copy the default template and change it's element type
  3. Create a custom element type that extends craft/elements/User

You can change the route of all navigation bar items (modifyCpNav)

    function(RegisterCpNavItemsEvent $event){
        // the 4th element is the "User", you can change the URL to your
        // custom template instead of the default template
        // I suggest you to loop all `navItems` and find 
        // the correct user instead of assuming it's the 4th
        // Craft::dd($event->navItems);
        $event->navItems[4]['url'] = 'path/to/template/user';

Then just copy the Craft templates/user/index template in your plugin to create an index page

{% if CraftEdition != CraftPro %}
    {% exit 404 %}
{% endif %}

{% requirePermission 'editUsers' %}

{% extends "_layouts/elementindex" %}
{% set title = "Users"|t('app') %}
// changes start
// replace the elementType with your custom element type
{% set elementType = 'prefix\\namespace\\elements\\User' %}
// changes end
{% block actionButton %}
    {% if currentUser.can('registerUsers') %}
        <a class="btn submit add icon" href="{{ url('users/new') }}">{{ "New user"|t('app') }}</a>
    {% endif %}
{% endblock %}

Then in your src/elements folder create a new User class to overwrite the sources

class User extends \craft\elements\User{ //<-- extend the default User element

     * @inheritdoc
    protected static function defineSources(string $context = null): array
        $sources = [
                'key' => '*',
                'label' => Craft::t('app', 'All users'),
                'criteria' => ['status' => null],
                'hasThumbs' => true

        // Overwrite the sources / usergroups...
        // usually Craft will search for usergroups at this place..
        // just leave it empty, so you'll only see the "default" group

        return $sources;

Don't forget to register your element

You could as well just hide the other sources via CSS/Javascript - but I would not suggest it, since everyone is able to see the other groups with minor Javascript skills

  • A few questions... Couldn't a user with a little knowledge of Craft go directly to the old admin/users page? I had an issue with $event->navItems[4]['url'] = ['template' => 'path/to/template/user'], it seems to want a text value, not an array. I replaced with $event->navItems[$x]['url'] = 'user2'; and that works. Commented May 27, 2018 at 0:46
  • Oh yeah it must be a route, I was one step too far. You can overwrite the route directly instead of changing the url as well since dynamic routes are resolved before template routes docs.craftcms.com/v3/routing.html Commented May 27, 2018 at 0:51
  • I don't seem to be able to override an admin route in the Routes section of the control panel? Commented May 27, 2018 at 1:01
  • Yes you are not, but you can do it with a Plugin Commented May 27, 2018 at 8:52
  • Having issues with the template. I added src/templates/users2/index.html and the logic that changes the url to the user page to 'users2'. I am getting a template not found error. Commented May 30, 2018 at 1:42

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.