WP Manifestindependent plugin directory
manifest / users / easy-profile-mentions

Easy Profile Mentions

Type @ in the WordPress block editor or comment form to tag user profiles. Supports WordPress, BuddyPress, and bbPress.

by Flex Perception · github.com/flexseth/easy-profile-mentions · website

0stars
0forks

Install

No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:

wp plugin install https://github.com/flexseth/easy-profile-mentions/archive/refs/heads/trunk.zip

Readme

Easy Profile Mentions

Type @ in the WordPress block editor or comment form to tag user profiles. A live dropdown appears as you type — select a user to insert a linked mention.

Supports WordPress user accounts, BuddyPress profiles, and bbPress profiles.


Requirements

Requirement Minimum
WordPress 6.4
PHP 7.4
Node.js 18+ (build only)
MySQL 5.7

Installation

From source (development)

# 1. Clone or copy the plugin into your WordPress plugins directory
cd wp-content/plugins/

# 2. Install JS dependencies and build assets
cd easy-profile-mentions
npm install
npm run build

# 3. Activate in WordPress Admin → Plugins

From a zip

  1. Download or export the plugin folder as a .zip
  2. Go to WordPress Admin → Plugins → Add New → Upload Plugin
  3. Upload the zip and click Activate

The build/ directory must be present. If it is missing, run npm install && npm run build before zipping.


How to use

In the block editor

  1. Open any post, page, or custom post type in the block editor
  2. Click into a Paragraph, Heading, Quote, or any other rich-text block
  3. Type @ followed by at least one character (e.g. @jane)
  4. A dropdown appears showing matching users with their avatar and display name
  5. Click a user or use Arrow keys to navigate and Enter to select
  6. The mention is inserted as a linked @Display Name inline element

In comment forms

  1. Navigate to any post with comments enabled
  2. Type @ followed by a name in the Comment textarea
  3. The same autocomplete dropdown appears
  4. Select a user — their mention is inserted at the cursor
  5. Submit the comment as normal

Comment autocomplete requires the visitor to be logged in. Raw @username tokens typed by non-logged-in users are still resolved to profile links when the comment is displayed.

Keyboard shortcuts (dropdown)

Key Action
Move selection down
Move selection up
Enter or Tab Insert selected mention
Escape Close dropdown

Profile URL resolution

The plugin resolves profile URLs in this order:

  1. BuddyPressbp_core_get_user_domain() (if BuddyPress is active)
  2. bbPressbbp_get_user_profile_url() (if bbPress is active)
  3. WordPressget_author_posts_url() (always available as fallback)

To override the URL for a specific user, use the epm_profile_url filter:

add_filter( 'epm_profile_url', function ( $url, $user_id ) {
    // Return a custom URL for user ID 42.
    if ( 42 === $user_id ) {
        return 'https://example.com/members/jane/';
    }
    return $url;
}, 10, 2 );

REST API

The plugin registers a single read-only endpoint used by the autocomplete dropdown.

GET /wp-json/epm/v1/users

Authentication: Requires a logged-in user with the read capability. Send the REST nonce in the X-WP-Nonce header (automatically handled by the editor and comment form scripts).

Parameters:

Parameter Type Default Description
search string "" Partial display name, login, or email
per_page integer 8 Max results (1–20)

Example request:

GET /wp-json/epm/v1/users?search=jane&per_page=5
X-WP-Nonce: abc123

Example response:

[
  {
    "id": 42,
    "slug": "jane-doe",
    "login": "janedoe",
    "displayName": "Jane Doe",
    "profileUrl": "https://example.com/members/jane-doe/",
    "avatar": "https://www.gravatar.com/avatar/…?s=48"
  }
]

Results are cached as transients for 5 minutes. The cache is automatically flushed when a user profile is updated, a new user is registered, or a user is deleted.


Hooks & filters

epm_profile_url

Override the resolved profile URL for any user.

apply_filters( 'epm_profile_url', string $url, int $user_id )

epm_user_query_args

Modify the WP_User_Query arguments used for searching.

apply_filters( 'epm_user_query_args', array $args, string $search )

epm_user_search_results

Filter the full results array before it is returned by the REST endpoint.

apply_filters( 'epm_user_search_results', array $results, string $search )

epm_format_user

Filter a single user row before it is included in the REST response.

apply_filters( 'epm_format_user', array $data, WP_User $user )

Example — add a custom field to every result:

add_filter( 'epm_format_user', function ( $data, $user ) {
    $data['jobTitle'] = get_user_meta( $user->ID, 'job_title', true );
    return $data;
}, 10, 2 );

Styling mentions

Mentions render as <a> elements with the class epm-mention and a data-user-id attribute:

<a class="epm-mention" href="/members/jane-doe/" data-user-id="42">@Jane Doe</a>

Override the default styles in your theme:

.epm-mention {
    color: #0073aa;
    font-weight: 600;
    text-decoration: none;
}

.epm-mention:hover {
    text-decoration: underline;
}

Target a specific user:

.epm-mention[data-user-id="42"] {
    color: #d63638;
}

Development

# Install dependencies
npm install

# Build for production (outputs to build/)
npm run build

# Watch for changes during development
npm start

# Lint JavaScript
npm run lint:js

# Lint CSS/SCSS
npm run lint:css

# Format files
npm run format

# Create a distributable zip
npm run plugin-zip

File structure

easy-profile-mentions/
├── easy-profile-mentions.php   # Plugin bootstrap & asset registration
├── readme.txt                  # WordPress.org readme
├── README.md                   # This file
├── package.json
├── src/
│   ├── index.js                # Registers epm/mention rich-text format
│   ├── mention-autocomplete.js # Block editor autocomplete completer
│   ├── view.js                 # Interactivity API store (comment form)
│   ├── editor.scss             # Editor-only styles
│   └── style.scss              # Shared front-end + editor styles
├── build/                      # Compiled output (generated, not committed)
├── includes/
│   ├── rest-api.php            # REST endpoint: GET epm/v1/users
│   ├── comment-support.php     # Comment text filter + form directives
│   └── integrations.php        # BuddyPress / bbPress URL resolution
└── assets/
    └── css/
        └── epm-mention.css     # (optional) standalone stylesheet

Frequently asked questions

Does the plugin create database tables? No. It uses WP_User_Query, the WordPress Transients API for caching, and no custom tables.

Do cached pages break mentions? No. Mentions are stored as plain <a> elements in post content, so full-page caches (WP Super Cache, W3 Total Cache, etc.) serve them correctly. The REST search endpoint is only called inside authenticated editor sessions.

Does it work with Multisite? Yes, but user searches are scoped to the current site. To search across the network, use the epm_user_query_args filter to modify the query.

Can non-logged-in users trigger mention autocomplete? No — the REST endpoint requires authentication. Visitors who type @username manually in a comment will still have those tokens converted to profile links when the comment is displayed.


Changelog

1.0.0

  • Initial release
  • Block editor @ autocomplete via registerFormatType + editor.Autocomplete.completers
  • Interactivity API store for comment form live autocomplete
  • REST endpoint epm/v1/users with nonce verification and transient caching
  • BuddyPress and bbPress profile URL resolution
  • @username → profile link parsing in comment display
  • Hooks: epm_profile_url, epm_user_query_args, epm_user_search_results, epm_format_user

License

GPL-2.0-or-later — see https://www.gnu.org/licenses/gpl-2.0.html

Read the full README on GitHub →