Query Users
This page covers how to query WordPress users.
User loops list authors with a published post. To list the members of a role, make it public in Settings > Privacy and filter the loop on it. Filtering on another role, or on a capability, returns no user until Roles is opened there. See Private Data.
Basic usage
Paste this directly into the query arguments editor in the Loop block's sidebar:
[
'number' => 10,
'orderby' => 'display_name',
'order' => 'ASC',
]
Common arguments
Arguments follow the WP_User_Query API — any argument it accepts works here too.
| Argument | Description | Example |
|---|---|---|
role | User role (a public role, or any once Roles is opened) | 'author', 'editor' |
role__in | Multiple roles (OR) | ['editor', 'author'] |
role__not_in | Exclude roles | ['subscriber'] |
orderby | Sort field, display_name by default | 'display_name', 'post_count' |
order | Sort direction | 'ASC', 'DESC' |
number | Limit results, 10 by default | 10 |
has_published_posts | Only users with posts | true, ['post'] |
include | Include specific IDs | [1, 2, 3] |
exclude | Exclude specific IDs | [1] |
search | Search by name | '*john*' |
Visitors only see authors with a published post: has_published_posts always applies, unless the loop filters on roles made public in Settings > Privacy. A filter on a user meta key needs that key public too, ACF and other field plugins' fields included: add it to Settings > Privacy > Public meta keys.
More query examples
Team page
[
'has_published_posts' => ['post'],
'orderby' => 'display_name',
'order' => 'ASC',
]
Authors with post counts
[
'has_published_posts' => ['post'],
'orderby' => 'post_count',
'order' => 'DESC',
]
Contributors (multiple roles, Roles opened)
[
'role__in' => ['author', 'editor', 'contributor'],
'orderby' => 'display_name',
]
Staff by role (the staff role opened as public users)
[
'role' => 'staff',
'orderby' => 'display_name',
'order' => 'ASC',
]
Template examples
In the HTML inspector, the Loop block uses get_users() syntax. Query arguments are managed by the sidebar — the inspector shows get_users() with empty parentheses to keep the template readable.
Staff directory with custom fields
{% for user in get_users({role: 'staff'}) %}
<div class="staff-card">
<img src="{{ user.avatar({size: 120}) }}" alt="{{ user.name }}">
<h3>{{ user.name }}</h3>
<span class="department">{{ user.meta('department') }}</span>
<span class="phone">{{ user.meta('phone') }}</span>
<a href="mailto:{{ user.user_email }}">{{ user.user_email }}</a>
</div>
{% endfor %}
The email and the department and phone meta keys are private: open them in Settings > Privacy, and make the staff role public there if its members do not publish posts: the loop lists them because it filters on that role.
Simple author box (single post)
This doesn't need a loop — use the author provider directly on a single post template:
<div class="author-box">
<img src="{{ author.avatar({size: 96}) }}" alt="{{ author.name }}">
<h4>{{ author.name }}</h4>
<p>{{ author.meta('description') }}</p>
<a href="{{ author.link }}">All posts by {{ author.name }}</a>
</div>
Without number, you only get the first 10; with number: -1, a site with thousands of listed users (e.g., a membership site with members opened) becomes very slow.
Next steps
- User provider — all fields available on user items
- get_posts() — query posts by a specific author
- Loop — loop concept and data sources