Bard
Bard is designed for rich article layouts. It's more than a content editor, it's practically a layout designer. Bard starts with simple, rich text editor with popup formatting controls. It stores structured data and adds the ability to insert blocks of any arrangement of custom fields amidst the text.
It's a lot like Medium's editor, but for your own site. It's also 100% compatible with Replicator's data structure — you can easily switch between their interfaces if you desire.
Preview
Usage
At first glance, Bard looks and feels like a simple text editor, but once you start writing you’ll realize there’s much more to it.
Clean HTML: Bard writes clean HTML. It’s only allowed a very basic set of tags and aggressively strips anything out. This isn’t WYSIWYG. This is better. This is structured content. There’s even a code mode so you can take a peek and be sure.
Formatting Options: Highlight some text and you get the most commonly used formatting options: bold, italic, link, h2, h3, and blockquote.
Custom Field Blocks: Between text paragraphs you can insert blocks of custom content. Most commonly this would be images or videos, but it can be quite literally any combination of one or more available fieldtypes grouped into sets. Just like Replicator.
Drag and Drop Reordering: Want to rearrange your post layout? Move the images around? Bring your TL;DR from the bottom up to the top? Just drag those blocks around.
Full Screen Mode: Like to cut out all possible distractions while you write? No problem.
Data Structure
Bard stores your data as an array, exactly like Replicator. Sensing a theme? The default text content will be scoped into type: text
as HTML content.
bard_field:
-
type: text
text: <p>I love it when he plays the saxophone. It gives me all the feels.</p>
-
type: image
image: /assets/img/sax.jpg
caption: "I want this mounted above my fireplace."
Fieldtypes
You can use any fieldtypes inside your Bard sets. Make sure to compare the experience with the other meta-fields: Grid and Replicator. You can even use Grids and Replicators inside your Bard sets. Just remember that because you can doesn’t mean you should. Your UI experience can vary greatly.
Text-only Mode
If you don’t configure any additional sets the field data will be saved as a string.
bard_field: "<p>Oh hi Mark.</p>"
Please note that you cannot name your Bard field “
content
”, but go ahead and name it anything else! Thecontent
field is what’s saved in your markdown files below the YAML, and can only contain a string, where Bard would save an array.
Templating
Use tag pair syntax with if/else
conditions to style each set accordingly.
{{ bard_field }}
{{ if type == "text" }}
<div class="text">
{{ text }}
</div>
{{ elseif type == "image" }}
<figure>
<img src="{{ image }}" alt="{{ caption }}" />
<figcaption>{{ caption }}</figcaption>
</figure>
{{ /if }}
{{ /bard_field }}
An alternative approach (for those who like DRY or small templates) is to create multiple “set” partials and pass the data to them dynamically, moving the markup into corresponding partials bearing the set’s name.
{{ bard_field }}
{{ partial src="sets/{type}" }}
{{ /bard_field }}
partials/
|-- sets/
| |-- gallery.html
| |-- image.html
| |-- poll.html
| |-- text.html
| |-- video.html
Extending Bard
Bard is powered by Scribe. You are free to extend Bard or the underlying Scribe instances by adding your own plugins. You can do this by pushing a Scribe plugin function into the plugins array:
Statamic.bard.plugins.push(myPlugin); // where `myPlugin` is a Scribe plugin function.
Here’s an example of a plugin that converts the selected text into uppercase:
const uppercasePlugin = function () {
return function (scribe) {
var command = new scribe.api.Command('uppercase');
scribe.commands.uppercase = command;
command.execute = function () {
scribe.transactionManager.run(() => {
const sel = new scribe.api.Selection();
const range = sel.range;
sel.placeMarkers();
const contents = range.extractContents();
contents.childNodes.forEach(node => node.textContent = node.textContent.toUpperCase());
range.insertNode(contents);
sel.selection.removeAllRanges();
sel.selection.addRange(range);
sel.removeMarkers();
});
};
command.queryEnabled = function () {
return true;
};
};
};
Statamic.bard.plugins.push(uppercasePlugin);
Custom Buttons
A custom button can be created with a Scribe plugin as described above, combined with a button handler.
The handler should be a function that expects an array of buttons coming from a Bard field’s config. You should modify this array to include your button.
Here’s an example of just pushing a new button on the end.
const handler = function (buttons) {
buttons.push({
text: 'Uppercase', // Tooltip text when you hover the button
command: 'uppercase', // The command you defined in your Scribe plugin
html: '<span>aA</span>', // Either the html contents of the button...
// icon: 'header', // ...or you can specify a font awesome icon name.
});
};
Statamic.bard.buttons.push(handler);
Here’s an example of finding where the config defined uppercase
and inserting the button there.
my_bard_field:
type: bard
buttons:
- bold
- uppercase # button will be inserted here
- italic
const handler = function (buttons) {
let i = buttons.indexOf('uppercase');
buttons.splice(i, 1, { text: 'Uppercase', command: 'uppercase', html: 'aA' });
};
Statamic.bard.buttons.push(handler);
Settings
This fieldtype supports the following settings in addition to the defaults.
allow_source
boolean true |
Controls whether the "show source code" button is available to your editors. |
---|---|
sets
array |
An array containing sets of fields. If you don't provide any sets, Bard will act like a basic text editor and just save a string. |
buttons
array |
An array of buttons that should appear in the toolbar.
You can choose from |
markdown
boolean false |
Experimental. Enabling this option will allow you to author (and save) Markdown. The toolbar, toggle source button, and keyboard shortcuts will be disabled. |
spellcheck
boolean true |
Enable contentEditable's automatic spellcheck. |
target_blank
boolean false |
Automatically add |
link_noopener
boolean false |
Set |
link_noreferrer
boolean false |
Set |
semantic_elements
boolean false |
Replace unsemantic |
container
string |
An asset container ID. When specified, the fieldtype will allow the user to add a link to an asset from the specified container. |
folder
string |
The folder (relative to the asset container) to use when choosing an asset. If left blank, the root folder of the container will be used. |
restrict_assets
bool |
If set to |