Flutter Quill - WYSIWYG or Rich HTML Content Plugin
Content Index
- Plugin Features
- Content Initialization
- Plugin Configuration
- Delta in Flutter for Rich Text Formatting (HTML) and Using WYSIWYG
- Synchronizing Delta and HTML
- Delta is not the same as HTML and vice versa
- Delta to HTML
- HTML to Delta
- Usage Example: Content Editing
- Usage Example: Submitting Content
- Context
I'm going to show you how you can use a plugin similar to CKEditor or, in short, to WYSIWYG (What You See Is What You Get) type plugins, meaning what you see is what you get in the final content. The fundamental difference here is that HTML is not directly used, unlike any traditional web application that uses CKEditor.
Plugin Features
The plugin, as you can see on screen, allows for several configurations:
- Typography: You can change it from the control bar.
- Font Size: It can be adjusted by indicating a numerical value.
- Code Blocks: Allows inserting content with special formatting.
In summary, this plugin allows for the easy creation of rich content within a text field. What you see on screen is exactly the plugin in action, ready to edit text with different styles and formats.
https://pub.dev/packages/flutter_quill
The one called flutter_quill is this, this is the official page, and we're going to see how you configure it once installed, which is typical for the dependencies section:
dependencies:
flutter:
sdk: flutter
*
flutter_quill:You import it and here you create an instance just like you can see here, we have others. I placed the basic one, I'm showing you the configuration:
import 'package:flutter_quill/flutter_quill.dart';
*
final QuillController _controllerHtmlEditor = QuillController.basic();
@override
void dispose() {
_controllerHtmlEditor.dispose();
super.dispose();
}
*When you create your instance, remember to call dispose, as with many other resources, for example, animations.
Here, what I'm doing is initializing an existing comment. This is the way to initialize it in case you're interested:
- We get the document, which represents what the user wrote.
- A couple of functions are used that I showed you in another video, fromDelta and toHtml, to convert between Delta and HTML as needed.
_controllerHtmlEditor.document = Document.fromDelta(htmlToDelta(c)),This applies again if you are using HTML to save the content. In that case, it's important to do this conversion to Delta. If the content is being saved locally in the application, the conversion wouldn't be necessary, unless you want to work with Delta for its storage.
Content Initialization
Here you can see the result using a future function, as it is a request to my resAPI. This step is optional and only serves to initialize the content.
Plugin Configuration
The plugin configuration might seem a bit strange because it is divided into two blocks:
Toolbar: This is the upper part, where the colors, background, lists, etc., are located. This is where you define the style of the editing bar.
Content Box: In this case, optionally, I placed a small style on it to prevent an empty space from appearing. This also allows control over the line spacing and the size of the editing area.
Finally, the name of the plugin is set and the instance we created earlier is passed to it. With this, your plugin works correctly, as shown on screen.
QuillSimpleToolbar(
controller: _controllerHtmlEditor,
configurations: const QuillSimpleToolbarConfigurations(),
),
Container(
padding: const EdgeInsets.all(5),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
border: Border.all(color: Theme.of(context).primaryColor),
color: appTheme.darkTheme ? Colors.black26 : Colors.black12),
height: 300,
child: QuillEditor.basic(
controller: _controllerHtmlEditor,
configurations: const QuillEditorConfigurations(),
),
),Delta in Flutter for Rich Text Formatting (HTML) and Using WYSIWYG
I wanted to briefly discuss how you can handle Delta and HTML, giving a small introduction.
Delta is nothing more than a structure like the following: it's something similar to HTML, applying styles, but in JSON format. It's not exactly the same, although we can perform some translations between both formats.
Why is this important? Because there are certain plugins or components that you will surely need. In my case, I use this plugin, which is similar to the WYSIWYG —“what you see is what you get”— one we use in web development. In this case, it's implemented in Flutter.
Synchronizing Delta and HTML
As you can see, in my case it is for the Academy application that I use. Here, in this case, it's the CKEditor plugin and here for the comments section. As you can see, the comments for a class, and here I have the ability to place content in rich text format, just as you can see, an h1, I can put a list here—well, I didn't enable the list here, now that I see it, I'll put it later—you can use bold, etc., you can perform those types of operations.
Delta is not the same as HTML and vice versa
Here we have it, it's not exactly the same. Here I also have a style applied, meaning the underline is due to the styles, that's another topic, but essentially the HTML comes out as an h1, something similar. Again, the translation is not perfect:
[{insert: Title 1}, {insert:
, attributes: {header: 2}}, {insert: Content, attributes: {bold: true}}, {insert:
}]
<div data-v-8d2ec44a=""><h2>Title 1</h2><p><strong>Content</strong></p></div>
This is something you can see in the official documentation for each of the plugins I'm going to show you on screen. In summary, these types of plugins do not work directly with HTML and CSS, but with an equivalent called Delta, which is the format in which the information is managed internally.
Delta is what we can work with. Even so, for these types of operations where the final presentation is not so critical —for example, if the text appears in bold here and not elsewhere— there is no major problem.
However, I try to respect as much as possible the style that the person defines when writing their content, even if it is not always maintained 100%.
Delta to HTML
We have a plugin for each of these situations, which is exactly what I'm using here. Notice that I show you one for Delta to HTML:
import 'package:vsc_quill_delta_to_html/vsc_quill_delta_to_html.dart';
String deltaToHTML(List<Map<String, dynamic>> delta) {
// final deltaOps = [
// {'insert': 'Hello\n'},
// {
// 'insert': 'This is colorful',
// 'attributes': {'color': '#f00'}
// }
// ];
final converter = QuillDeltaToHtmlConverter(
delta,
// ConverterOptions.forEmail(),
);
return converter.convert();
}Here remember that Delta would be what we are going to translate, a Delta in map format, and the method we use would be the one—well, the one you can see on screen. We simply pass the Delta and it does the conversion here.
HTML to Delta
For the other one, HTML to Delta:
import 'package:flutter_quill_delta_from_html/flutter_quill_delta_from_html.dart';
Delta htmlToDelta(String html) {
try {
return HtmlToDelta().convert(html);
} catch (e) {
// return HtmlToDelta().convert('<p></p>');
return Document.fromJson([
{'insert': '\n'},
]).toDelta();
}
}Here we receive the HTML, which is basically a string, and we convert it to Delta using htmlToDelta.
const delta = htmlToDelta(html);In the same way, we can convert a Delta back to HTML using deltaToHtml. This is the inverse and is useful for saving or displaying the content. The plugins I use for these conversions are already imported and you can see them on screen. More details, examples, and configurations are available in the official documentation.
In my case, a simple configuration was enough to work correctly.
Usage Example: Content Editing
In the project, when I save content to the database, I store it as HTML. Therefore, if I want to edit that content, I must convert it to Delta so that it can be handled by the editor shown on screen.
- Step 1: Get the HTML from the database.
- Step 2: Convert that HTML to Delta using the mentioned method.
- Step 3: Set the Delta in the editor to be able to edit the content.
Usage Example: Submitting Content
When I finish editing and press submit, the content must return to the database as HTML.
First, I get the document from the editor and extract the Delta.
Then, I convert that Delta to HTML using the corresponding plugin method.
Finally, I send the HTML to the API, which will save it in the database.
This way, the application is always responsible for performing the conversions between HTML and Delta, either from HTML to Delta when loading content for editing, or from Delta to HTML when saving the changes.
Context
This flow is necessary because the Academy application was born as a web application and is now being adapted to other platforms, such as Flutter. Therefore, the conversion between HTML and Delta allows maintai
I agree to receive announcements of interest about this Blog.
I'll show you how to use the Flutter Quill plugin in Flutter to enable Rich Text in your application, and I'll also introduce a mechanism for formatting text in Flutter.