Links, files, media and callouts¶
Links to content¶
Core 11.3 added the pieces a link to other content on the site needs, suggestions as you type and a per-content-type rule for the address a link resolves to among them, so this needs no contrib module.
The shipped BlockNote format has this set up already, for every kind of node. For another format, or another kind of content:
- Go to the text format at
/admin/config/content/formatsand tick Content link on the Inline content tab. - A Content link tab appears while it is ticked. Tick the kinds of content authors may link to, and, for a kind with more than one bundle, the bundles it may point at; ticking a kind with no bundle ticked permits every bundle of it. Nothing is offered until a kind is ticked. A Permitted address kinds choice appears on the same tab only when an installed module offers any address rule beyond this module's own that a picked result may follow; tick none to keep this module's own file-versus-page rule as the only one available.
An author types [[ to open a search of what is permitted, which inserts the picked result's current title as the link text; or selects text, opens the link form from the formatting toolbar and searches the same content from its URL field, where picking a result keeps the selected wording as the link's text and falls back to the target's title when nothing was selected, and the form's Open in a new tab checkbox, while the format permits one, decides whether the content link opens in a new tab. A content link the [[ search inserts opens in the same tab until its own Edit link form says otherwise. With the caret in a content link, a toolbar of its own shows the target's current title, Edit link, Open link, and Unlink. Its Edit link form offers the same Open in a new tab checkbox a plain link's form does, while the format permits one, next to the same Save button; ticking it and saving without changing the address never turns the content link into a plain one. The [[ search follows the Slash menu toggle and that toolbar the Link toolbar toggle. A visitor sees an ordinary link that follows the target's current address; a target that has since been removed shows as plain text instead.
A link to a file, or to a media item's source file, is access-checked the same way an uploaded file already is: a visitor who may not view it gets the plain text instead of a link, and a linked file gets a usage record the way an uploaded one does. A link to a page, a node or any other content with its own route, is not checked here; the page itself enforces its own access, the way any link to it already would, so it still links even when the current visitor may not see the page behind it.
A site standardized on linkit, as Drupal CMS is from its base recipe, can install the Linkit submodule to search a curated linkit profile instead of this picker and let a picked result follow one of linkit's own address rules, offered under Permitted address kinds above; see the Linkit section below.
File uploads¶
The image, video, audio and file blocks can hold a file uploaded from inside the document, as well as a URL an author types. An upload creates an ordinary managed file on the site, and the document stores the file's identity rather than its address, so the document survives the file being moved, renamed, or served from a different scheme.
Three things have to be true before an author is offered an upload: the field permits it, the account has the permission, and the text format enables at least one of the four file blocks. If any of them is not, the file panel offers Embed and no Upload tab, which is the honest answer rather than a button that refuses.
The field's settings¶
They are under File uploads in the field's settings, at Manage fields for the bundle, and they are core's own controls for a file field.
| Setting | Default | What it does |
|---|---|---|
| Allow uploads | On | With uploads off, an author may still reference a file by URL. |
| Upload destination | The site's default file scheme | Where uploaded files are stored. This is a setting of the field, not of the field storage, so one storage can serve a public field beside a private one. |
| File directory | blocknote/[date:custom:Y]-[date:custom:m] |
A subdirectory within the destination. Tokens are replaced. |
| Allowed file extensions | png gif jpg jpeg webp mp4 webm mp3 ogg pdf |
Required, and separated by commas or spaces. |
| Maximum upload size | Empty | A value like 512, 80 KB or 50 MB. Empty means PHP's own limits decide. |
| Maximum image dimensions | Empty | Width by height. A larger image is scaled down to fit on upload, which is what core's own image field does and costs the image its EXIF data. The limit applies to uploaded images only. |
One extension list serves all four blocks. There is no separate list for images, and no check that a file going into an image block is an image. Deciding that on the server would mean trusting the browser to say which block it was uploading into, which is not a claim a server can act on, so a list that permits png and mp4 permits both into either block. A site that wants images only sets an image-only list. This is a stated boundary of this release.
Leave svg and html out of the list of a field that uploads to public storage. The web server serves a public file as it is, and an SVG or HTML file can carry script that runs on the site's own domain when the file is opened.
The file picker is not narrowed to the list. The file panel offers the file types each block accepts, as BlockNote declares them, so an author can choose a file the field refuses. The editor refuses that file before sending it, with the message the server would give. On the Upload tab the panel shows a short failure of its own naming no reason, and the reason is in the notice above the editor.
The permission¶
Grant Upload files into BlockNote documents at Administration › People › Permissions (/admin/people/permissions) to the roles that should be able to place files. It is granted to nobody on installation. It is a genuine grant of the right to put files on the site, so give it the same thought you would give the file upload permissions on a file field.
Private files¶
Set the field's Upload destination to private and uploads from that field go to the private scheme, where Drupal serves them through a download callback rather than off the web server. The module answers for the files its own documents reference: a file is served to an account that may view an entity referencing it, and the field of that entity whose document names it, and refused otherwise. Two revisions of that entity are read, its current revision and, where a site keeps drafts, its latest revision. A file that only the latest revision names, which is what an author adds to a draft waiting for review, is served under the permission that views revisions: for a node that is View all revisions, or View revisions on that content type. It is the rule core applies to a file field that only a draft references. The permissions that open the Latest version tab, View the latest version with View any unpublished content, are not revision permissions, so an account holding those alone reads the draft with that file shown as unavailable until it holds a revision permission too. A file that only an older revision still names is refused. A site that withholds the field, with Field Permissions or a rule of its own, withholds the files its documents name along with it. A temporary file an author has just uploaded is served to that author, before the entity has been saved.
The rendered page answers from the same rule, with one difference. It asks core's own file access first. Core serves a private file to the account that uploaded it for as long as no file field references it, and a reference from inside a document is not a file field. So the account that uploaded a file is shown it on the page even where this rule refuses it, and the download callback, which answers for a permanent file from this rule alone, refuses the fetch. For every other account the two agree: a private file a document names is shown to every account the download callback would serve it to, and renders as unavailable for the rest.
When a file becomes permanent¶
An upload is stored as a temporary file. It becomes permanent, with a usage record, when the entity holding the document is saved and the saved document is found to reference it. A file uploaded into a form that was then abandoned stays temporary and is deleted by the file module's cron, which is what keeps an editing session from littering the site.
The editor learns which files a document names, and where they are, when the form is built. A file deleted or withheld while the form is open still shows in the editor until the page is reloaded.
The limit above which nothing reaches the module¶
A file larger than PHP's post_max_size is discarded by PHP before Drupal sees the request, so the field's Maximum upload size cannot report it and the editor shows a generic failure. If authors are hitting that, raise post_max_size and upload_max_filesize in the site's PHP configuration; the field setting only narrows what PHP already allows.
Media¶
BlockNote Media (blocknote_media) is a submodule that adds two blocks: a media item chosen from the Media Library and rendered in a media view mode, with a caption written in the document, and a gallery of such items in a grid.
It ships nothing enabled. Installing it changes nothing an author sees. It requires core's media and media_library modules.
Enabling it in a format¶
- Install the submodule:
drush pm:install blocknote_media. - Go to the text format at
/admin/config/content/formatsand tick Media on the Blocks tab. - A Media tab appears beside it as soon as the block is ticked, with two settings. Permitted media types are the types authors may choose from in this format; tick none to permit every media type on the site. Permitted view modes are the view modes an author may switch an item to, and the list offers only view modes that a permitted media type has an enabled display for; the default view mode is always available and is not listed. Each view mode names, in parentheses, the permitted media types that have an enabled display for it, and an author is offered a view mode only for an item whose type has one; a type's Manage display tab is where a view mode is enabled for it. Tick none to leave every item in the default view mode. The list is curation and not a boundary: a document that names a view mode the format no longer permits still saves, and the editor, the preview and the page all show that item in the default view mode.
- For galleries, tick Media gallery on the Blocks tab too. It has no settings of its own: the media types and view modes the Media tab permits are the ones a gallery's items and its view mode are chosen from, so the form refuses Media gallery without Media.
Permitting a view mode makes the format depend on that view mode's configuration. Deleting the view mode afterwards removes it from the format's settings and leaves the format alone, which is deliberate: a format that kept the name would be deleted along with the view mode, and the fields pointing at that format would go with it.
What an author gets¶
The editor offers the media item where the format permits at least one media type; a format that permits none offers nothing rather than a dialog that refuses. Choosing an item opens core's Media Library dialog, and the item is inserted with the uuid and the view mode as its stored properties. Closing the dialog without choosing an item cancels the insert: the empty media block goes again, and the empty paragraph it was put in place of, if any, comes back. The preview in the editor is rendered by the site's own view builder, through the same code that renders the public page, so what the author sees is what a visitor gets. The view mode menu, on the formatting toolbar and in the block menu, offers only the view modes the item's own media type can display, and is not drawn while there is nothing to choose between. The preview is not interactive: a player inside it does not play, a link in it does not open and Tab does not stop inside it; clicking anywhere on it selects the block. The caption is the block's own text, written and styled under the same policy as the rest of the document. In the caption, / and the Markdown-style triggers such as # and - are typed as text, because a caption cannot become or hold another block. Backspace at the start of the caption, or Backspace and Delete from the block beside it, selects the media block instead of merging it; a second press deletes it, and undo restores it. Enter at the start of a caption inserts an empty paragraph before the block and leaves the block and its caption as they are. With the block selected, which clicking the preview does, a typed character replaces the block with a paragraph; undo brings it back.
Alternative text belongs to the media item, which is where Drupal keeps it and where changing it fixes every document using it. For one use of an image, an author can override it, or mark the image decorative, with Override media image alternative text on the formatting toolbar or Alternative text in the block menu. The form shows the item's own alternative text, which an empty field keeps, unless the text is withheld: an account that may not view the image field is not shown it, and neither is anyone when the text, percent-encoded, is over 1536 bytes, which text in ASCII never is and Georgian or Chinese text is past 170 characters, and the form then says only that a blank field keeps it; the field takes up to 512 characters, as core's image field does, and ticking Decorative image renders the image with an empty alt. Both are offered for an item whose media type's source field is an image field with alternative text enabled, as in core's media embed, and for a block that already holds an override, so that it can be cleared; choosing another item for the block clears them. Alignment is the author's, from the formatting toolbar or the block menu, with the four choices core's own editor offers a media item: Break text, the default, keeps the item on a line of its own; Align left and wrap text and Align right and wrap text float it on the page, so that the text after it flows beside it; Align center and break text centers it on a line of its own. Each is rendered as a class on the figure, and the editor keeps a floated item on a line of its own. Width is not here; a site builder answers size with a view mode.
A gallery is built from the slash menu's Gallery, which opens the Media Library letting the author pick several items; the gallery holds them in the order they were picked, each a media block with its own caption and alternative text, shown in the editor as a grid of their previews. Add media appends more, and the number of columns, two, three or four, and the view mode every item is shown in are the gallery's own, on the formatting toolbar beside an item's own functions and in the block menu, from the gallery or from any item in it. An item's own view mode and alignment are not used in a gallery, and are kept for when it is moved out. Items reorder by dragging, as any block does, or with the block menu's Move up and Move down or Ctrl+Shift+Up and Ctrl+Shift+Down, within the gallery; a block next to a gallery moves past it the same way. Enter in an item's empty caption starts a paragraph after the gallery, and an item cannot be moved out of it, so Shift+Tab in one moves focus on, as in a block that is not nested. A block of another kind dropped into a gallery moves out to right after it, and deleting the last item deletes the gallery. On the page a gallery is a list of the items' figures in a grid, which the default styles lay out and a theme may restyle; the module adds no lightbox, so an item that should open larger, or link somewhere, gets that from the view mode the gallery shows it in.
Remote embeds (YouTube, Vimeo and others)¶
The module has no embed block and needs none: in Drupal, remote content is a media item. Core's Remote video media type takes a YouTube or Vimeo URL through oEmbed and renders the player in an iframe the site itself serves (core's /media/oembed route, on the site's domain or on the separate domain media.settings names), and an author places one with the same Media Library dialog as any other item, through the Add Remote video via URL field on that type's tab. Other providers come from contrib: oEmbed Providers adds any provider in the oEmbed registry and lets a site define its own, and a media_entity_* module covers a service oEmbed does not.
The player's size is the display's business, not the block's. The oEmbed formatter on the Remote video type's default display has a Maximum width and a Maximum height, both 0 out of the box, which leaves the player at whatever size the provider answers with; set a maximum width there, or give the type a second view mode with its own size and permit that view mode in the format.
What an account needs¶
- Use the BlockNote text format for the format being written in, which is what the whole editor needs.
- View media (
view media), which is what core's Media Library requires of anyone opening it. - View access to the individual item, which the preview checks and which the public page checks again for each visitor.
A visitor who may not view an item sees Inaccessible media where it would have been, with the caption intact; a document naming an item that has been deleted shows Missing media the same way.
Uninstalling the submodule¶
Uninstalling BlockNote Media is refused while an enabled format enables its blocks, so untick Media and Media gallery in each such format first. A format restricted to a single paragraph refuses it too while Media is still ticked in the block list it hides: untick the restriction to show the list, untick Media, and tick the restriction again before saving. A disabled format is not checked, so it does not refuse the uninstall and keeps the block and its settings afterwards, with no schema left to describe them, which fails configuration validation. A disabled format also has no Edit link, so enable it first, untick Media and save. A document that still holds a media block afterwards renders without it, and the editor shows the block as one the format cannot hold. The document cannot be saved until an author removes the block.
Linkit¶
BlockNote Linkit (blocknote_linkit) is a submodule that lets the content link search a linkit profile instead of this module's own picker, and lets a picked result follow one of the profile's own address rules.
It ships nothing enabled. Installing it changes nothing an author sees. It requires the contributed Linkit module, with at least one profile already configured.
Enabling it in a format¶
- Install the submodule:
drush pm:install blocknote_linkit. - Go to the text format at
/admin/config/content/formatsand, on the Content link tab, name a profile under Linkit profile. The Linkit profile select is on that tab only once the format has been saved as a BlockNote format; a format being newly added or converted needs a first save before this select appears on its second. - Under Permitted address kinds, tick the address kinds the profile's own matchers use. A matched result naming an address kind the format has not ticked still appears in the search, but falls back to this module's own file-versus-page rule rather than being refused. The format form warns, when it is shown and when it is saved, of each address kind the profile's matchers use that the format has not ticked.
What an author gets¶
The [[ search and the link form's own search both query the named profile instead of this module's picker, so an author sees whatever result set and grouping the profile's matchers build. A picked result whose match named a permitted address kind stores it on the link; an unpermitted address kind is dropped before the search ever offers the result, the same as if the profile had not matched it that way.
What a visitor gets¶
A link storing a permitted address kind resolves by the profile's own rule for it on the public page: a page left unchecked with the target's own access controlling it, or, for an address kind that answers a file or a media item's own file, the same access-checked resolution an uploaded file already gets. A link storing no address kind, or one the format no longer permits, resolves by this module's own file-versus-page rule, unchanged.
Uninstalling the submodule¶
Uninstalling blocknote_linkit removes the Linkit profile setting from every format that named one, and the content link's search reverts to this module's own picker on the next page load. A document that still stores an address kind keeps it as it was; the module's own resolver ignores it and answers its own rule instead, so nothing about the document is refused or rewritten. A format's own Permitted address kinds list stays exactly as it was stored, invisibly, until a site builder edits it again.
Drupal CMS¶
Drupal CMS's base recipe installs Linkit and ships linkit.linkit_profile.default, pointing a link at a node's canonical page and at a Document media item's own file rather than its page: a canonical link to a media item sent an anonymous visitor to a login page, because the item's page requires an account the visitor did not have, where the file itself is public (Drupal CMS issue #3500041). With this submodule installed, a BlockNote format names that profile and ticks Canonical URL and Direct URL to media file entity under Permitted address kinds.
Extras¶
BlockNote Extras (blocknote_extras) is a submodule for blocks a site needs but not every site uses, each enabled per text format and loaded only in the formats that enable it. Its one block is the Callout: a note set apart from the text, with an optional title, in one of five tones.
It ships nothing enabled. Installing it changes nothing an author sees in a format that exists. A format added afterwards starts with every installed block ticked, Callout among them.
Enabling the callout in a format¶
- Install the submodule:
drush pm:install blocknote_extras. - Go to the text format at
/admin/config/content/formatsand tick Callout on the Blocks tab. - A Callout tab appears beside it with Permitted tones: Note, Info, Success, Warning and Danger, all ticked by default. A new callout takes the first permitted tone in that order. A document holding a tone the format no longer permits is refused on save; the editor gives such a callout the first permitted tone and names the change above the editor, and the page shows it in the Note tone until it is saved again.
What an author gets¶
The slash menu's Callout inserts one. Its text is its first paragraph, and the blocks nested under it, such as a list, more paragraphs or an image, are part of it and drawn inside its box: Enter in the callout's text starts a paragraph inside it, and Enter in an empty last block inside it leaves the callout. A callout holds no heading, because a heading inside a box would enter the document's outline and its table of contents: the editor refuses to turn a block inside a callout into a heading, or to bring one in by pasting, dropping or moving it, and says why, aloud and in a notice above the editor that stays until the next edit, and the save refuses one.
Tone and Title are on the formatting toolbar while text in the callout is selected, and in the block menu as its Callout group, Alt+F10 with the caret in the callout, and in the same group in the menu the side menu's drag handle opens, which reaches a new, empty callout that has no text to select: the tones as a choice, offered only where the format permits more than one, and Title, which opens a form, from any of them. The title is plain text, shown above the callout's text, and is not a heading. Each tone has its own icon, which the author does not choose.
What a visitor gets¶
On the page a callout is a note, role="note", and neither a landmark nor a heading, so it adds nothing to the page's landmarks or its outline. A screen reader reads the tone first, such as "Warning:", from text that is hidden visually, then the title and the text. The icon is hidden from assistive technology and drawn in the color of the text around it, so it follows a high contrast mode. The default styles give each tone a colored border and background, and docs/rendering.md has the markup a theme styles instead.
Converting callouts¶
The HTML converter does not recognize callouts, since every site marks them its own way. docs/converting.md shows the one line that maps a site's own callout class to the callout, and what becomes of a heading inside one.
Uninstalling the submodule¶
Uninstalling BlockNote Extras is refused while an enabled format enables Callout, so untick it in each such format first, as for Media. A document that still holds a callout afterwards renders without it, and the editor shows the block as one the format cannot hold.