Skip to:

Opened 13 years ago

Closed 10 years ago

Last modified 9 years ago

#3278 closed enhancement (fixed)

@mentions autosuggest support

Reported by: djpaul's profile DJPaul Owned by: djpaul's profile djpaul
Milestone: 2.1 Priority: normal
Severity: normal Version:
Component: Toolbar & Notifications Keywords: dev-feedback has-patch
Cc: vivek@…, pericam@…


The attached patch adds AJAX autosuggestion of @mention names to the following screens' textareas/input boxes: comments, "What's new" activity stream box, private messaging body field, forums.

It is triggered by typing @ and at least one other character. For example, type "@a" in the new comment text area, and, assuming you have users whose names begin with an "a", it will return the results.

It has been patched into the Activity component and should be picked up by any BP-Default child themes automatically. It is also easy to add support into a non-child BuddyPress theme, though minor CSS tweaks may be needed.

Attachments (7)

autosuggest-41.patch (24.8 KB) - added by DJPaul 13 years ago.
title.jpg (30.6 KB) - added by karmatosed 13 years ago.
master...suggestions.patch (108.2 KB) - added by DJPaul 10 years ago.
master...suggestions-2.patch (43.0 KB) - added by DJPaul 10 years ago.
3278.01.patch (60.6 KB) - added by DJPaul 10 years ago.
3278.02.patch (60.5 KB) - added by imath 10 years ago.
3278.03.patch (61.6 KB) - added by DJPaul 10 years ago.

Download all attachments as: .zip

Change History (69)

13 years ago


#1 @DJPaul
13 years ago

Something to be done soon is to tweak how the results panel looks and feels as it opens, and when results are populated.

Future 'To Do' tasks for the jQuery plugin are to add keyboard up/down/return/tab support, and to dynamically swap out the regular textbox for a contentEditable div so that the inserted names can be styled differently.

Last edited 13 years ago by DJPaul (previous) (diff)

#2 @karmatosed
13 years ago

Sounds cool if ok let me do a mockup next few days and report back. I'm thinking use the already set highlight styles but take into this would be a good route. Any examples if similar functions people like / want looked at for ideas?

#3 @karmatosed
13 years ago

  • Owner set to karmatosed
  • Status changed from new to accepted

#4 @DJPaul
13 years ago

Mockups for what? The design's done.

#5 @karmatosed
13 years ago

Meant CSS.... Having a brain burp sorry

#6 @karmatosed
13 years ago

I've done some yellow highlight styling I think works and fits in with highlights hopefully. Attached screenshot but here is the CSS also.

