Skip to content

Instantly share code, notes, and snippets.

@songjiz
Created March 15, 2019 11:08
Show Gist options
  • Save songjiz/7256eaf4aae6f8d3505bf6ac9aa17e5a to your computer and use it in GitHub Desktop.
Save songjiz/7256eaf4aae6f8d3505bf6ac9aa17e5a to your computer and use it in GitHub Desktop.

Implementing rich-text mentions with Action Text

  1. Mix ActionText::Attachable into your mentionable person model:

    class Person < ApplicationRecord
      include ActionText::Attachable
    
      # ...
    end
  2. Implement a server-side endpoint that returns a list of mentionable people. For each person, provide the result of calling #attachable_sgid, rendered mention markup, and anything you need to filter autocomplete results client-side.

    [
      {
        "name": "George Claghorn",
        "sgid": "BAh7CEkiCGdpZAY6BkVUSSImZ2lkOi8vc2FuZGJveC9QZXJzb24vMT9leHBpcmVzX2luBjsAVEkiDHB1cnBvc2UGOwBUSSIPYXR0YWNoYWJsZQY7AFRJIg9leHBpcmVzX2F0BjsAVDA=--fa632245bb1b8ac891f23f84e9053a06e57dcc37",
        "content": "<span class=\"mention\"><img src=\"...\" class=\"avatar avatar--tiny\"> George</span>"
      }
    ]
  3. Determine when the user has started a mention. Unfortunately, this is a little “draw the rest of the owl” at the moment. We haven’t published our implementation at Basecamp. Here’s how my colleague Javan described it:

    At a high level, we listen for trix-change, use editor.getPosition() and editor.getDocument().toString() to determine what character was typed, and position the autocomplete options using editor.getClientRectAtPosition().

  4. When the user commits to a mention—for example, by clicking on one of the autocomplete results or pressing Enter—use Trix’s content attachment API to insert it. Make sure to provide the mentioned person’s attachable_sgid in the attachment’s sgid attribute:

    import { Attachment } from "trix";
    
    // ...
    
    let attachment = new Attachment({ sgid: mention.sgid, content: mention.content });
    editorElement.editor.insertAttachment(attachment);
  5. When displaying rich-text content containing mentions, Action Text automatically renders the people/_person.html.erb partial for each mentioned person (just like it automatically renders active_storage/blobs/_blob.html.erb for file attachments).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment