Skip to content

Rich Editor ​

The richeditor field edits formatted text with a toolbar, menus that appear on the selection and an HTML source view, built on TipTap. It saves the content as HTML. The editor loads the first time a page shows a rich editor field.

Default toolbar ​

With no options, the toolbar has paragraph formats, alignment, bold, italic and underline, ordered and unordered lists, snippets, tables, links, images, a horizontal line and the HTML view. Selecting a link, an image or a table opens a menu of its own, such as image alignment or table rows and columns.

Without more setup, images go in by address, links open a form for the address, and the snippet button stays disabled. Uploads add Upload from Computer to the image menu, and page hooks connect a media picker, a page link picker and snippets.

yaml
fields:
    overview:
        label: Overview
        type: richeditor
        comment: Select text for formatting, or use the toolbar above it.

Toolbar buttons ​

toolbarButtons lists the buttons in order, with '|' for a separator. It also takes a pipe separated string, such as bold|italic||insertLink, where a double pipe is a separator. The list is used exactly as given.

yaml
fields:
    key_points:
        label: Key Points
        type: richeditor
        toolbarButtons: [bold, italic, underline, '|', formatUL, formatOL, '|', insertLink, '|', undo, redo]
        comment: Only these buttons, in this order, with a separator for each pipe.

Every button ​

These are the built-in buttons that work on any page. Three more depend on the page: insertFile offers Upload from Computer only once uploads are on (and takes an address until then), while insertPageLink and insertSnippet reach a picker only when the page sets the matching hooks. emoticons, left out here, adds a panel of emoji. The full list is in Toolbar buttons.

Keyboard shortcuts include Ctrl+B, Ctrl+I and Ctrl+U for bold, italic and underline, Ctrl+Shift+S for strikethrough, and Ctrl+K, which opens the link picker or the link form.

yaml
fields:
    specifications:
        label: Specifications
        type: richeditor
        toolbarButtons: [
            paragraphFormat, paragraphStyle, inlineStyle, fontFamily, fontSize, color, '|',
            bold, italic, underline, strikeThrough, subscript, superscript, clearFormatting, '|',
            align, formatOL, formatUL, outdent, indent, quote, '|',
            insertLink, insertImage, insertVideo, insertAudio, insertTable, insertHR, '|',
            undo, redo, selectAll, html, fullscreen
        ]
        comment: Every built-in button that works without a page hook.

Uploads ​

uploadDisk names a filesystem disk and turns on the field's onUploadFile handler. Files uploaded from the image and file menus, and images pasted or dropped into the editor, are stored on that disk under uploadPath (uploads/richeditor by default) with hashed names, and the editor inserts the disk's URL for them, so pick a disk with public URLs, such as public.

Images accept jpg, jpeg, png, gif and webp. File links also accept pdf, doc, docx, xls, xlsx, ppt, pptx, txt, csv and zip. Both the file name and its content must match an accepted type, and uploadMaxSize limits each file in megabytes (10 by default). Uploads are off in read-only fields and in preview mode.

yaml
fields:
    story:
        label: Story
        type: richeditor
        uploadDisk: public
        uploadPath: uploads/richeditor
        uploadMaxSize: 2
        toolbarButtons: [paragraphFormat, bold, italic, '|', insertImage, insertFile, '|', html]
        comment: Images can also be pasted or dropped in, and each upload is stored on the public disk.

A page uploadFile hook replaces this upload, for a page that prefers its own endpoint.

Line breaks ​

useLineBreaks makes Enter add a <br> inside the same paragraph rather than start a new one, for addresses and signatures.

yaml
fields:
    signature:
        label: Email Signature
        type: richeditor
        useLineBreaks: true
        size: small
        toolbarButtons: [bold, italic, '|', insertLink]
        comment: Enter starts a new line inside the same paragraph.

Editor options ​

editorOptions passes settings to the editor. Here paragraphFormat replaces the paragraph formats, paragraphStyles and linkStyles replace the class names those menus offer, and images insert on the left at their own size, with imageDefaultAlign: left and imageResize: false. The style maps are class names mapped to labels, and the classes go into the saved HTML, so style them wherever the content is shown. The full list is in Editor options.

yaml
fields:
    article:
        label: Article
        type: richeditor
        toolbarButtons: [paragraphFormat, paragraphStyle, '|', bold, italic, '|', insertLink, linkStyle, insertImage]
        editorOptions:
            paragraphFormat:
                N: Body
                H2: Heading
                H3: Subheading
            paragraphStyles:
                oc-text-gray: Muted
                oc-text-uppercase: Caps
            linkStyles:
                oc-link-strong: Bold link
            imageDefaultAlign: left
            imageResize: false
        comment: Three paragraph formats, two paragraph styles, a link style, and images that insert on the left at their own size.

Size ​

size sets the starting height: tiny, small, large (the default), huge or giant. The editor still grows with its content.

yaml
fields:
    teaser:
        label: Teaser
        type: richeditor
        size: small
        comment: A small editor that still grows with its content.

Read-only ​

A readOnly editor keeps its toolbar, disabled, and the content can still be selected and copied. A disabled field looks the same, and its value is not saved.

yaml
fields:
    disclaimer:
        label: Disclaimer
        type: richeditor
        readOnly: true
        comment: The content can be selected and copied, but not changed.

Preview ​

In preview mode the field shows the HTML itself, cleaned of scripts and event handlers. safeMode: false shows it unchanged, so keep safe mode on unless every author is trusted. This example's form is made with previewMode on.

yaml
fields:
    press_release:
        label: Press Release
        type: richeditor

Page hooks and custom buttons ​

Media pickers, link pickers and snippets belong to the page, and so can uploads. Connect them through the shared richEditor object, which a page script imports with import { richEditor } from '/vendor/larajax/ui/index.js'. Set its hooks and register buttons at the top level of the script, before the editors load, and they apply to every rich editor on the page. Each hook is optional: without it, the editor hides or falls back for the feature it powers.

HookDescription
uploadFile(file, { type }) stores a file and resolves with its URL, where type is image or file. Replaces the uploadDisk upload.
browseMedia({ type, onInsert }) opens a picker for an image, video, audio or file, calling onInsert with a list of { url, title, type }.
browseLinks({ value, onInsert }) opens a link picker for insertPageLink, calling onInsert with { url, title }.
resolveLink(href) turns a stored link into an address the browser can open.
browseSnippets({ onInsert }) opens a snippet picker, calling onInsert with the snippet markup.
mountSnippet(element, { changed, opened, closed }) prepares a snippet for editing and returns a function that releases it. Without it, snippets show as a labelled placeholder.
editSnippet(element) opens a snippet's properties, returning false when it cannot.
alert(message) shows an error message. Default: the browser's alert().
tooltip(label, shortcut) returns the attributes that give a button its hover hint. Default: a title.

richEditor.registerButton(name, definition) adds a button of your own. Name it in a field's toolbarButtons, or give it a toolbar placement to add it to the default toolbar of every field that sets no buttons.

KeyDescription
labelthe tooltip and accessible label.
iconan icon class name, or { html: '...' } markup.
toolbarstart, end, { before: name } or { after: name }, its place in the default toolbar.
separatorbefore, after or both adds a separator beside it.
onClick(editor) runs the button. The editor has insertHtml(), getContent(), setContent() and focus().
focusfocuses the editor before onClick. Default: true.
undorecords an undo step after onClick. Default: false.

The toolbar and menu icons come from the configured icon pack (the richeditor.* keys), and the editor's labels and messages pass through __(), so they follow the app locale.

Showing the saved HTML ​

Wherever your app shows the saved HTML, include /vendor/larajax/ui/vendor/richarea/base-styles.css for the image alignment and the built-in style classes, and wrap the content in an element with the rich-editor-content class to apply the default typography as well. Clean the HTML first when its authors are not trusted.

Options ​

OptionDescription
toolbarButtonsthe buttons, as a list or a pipe separated string, see Toolbar buttons. Default: the default toolbar.
toolbarthe code of a named toolbar definition, used when toolbarButtons is not set. The base widget defines none, so it applies only in a subclass that provides them.
editorOptionssettings passed to the editor, see Editor options.
useLineBreaksEnter adds a line break instead of a new paragraph. Default: false.
uploadDiskthe filesystem disk that stores uploads, turning them on. Default: none.
uploadPaththe folder on the disk for uploads. Default: uploads/richeditor.
uploadMaxSizethe largest upload in megabytes. Default: 10.
safeModecleans the HTML shown in preview mode. Default: true.
readOnlyshows the content without editing it, and still saves it. Default: false.
sizethe starting height: tiny, small, large, huge or giant. Default: large.

The field also takes the common field properties, such as placeholder, disabled and stretch.

Toolbar buttons ​

GroupButtons
Textbold, italic, underline, strikeThrough, subscript, superscript, clearFormatting
StylesparagraphFormat, paragraphStyle, inlineStyle, fontFamily, fontSize, color, emoticons
Blocksalign, formatOL, formatUL, outdent, indent, quote, insertHR
InsertinsertLink, insertPageLink, linkStyle, insertImage, insertVideo, insertAudio, insertFile, insertTable, insertSnippet
Toolsundo, redo, selectAll, html, fullscreen

Editor options ​

OptionDescription
paragraphFormatthe paragraph formats, as keys (N, H1 to H6, PRE) mapped to labels. Default: Normal, Heading 1 to 4 and Code.
paragraphStylesparagraph classes mapped to labels. Default: oc-text-gray, oc-text-bordered, oc-text-spaced, oc-text-uppercase.
inlineStylestext classes mapped to labels. Default: oc-class-code, oc-class-highlighted, oc-class-transparency.
linkStyleslink classes mapped to labels. Default: oc-link-green, oc-link-strong.
imageStylesimage classes mapped to labels. Default: oc-img-rounded, oc-img-bordered.
tableStylestable classes mapped to labels. Default: oc-dashed-borders, oc-alternate-rows.
tableCellStylestable cell classes mapped to labels. Default: oc-cell-highlighted, oc-cell-thick-border.
imageDefaultAlignwhere new images go: left, center or right. Default: center.
imageResizelets images be resized by dragging their handles. Default: true.
imageAlignClassesthe classes for each image alignment, keyed left, center and right.
fontFamilyCSS font stacks mapped to labels for the fontFamily button. Default: six web safe fonts.
fontSizethe sizes the fontSize button offers, in pixels. Default: 8 to 96.
colorsthe hex colors the color button offers. Default: a palette of 27 colors.
emoticonsthe emoji the emoticons button offers. Default: 60 emoji.
linkProtocolsextra URL schemes allowed in links, beyond the usual web, mail and phone ones. Default: none.

Other keys, and those the field sets itself (readOnly, useLineBreaks, toolbarButtons), are ignored.