In the system that I'm building, I need the ability to mention Umbraco members in text in the website. In order to do that, I need to build an extension to Umbraco's Rich Text Editor: TinyMCE.
As a content editor, I want to tag members in a message or article so that they get notified about new content about them.
I looked at similar implementations, like in Slack or on X. Slack uses a special html tag for mentions during writing, but then sends the data to the backend with a token with a specific format. I decided to take a similar approach, but for now forget about the translation step. In content, a mention will look like this:
1 |
|
Before I started building, I was looking for ways to hook into TinyMCE in Umbraco. This is one of my least favourite things to extend in the Umbraco backoffice. I have done this before though, and I found it easiest to extend the editor if I create a decorator on Umbraco's tinyMceService in AngularJS. In TinyMCE's documentation, I found a feature called 'autoCompleters', which did exactly what I needed, so there was my hook into the editor. My initial code (without any testing yet), looked like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
I'm using vite and typescript in this project, but I don't have any types for TinyMCE installed. For now I'll keep the any and just try to avoid TinyMCE as much as possible.
I decided to use jest for testing. I found an easy getting started and I quickly managed to get something working.
✅ Success |
---|
I learned a new tool for unit testing in frontend code. I succesfully applied the tool to write a frontend with unit tests |
I wrote my first test:
mention-manager.test.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
I was somewhat surprised by the strictness of the typescript compiler. Working in steps here really meant not adding anything that you aren't actually using yet. For example, I wanted to add a reference to the "UI", because I knew I was going to use that later, but I couldn't actually compile the MentionsManager until I used everything that I put in the constructor.
After a few rounds of red, green and refactor, I ended up with these tests:
mention-manager.test.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
|
With this logic in place, I could fetch mentions from any source and show them in the RTE through the 'fetch' hook.
I used the same approach to create a 'pick' method to take the selected member and insert the mention into the editor. This is the code that I ended up with:
mention-manager.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
❓ Uncertainty |
---|
The Range interface is a built-in type that is really difficult to mock and this interface leaks an implementation detail into my business logic. I feel like there might've been a better way to do this. |
Overall, I think I ended up with simple code that is easy to change. There are still parts of this code that I don't really like. I wanted the business logic to drive the UI, but the code ended up more like a simple store that also does a single call to the UI. I wonder if I could more strongly wrap the UI to get more use out of the manager.
以上がTDD の学習: Umbraco のリッチ テキスト エディターでメンバーにタグ付けするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。