{"id":18561322,"url":"https://github.com/apostrophecms/rich-text-example-extensions","last_synced_at":"2025-10-16T16:43:50.197Z","repository":{"id":101383026,"uuid":"603440827","full_name":"apostrophecms/rich-text-example-extensions","owner":"apostrophecms","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-02T15:05:50.000Z","size":173,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-08T10:54:57.063Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apostrophecms.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-02-18T14:21:32.000Z","updated_at":"2024-05-02T15:05:55.000Z","dependencies_parsed_at":"2023-11-15T21:24:46.483Z","dependency_job_id":"def88997-83e7-4472-a2fa-c017fff69263","html_url":"https://github.com/apostrophecms/rich-text-example-extensions","commit_stats":null,"previous_names":["bodonkey/rich-text-example-extensions"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apostrophecms%2Frich-text-example-extensions","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apostrophecms%2Frich-text-example-extensions/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apostrophecms%2Frich-text-example-extensions/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apostrophecms%2Frich-text-example-extensions/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apostrophecms","download_url":"https://codeload.github.com/apostrophecms/rich-text-example-extensions/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254377631,"owners_count":22061189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T22:06:31.460Z","updated_at":"2025-10-16T16:43:45.165Z","avatar_url":"https://github.com/apostrophecms.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/apostrophecms/apostrophe/main/logo.svg\" alt=\"ApostropheCMS logo\" width=\"80\" height=\"80\"\u003e\n\n  \u003ch1\u003eApostropheCMS Rich Text Widget Example Extensions\u003c/h1\u003e\n  \u003cp\u003e\n    \u003ca aria-label=\"Apostrophe logo\" href=\"https://v3.docs.apostrophecms.org\"\u003e\n      \u003cimg src=\"https://img.shields.io/badge/MADE%20FOR%20ApostropheCMS-000000.svg?style=for-the-badge\u0026logo=Apostrophe\u0026labelColor=6516dd\"\u003e\n    \u003c/a\u003e\n    \u003ca aria-label=\"Join the community on Discord\" href=\"http://chat.apostrophecms.org\"\u003e\n      \u003cimg alt=\"\" src=\"https://img.shields.io/discord/517772094482677790?color=5865f2\u0026label=Join%20the%20Discord\u0026logo=discord\u0026logoColor=fff\u0026labelColor=000\u0026style=for-the-badge\u0026logoWidth=20\"\u003e\n    \u003c/a\u003e\n    \u003ca aria-label=\"License\" href=\"https://github.com/apostrophecms/blog/blob/main/LICENSE.md\"\u003e\n      \u003cimg alt=\"\" src=\"https://img.shields.io/static/v1?style=for-the-badge\u0026labelColor=000000\u0026label=License\u0026message=MIT\u0026color=3DA639\"\u003e\n    \u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\nThis module bundle adds three new extensions to the `@apostrophecms/rich-text-widget`. While you may find these new extensions useful, they are also a great learning resource and the basis for a series of upcoming tutorials.\n\n### Typography\nThe first extension, `@apostrophecms/typography` adds a whole series of autocomplete actions to your editor. One example, typing `(tm)` will autoconvert to `™`. For a whole list check out the [documentation](https://tiptap.dev/api/extensions/typography). Note that some auto-convert rules (like fractions) won't work if you have the insert menu turned on. You can configure this module either at the project level in the `modules/@apostrophecms/rich-text-editor/index.js` file, or in the configuration section for the rich-text-widget of individual areas.\nExample:\n```js\nwidgets: {\n  '@apostrophecms/rich-text': {\n    insert: [\n      ...\n    ],\n    toolbar: [\n      ...\n    ],\n    styles: [\n      ...\n    ],\n    typoConfig: {\n      // Will no longer convert `(tm)` to ™\n      trademark: false,\n      // Will convert `-\u003e` to `=\u003e`\n      rightArrow: '=\u003e'\n    }\n  },\n  '@apostrophecms/image': {},\n  '@apostrophecms/video': {}\n}\n```\n\nWow! Cool! Neat! But... why? Because this extension shows how to take an existing tiptap extension, that doesn't require a new button or any other control element, and add it to the rich text editor.\n\n### Smilies 😀\nThe second extension, `@apostrophecms/smilies` adds a host of keyboard shortcuts for smilie emojis, plus my favorite non-emoji ( `:ashrug `, `¯\\_(ツ)_/¯`). You can see the full list in [the code](modules/@apostrophecms/smilies/lib/replacementEmojis.js). Wow! Cool! Neat! But... isn't there a keyboard shortcut for that now? Yup, but this extension is a great way to learn how to create your own small tiptap extension and add it to the rich-text-widget! You can configure this module either at the project level in the `modules/@apostrophecms/rich-text-editor/index.js` file, or in the configuration section for the rich-text-widget of individual areas to select what skin tone (1 = lightest, 5 = darkest) for the replacement emojis. Note that not all operating systems can display skin tone emojis correctly, so some may not appear as expected.\nExample:\n\n```js\nwidgets: {\n  '@apostrophecms/rich-text': {\n    insert: [\n      ...\n    ],\n    toolbar: [\n      ...\n    ],\n    styles: [\n      ...\n    ],\n    smiliesConfig: {\n      tone: 2\n    }\n  },\n  '@apostrophecms/image': {},\n  '@apostrophecms/video': {}\n}\n```\n\n### Character Count\nThe third extension, `@apostrophecms/characterCount` allows you to display how many characters and words you have typed in your editor box. You can either open the box from the toolbar or the insert menu. If you add it to the toolbar, it will also tell you how many characters you have highlighted. You can limit the number of characters that can be added to the editor box through the configuration.\n\n```js\nwidgets: {\n  '@apostrophecms/rich-text': {\n    insert: [\n      'table',\n      'image',\n      // optionally, add here to have it appear on the insert menu\n      'characterCount'\n    ],\n    toolbar: [\n      ...\n      // optionally, add it here to have it appear on the toolbar\n      'characterCount',\n    ],\n    styles: [\n      ...\n    ],\n    charCountConfig: {\n      // How X!\n      limit: 280\n    }\n  },\n  '@apostrophecms/image': {},\n  '@apostrophecms/video': {}\n}\n```\n\nWow... okay, okay. Even I can't get that excited about this one. So, why? This extension will show you how to implement a new button on the toolbar or item in the insert menu to bring up the character count box. It will also give you a basic overview of how you would implement the Vue components for each.\n\n## Installation\n\nTo install the module, use the command line to run this command in an Apostrophe project's root directory:\n\n```\nnpm install @apostrophecms/rich-text-example-extensions\n```\n\n## Usage\n\nConfigure the modules in the `app.js` file:\n\n```javascript\nrequire('apostrophe')({\n  shortName: 'my-project',\n  // Activate the bundle -\u003e subject to change with renaming/ownership change\n  bundles: [ '@apostrophecms/rich-text-example-extensions' ],\n  modules: {\n    // The typography module\n    '@apostrophecms/typography': {},\n    // The smilies module\n    '@apostrophecms/smilies': {},\n    // The character count module\n    '@apostrophecms/characterCount': {}\n  }\n});\n```\n\nEnabling any of these modules will improve the rich-text-widget, making them available without additional configurations. You will only need to add the `characterCount` to the toolbar or insert menu (or both!) configuration as shown above.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapostrophecms%2Frich-text-example-extensions","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapostrophecms%2Frich-text-example-extensions","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapostrophecms%2Frich-text-example-extensions/lists"}