#mentions-autosuggest li:not(.section):hover {
background: #fff9db;
background: -moz-linear-gradient(top, #fff9db 0%, #fff7d0 100%); /* FF3.6+ */
background: -ms-linear-gradient(top, #fff9db 0%, #fff7d0 100%); /* IE10+ */
background: -o-linear-gradient(top, #fff9db 0%, #fff7d0 100%); /* Opera11.10+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fff9db), color-stop(100%, #fff7d0)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #fff9db 0%, #fff7d0 100%); /* Chrome10+,Safari5.1+ */
background: linear-gradient(top, #fff9db 0%, #fff7d0 100%); /* W3C */
border-bottom: 1px solid #ffeb86;
border-top: 1px solid #ffeb86;
cursor: pointer;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9db',endColorstr='#fff7d0',GradientType=0);

13 years ago

#7 @karmatosed
13 years ago

  • Owner changed from karmatosed to DJPaul
  • Status changed from accepted to assigned

#8 @Dennissmolek
13 years ago

is this something I can turn off? My site doesnt use the @mention..

Wanted to add, looks really cool and love that you have both a regular and DEV version of the files..

Last edited 13 years ago by Dennissmolek (previous) (diff)

#9 @DJPaul
13 years ago

  • Milestone changed from Awaiting Review to Future Release

Anyone wanting to try this can download BP Labs:

#10 @DJPaul
13 years ago

  • Milestone changed from Future Release to 1.6
  • Severity set to normal

Per the dev chat, this one's mine. BP Labs has a proof of concept though it will be implemented differently.

#11 @DJPaul
13 years ago

  • Type changed from enhancement to task

#12 @DJPaul
13 years ago

To update. Per previous dev chat, implementing this with jQuery autocomplete involves rewriting all of the javascript, which is about half of the implementation. Additionally, autocomplete is part of jQuery UI; to load it, we need to first load UI Core, Widget, and (maybe) Position. And then one or two more javascripts are needed to customise autocomplete (we could bundle these into one file). Then there's need for another new javascript file to keep the core implementation of the @mentions autosuggest separate from BP-Default.

In a nutshell: we're going to be loading ~6 new javascript files on most Activity pages, Private Messaging (compose) and maybe bbPress forums. This strikes as pretty inelegant.

Is using jQuery autocomplete a must-do?

#13 @boonebgorges
13 years ago

I don't think it's necessarily must-do, as long as the custom jQuery being introduced is reusable in other parts of BP. That is, we should be able to refactor (eg) private message autocomplete to use the new stuff.

#14 @johnjamesjacoby
13 years ago

Surprised we can't just include jQuery autocomplete on its own. It would be nice to have 1 API for this and deprecate the old code from PMs.

#15 @DJPaul
13 years ago

PMs currently use

Note (2010-06-23): This plugin is deprecated and not developed anymore.
Its successor is part of jQuery UI, and this migration guide explains how to
get from this plugin to the new one.
Last edited 13 years ago by DJPaul (previous) (diff)

#16 @DJPaul
13 years ago

  • Milestone changed from 1.6 to Future Release
  • Owner DJPaul deleted

With the javascript question still open, I don't think I'll have enough time to finish this. I'm punting to a future release.

#17 @sooskriszta
10 years ago

  • Cc vivek@… added

#18 follow-up: @DJPaul
10 years ago

I've decided to pick this up again after a three year hiatus. Wow, is our current autocomplete code a bit messy :)

Doing dev here:

#19 in reply to: ↑ 18 @imath
10 years ago

Replying to DJPaul:

I've decided to pick this up again after a three year hiatus.


#20 @DJPaul
10 years ago

First thing I'm working on is to create a new endpoint/functions/tests for a single unified at-mentions system; currently both the wp-admin Groups admin and the Messages components have two slightly different implementations.

Second step will be switching those areas to use the new at-mentions code.

Third step will be proposing/implementing new UI/JS to implement the at-mentions (I already have a pretty solid idea on how I want to try this, and it shouldn't be too hard).

Finally, I'll re-visit the original idea on this ticket and see about implementing at-support everywhere it makes sense.

#21 @DJPaul
10 years ago

I've finished creating the beginning of a new Suggestions API backend. Backpat is mostly* maintained, and there are more unit tests than you can shake a stick at. Check it out here, and I'll also upload a patch version of that to this ticket.

The basic idea is the data for any current/future @mentions/auto-suggest style lookups comes from the new bp_core_get_suggestions() function. It's been built to be easily extendable by other plugins or components to implement their own kinds of automatically suggested content -- for example, #hashtags, or cross-posts -- and hopefully be more flexible for core development in the future (specifically, the other things I want to do in this ticket, and eventual integration as its own REST API endpoint).

Currently, Messages and Groups (wp-admin) have user auto-suggests. The PHP callbacks for the AJAX handlers for those methods have been rewritten to use bp_core_get_suggestions; the CSS/JS for those things remain untouched.

I say that backpat is "mostly" maintained, and it is. Here are the differences, which I don't think are worth supporting:

  • Messages: the bp_core_autocomplete_ids and bp_friends_autocomplete_ids filters have been removed (they were introduced in v1.5). See this commit for the relevant change. They were much too challenging to implement elegantly, for little gain.
  • Messages: the HTML elements added by the JS include the user's avatar, which linked back to their BP profile. The change is that the link back to the profile has been removed. I couldn't find a good way to re-implement, and at any rate, it seemed like an odd UI element to include a link on.
  • Groups: the HTML elements added by the JS used to show the user_login (if username compat mode enabled) or user_nicename, and always the user_email. They now only display the user_nicename and their display name. This was inconsistent with Messages.

#22 @DJPaul
10 years ago

  • Component changed from Activity to Notifications
  • Milestone changed from Future Release to 2.1
  • Type changed from task to enhancement

#23 @DJPaul
10 years ago

  • Keywords dev-feedback added

Feedback would be great. I would like to iterate and move quickly on this. If anyone has concerns about how i've re-worked the two existing suggest uses (in terms of the backpat issues I highlighed above), I'm totally fine with leaving that code as it already is in BP, and just using the new function/API for new stuff (or as part of a larger overhaul of those features).

#24 @boonebgorges
10 years ago

Thanks for the work on this, DJPaul. Huge improvement on what we've already got, and it's exciting to think that it'll be a good basis for future enhancements that involve autocomplete/suggest.

A question/comment about the design. I find the pattern elegant. By routing all suggestions through bp_core_get_suggestions(), you reduce the amount of duplicate code that'd otherwise be required through the components. Likewise, filtering the query args for the members suggestions in order to power group membership suggestions is clever and results in less code repetition.

But I must admit that, while elegant, it's not altogether straightforward. In order to understand how the group member suggestions work, you have to follow the filter train back through 'bp_members_get_suggestions', which itself is a callback that is indexed by the 'type' param passed to bp_core_get_suggestions(). This is not transparent for the developer who's looking to add custom suggestions to her own plugin.

I don't have any super concrete suggestions for more straightforward designs. One very rough idea is to have an abstract class BP_Suggestions that handles some of the basic sanitization and authorization logic that is currently in bp_core_get_suggestions(). It would have abstract methods along the lines of validate_params() (see bp_friends_suggestions_filter_query_args()) and get_item_data() (which would contain the actual query logic). Use would then be something like: $gm_suggestions = new BP_Group_Member_Suggestions(); $gm_suggestions->setup( $args ); $gm_suggestions->get_results();

This is not fundamentally different from what you're doing (you could even daisy-chain Friends and Group Members classes on top of the central Members suggestions, much as you've done here), but it would put things together in a way that might be a bit easier to understand than the current system of (1) registering the service by filtering 'bp_suggestions_get_types', (2) passing a callback to bp_core_get_suggestions(), and then perhaps (3) filtering some query arguments when extending an existing suggestions service. With an abstract class, everything would be in one place, and there'd be no filtering required.

Again, this is just a thought. If others prefer your design, I'm happy enough with it, and won't say another word. I'm just trying to think about how easy to parse this will be for the newcomer.

#25 @DJPaul
10 years ago

I had considered using classes at one point for this but decided that while it would provide some means of code re-use, the data being represented wasn't really OO (or going to benefit much from being built like that), and decided against it after sketching out some ideas.

Thanks for the feedback, Boone. I'll give it some thought and see what I can come up with.

#26 @boonebgorges
10 years ago

Agreed that the data is not really object like, but the class has the advantage of making the API centralized. Anyway, thanks for considering the thoughts.

#27 @DJPaul
10 years ago

I'm having a bunch of trouble getting a patch from Github, but I think I have it: check out master...suggestions-2.patch. It re-implements the older patch along the lines of what I think Boone was suggesting. There's more duplication in this code patch, but I think it is more understandable.

#28 @boonebgorges
10 years ago

Patch applies cleanly for me.

Thanks a million for this, DJPaul. In my (humble) opinion, it's much more understandable - it's fairly obvious, by looking at a class like BP_Members_Suggestions, how to build my own suggestion service.

One small architectural suggestion. It would make implementation a bit simpler if bp_core_get_suggestions() took a class parameter rather than requiring type and then translating that into a class name. True, a few more characters to type in the case of core-provided services; but one less thing to do when building one's own service (no need to add_filter( 'bp_suggestions_services' )). The only reason I can see for forcing the registration of the service is if we needed to have a list of registered services somewhere (say, to build an admin UI that lists all suggestion types?), but nothing like that is being proposed here, so I think it's unneccesary overhead. And if we ever decided we needed a list of these classes, we could in theory do something like Anyway, not a dealbreaker, just a thought.

Approach looks great to me otherwise.

#29 @r-a-y
10 years ago

About the BP_Members_Suggestions class code being in bp-core-classes.php instead of bp-member-classes.php, see #5436.

Other than that, I've got nothing really to add. Patch works great!

#30 @DJPaul
10 years ago

Thanks chaps :)

#31 follow-up: @johnjamesjacoby
10 years ago

This looks super awesome.

Tangent; after reading this:

 * This class is in the Core component because it's required by a class in the
 * Groups component, and Groups is loaded before Members (alphabetical order).

I have a hunch we should be forcing Members to load immediately after Core; it's essentially an extension of the Core component. Obviously any moving around would need testing, but we should probably institute some kind of load order parameter to provide some sanity outside of the alphabetical slurp.

Last edited 10 years ago by johnjamesjacoby (previous) (diff)

#32 @DJPaul
10 years ago

Boone, I'm not totally sold by the suggestion of using a string parameter to provide a class name. It feels a bit weird as far as design patterns go in the WordPress world, and it could introduce unnecessary backwards compatibility restraints if we ever decided to rename things in the future.

The bp_suggestions_services filter itself doesn't/isn't intended to do anything like providing a list of registered services; it's just there as a place for other plugins to add filters to, to add a new suggestions service. If anything, the older/first patch's approach to registering services was much more structured than this. I think I'm going to commit as-is for now, but as always, your feedback is greatly appreciated.

#33 in reply to: ↑ 31 @DJPaul
10 years ago

I have a hunch we should be forcing Members to load immediately after Core

Yep, would be nice. :)

#34 @r-a-y
10 years ago

I have a hunch we should be forcing Members to load immediately after Core

See ticket:5436#comment:2.

#35 @djpaul
10 years ago

In 8557:

at-mentions: overhaul the mentions implementation for Private Messages and Groups (admin) components.

Previously, these components had seperate implementations of username auto-suggestions, which weren't
reusable outside of where they'd been built, nor easily extended by developers, or other plugins.
This change creates a central API for auto-suggestions, currently only for usernames, but easily
extensible for other kinds of auto-suggestions in the future (i.e. group names, or #hashtags).

See #3278

#36 @DJPaul
10 years ago

Per a note I left on #5735, I am going to soft-deprecate some (not all) existing JS that we use for our existing auto-suggestions. All I'll be doing is moving a few existing third-party JS libs that we use into the core/deprecated folder; nothing else will change. wp_register_script, which we use already, will maintain backwards compatibility for any plugin/theme authors who enqueue/require scripts correctly.

I do not know if this ticket's proposed at-mentions changes will be ready for 2.1 yet, but even if they don't make the cut, this change will still be worthwhile in terms of the bigger picture of identifying what JS we want/don't want any more.

#37 @djpaul
10 years ago

In 8559:

Messages: soft-deprecate existing autocomplete CSS/JS by moving assets into deprecated folder.

Functionality hasn't been changed, the scripts have just been moved. Eventually, these will be
replaced by a newer auto-suggest JS/UI, then these will be used just for backwards compatibility
with old themes.

See #3278 and #5735.

This ticket was mentioned in IRC in #buddypress-dev by jjj. View the logs.

10 years ago

This ticket was mentioned in IRC in #buddypress-dev by paulgibbs. View the logs.

10 years ago

10 years ago

#40 @DJPaul
10 years ago

  • Keywords has-patch added

I've just added 3278.01.patch which brings auto-suggestions to @mention lookups. I encourage interested folks to test it out. Here is a high-level overview of the patch:

  • Adds two new third-party libraries; At.js and its dependency, Caret.js. At.js handles the suggestions UI, including fetching suggestions from the server.
  • For our At.js implementation, we've built on top of a number of CSS tweaks and JS adaptations that have been taken from Automattic's O2 theme (which uses At.js).
  • @mentions suggestions are implemented in the following areas: Activity update/reply forms, WordPress post comments, and wp-admin's new/edit post screens (but only in the "Text" editor, not "Visual").
    • Some progress has been made on supporting contentEditable areas (such as WP's "Visual" editor), but there are a number of bugs and Internet Explorer quirks that need to be resolved before it will work reliably.
    • I suggest we don't highlight "Text" editor view support in the release notes, and wait until we finish "Visual" editor support in/for BP 2.2.
  • If the Friends component is active, and if the user has any friends, we're storing those friends' details in a JS global which At.js uses to pre-populate its lookup list (see bp_friends_prime_mentions_results). This makes it feel super fast and responsive.
    • If a match isn't found, At.js makes an AJAX request back to the server to get results.
    • I've iterated on the search_wildcard parameter I added in r8675 to better handle lookup of surnames (and similarly formatted data).

#41 @DJPaul
10 years ago

Oh, to test this: make sure you've got some Friends or multiple users on your test site, go to one of the supported text areas, and type @.

If you prefer to look at the code on Github rather than a patch, go here:

Last edited 10 years ago by DJPaul (previous) (diff)

#42 @r-a-y
10 years ago

Love it, DJPaul!

Some tiny, tiny things:

  • In bp_activity_mentions_script(), can we break out the following logic to a filterable function so it can be potentially hooked by plugins?
if ( ! bp_activity_do_mentions() || ! bp_is_user_active() || ! ( bp_is_activity_component() || bp_is_blog_page() && is_singular() && comments_open() ) )
  • In mentions.js, for the 'suffix', can we add a space? This is to emulate Twitter and Github.
  • For consistency, can we change the red text colour to the blue that we use when the #whats-new textarea is in focus or a similar hue to that?

Other than that, looks solid!

Last edited 10 years ago by r-a-y (previous) (diff)

#43 @imath
10 years ago

DJPaul, this is great ! Just tested it and as r-a-y I'm loving it!

I agree with r-a-y about the text color. I'm adding 3278.02.patch (--no-prefix version) so that it will be easier for others to test as it's super awesome :)

10 years ago

#44 @DJPaul
10 years ago

The blue colour on the activity form was introduced by me back in #3360 and if I remember correctly, it was a colour that I pinched directly from Twitter. I am not interested in arguing about colours but I would like us generally to start using a subtle BuddyPress orange/red for highlighting bits of our UI that need to be strongly styled (such as this auto-suggest).

This ticket was mentioned in IRC in #buddypress-dev by paulgibbs. View the logs.

10 years ago

#46 follow-up: @DJPaul
10 years ago

In mentions.js, for the 'suffix', can we add a space

We could, but the goal here isn't to duplicate exactly how Twitter or Github's auto-complete work. :) In my experience with (heavily) using auto-suggestions in O2, I think no suffix works better. There's an interesting point on an at.js issue about this (, which I'll copy here:

...then no space is added when you insert a match. The completions list stays open, but you can then type a comma, period, or space (or whatever) which will hide the completions list. This preserves a more natural flow if you're using the UI completely via keyboard (type, @something, enter/tab to insert, then "!" to end a sentence for example).

At any rate, this would be an easy one-line change to make.

10 years ago

#47 @DJPaul
10 years ago

Added a bp_activity_maybe_load_mentions_scripts function per R-a-y's comments. Also has the beneficial affect of preventing bp_friends_prime_mentions_results making useless DB queries on pages where we aren't loading suggestions.

#48 in reply to: ↑ 46 @sooskriszta
10 years ago

Replying to DJPaul:

...then no space is added when you insert a match. The completions list stays open, but you can then type a comma, period, or space (or whatever) which will hide the completions list. This preserves a more natural flow if you're using the UI completely via keyboard (type, @something, enter/tab to insert, then "!" to end a sentence for example).


#49 @djpaul
10 years ago

In 8753:

Core: adjust the SQL generated by BP_User_Query's search_wildcard parameter for better Suggestions API search results.

Introduced in r8675, the search_wildcard parameter controls where BuddyPress places MySQL wildcard characters around the search term (when it's set).

This change adjusts how the wildcard SQL is constructed; in addition to the wildcard, we now also check for matches that have a single space character at the opposite end of the string (from where the wildcard is). This allows searching data that looks like (for example) a surname in a combined first name/surname field.
e.g. if a displayname is "Paul Gibbs", you can search for "Gi", and with search_wildcard=right, the SQL generated will be LIKE 'Gi%' OR LIKE '% Gi%'.

See #3278

#50 @djpaul
10 years ago

  • Owner set to djpaul
  • Resolution set to fixed
  • Status changed from assigned to closed

In 8754:

Activity: introducing @mentions auto-suggestions.

Activity has long-supported @mentions, where you can mention the name of another user to get their attention in a conversation. You've always had to know the exact username of the person you're trying to mention, or you've been forced to go look it up. Now, when leaving an activity update or reply, press @ and then start typing someone's diaply name (or user_nicename), and username suggestions will automatically appear below where you're typing.

If the Friends component is active, and if the logged-in user has any friends, those friends' details are used to pre-prime the username suggestions for super-fast snappy suggestions. Suggestions are also provided when writing a blog post comment.

This change has mostly been implemented using two third-party libraries, At.js ( and Caret.js ( Big thanks to those projects' authors for their fine work, and also to Automattic's O2 team, who made a number of CSS+JS tweaks/adaptions to At.js, which we've adopted. Props also to karmatosed for design suggestions on the earliest implementation of this feature, three years ago. :)

Fixes #3278

#51 @djpaul
10 years ago

In 8771:

Activity: slight CSS/JS tweaks to @mentions window.

Ported from Automattic's O2 team's implementation of the At.js library.

See #3278

#52 @djpaul
10 years ago

In 8773:

Activity: Combine the @mentions enqueuing function.

Previously, there was a function for loading in both admin and frontend contexts.
I've combined the loading into one function which removes a bunch of duplicated logic, probably left over from an early approach at building the suggestions feature.

See #3278

#53 @johnjamesjacoby
10 years ago

Can we revert r8773, or think about refactoring this to have less repetition and still have front/back-end hooks?

Theme authors need a sane way to unhook this functionality if they don't need it, that doesn't also impact our own core administrative functionality.

#54 @johnjamesjacoby
10 years ago

Disregard the previous comment. That commit message reads like you combined everything together. After looking at the code in final, it's fine as is.

#55 @djpaul
10 years ago

In 9006:

Activity: @mentions theme compatibility improvement

Some themes add margin-top to images (e.g. "Eighties"), and we need to remove that here so that the Gravatar lines up with the text.

See #3278

#56 @djpaul
10 years ago

In 9008:

Activity: @mentions RTL fixes

The suggestions window was being stretched full width, due to the mentions.js only setting .left (after left had been set in the CSS), but in RTL, right had been set, causing a full-width window.

See #3278, #5855

#57 @Zane
10 years ago

Any way to add this feature to BBPress topic creation or replies?

#58 @imath
10 years ago

Hi Zane,

there's a ticket about this in bbPress's trac

In the meantime, you can try this gist :

#59 @Stagger Lee
9 years ago

  • Cc pericam@… added

#60 follow-up: @Stagger Lee
9 years ago

Need to ask, it is very important. Sorry for off topic.
Is it possible to subscribe to tracs without adding comment like I just did ? It is something only on bbPress and buddyPress tracs, not on WP core trac.

I am asking because I feel bad to send lot of emails to all people on each trac just because I subscribed to it.

Can it be done silently as on WP core trac ?

#61 @DJPaul
9 years ago

Don't worry about other people if you want to subscribe to any particular trac ticket. It's great if you want to follow along. :)

I don't think there's a way to subscribe silently, but there is a way to subscribe to *every* ticket, but then you get a lot of emails. :)

#62 in reply to: ↑ 60 @netweb
9 years ago

Replying to Stagger Lee:

Can it be done silently as on WP core trac ?

Not yet, but it is planned, see or subscribe to #meta291

Note: See TracTickets for help on using tickets.