Closed mattbloomfield closed 2 months ago
So if we're going by the Creating a custom Node from scratch user guide, that's a good start. From this you can add your own Node or Mark to Tiptap.
Extensions are also supported, which something like a character counter is - not a Node or a Mark, but "something" attached to Tiptap for all sorts of things.
In your own JS file, you can access Tiptap core functions, but those are really for extending or creating with their things. For example:
// modules/vizymodule/src/assets/js/emoji.js
document.addEventListener('onVizyConfigReady', (e) => {
const { Node } = Craft.Vizy.Config.tiptap.core;
const Emoji = Node.create({
name: 'emoji',
Otherwise, you'd have to install Tiptap yourself in your own dependencies to access Node
, which is a waste of time with Tiptap already being loaded. In fact, you can see that we're using registerExtensions
which is what you'll likely do.
What this doesn't cover is access to Vizy's instance of the Tiptap editor. That's all just providing access to the JS classes, and nothing about the instance of the Vizy field or Tiptap editor.
Getting the const {Editor} = Craft.Vizy.Config.tiptap.core;
isn't going to be useful here.
What I would highly recommend is to use Tiptap's own CharacterCount
extension, which will make things easier!
import CharacterCount from '@tiptap/extension-character-count';
document.addEventListener('onVizyConfigReady', (e) => {
Craft.Vizy.Config.registerExtensions((extensions) => {
return [
CharacterCount.configure({
limit: 240,
}),
];
});
});
You'll need to run npm install @tiptap/extension-character-count
according to the TipTap docs in your own JS.
Then you might want to go about rendering the character counts in the field. Now that is an interesting idea, and I'm not quite sure how to go about that. If this were a case of you writing the Vue template yourself, you could just output it like their docs state:
<template>
<div>
<editor-content :editor="editor" />
<div class="character-count" v-if="editor">
{{ editor.storage.characterCount.characters() }}/{{ limit }} characters
<br>
{{ editor.storage.characterCount.words() }} words
</div>
</div>
</template>
But that's not going to work, as Vizy is the one to output the <editor-content>
element. We would need a method of hooking into template rendering, but I'm not sure how we can make that flexible on where you want to put the template content in the Vizy field.
Okay, so I've added the ability to insert Vue template alongside the editor, which I think will help in your instance. You can use the below code in your JS.
import CharacterCount from '@tiptap/extension-character-count';
document.addEventListener('onVizyConfigReady', (e) => {
Craft.Vizy.Config.registerExtensions((extensions) => {
return [
CharacterCount.configure({
limit: 240,
}),
];
});
Craft.Vizy.Config.registerTemplates(() => {
return {
position: 'afterEditor',
template: `<div class="character-count" v-if="editor">
{{ editor.storage.characterCount.characters() }}/240 characters
<br>
{{ editor.storage.characterCount.words() }} words
</div>`,
};
});
});
Which will now all the template code into the editor.
Added for the next release. To get this early, run composer require verbb/vizy:"dev-craft-4 as 2.1.17"
.
Dude unreal. I’ll check it out and let you know how it works.
Matt Bloomfield
On Sat, Apr 6, 2024 at 04:40 Josh Crawford @.***> wrote:
Okay, so I've added the ability to insert Vue template alongside the editor, which I think will help in your instance. You can use the below code in your JS.
import CharacterCount from @.***/extension-character-count'; document.addEventListener('onVizyConfigReady', (e) => { Craft.Vizy.Config.registerExtensions((extensions) => { return [ CharacterCount.configure({ limit: 240, }), ]; });
Craft.Vizy.Config.registerTemplates(() => { return { position: 'afterEditor', template: `<div class="character-count" v-if="editor"> {{ editor.storage.characterCount.characters() }}/280 characters <br> {{ editor.storage.characterCount.words() }} words </div>`, }; });});
Which will now all the template code into the editor.
Added for the next release. To get this early, run composer require verbb/vizy:"dev-craft-4 as 2.1.17".
— Reply to this email directly, view it on GitHub https://github.com/verbb/vizy/issues/294#issuecomment-2041056382, or unsubscribe https://github.com/notifications/unsubscribe-auth/AI6XNVQRYFRYZMDJMF5O6DTY37NJRAVCNFSM6AAAAABFWAAPRWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANBRGA2TMMZYGI . You are receiving this because you authored the thread.Message ID: @.***>
Added in 2.1.18
Question
Hey Josh,
Trying to add a character counter to a vizy field and really struggling to figure out how to do it. Admittedly this is my first time attempting to interact with the tiptap API so I may be misguided.
What works so far is that I have created a Vizy plugin, it gets added to the config and picked up such that a console.log from the plugin runs when my Vizy field is on the page.
From there though, I can't figure out a reliable way to hook into the tiptap events. If I do a do/while loop in JS I can wait for the Vizy text to be on the page, then get the number of characters using vanilla js. However, I cannot seem to add an event listener for changes to the text. Could you give me a few tips?
I see that I can access tiptap's core via something like
const {Editor} = Craft.Vizy.Config.tiptap.core;
but even with that, I can't tell if that's connected into the Vizy Editor on the page. It also doesn't seem to quite match the API found here: https://tiptap.dev/docs/editor/api/editor. Am I looking in the right place?Additional context
No response