Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Added the “Parse embeds” field setting. ([#409](https://github.com/craftcms/ckeditor/pull/409))
- Added the “Show toolbar buttons for entry types with icons” field settings. ([#413](https://github.com/craftcms/ckeditor/pull/413))
- Fixed an error that occurred when copy/pasting a nested entry from a top-level element’s CKEditor field into a nested element’s CKEditor field. ([#408](https://github.com/craftcms/ckeditor/issues/408))

## 4.8.0 - 2025-04-30
Expand Down
18 changes: 7 additions & 11 deletions src/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,12 @@ private static function adjustFieldValues(
*/
public ?string $createButtonLabel = null;

/**
* @var bool Whether entry types with icons should be shown as separate buttons in the toolbar.
* @since 4.9.0
*/
public bool $expandEntryButtons = false;

/**
* @var EntryType[] The field’s available entry types
* @see getEntryTypes()
Expand Down Expand Up @@ -978,6 +984,7 @@ protected function inputHtml(mixed $value, ?ElementInterface $element, $inline):
'accessibleFieldName' => $this->_accessibleFieldName($element),
'describedBy' => $this->_describedBy($view),
'entryTypeOptions' => $this->_getEntryTypeOptions(),
'expandEntryButtons' => $this->expandEntryButtons,
'findAndReplace' => [
'uiType' => 'dropdown',
],
Expand Down Expand Up @@ -1356,17 +1363,6 @@ private function _getEntryTypeOptions(): array
return $entryTypeOptions;
}

/**
* Fill entry card CKE markup (<craft-entry data-entry-id="96"></craft-entry>)
* with actual card HTML of the entry it's linking to

* Replace the entry card CKE markup (<craft-entry data-entry-id="96"></craft-entry>)
* with actual card HTML of the entry it's linking to

* Replace the entry card CKE markup (<craft-entry data-entry-id="96"></craft-entry>)
* with the rendered HTML of the entry it's linking to
*/

/**
* Normalizes <figure> tags, ensuring they have an `image` or `media` class depending on their contents,
* and they contain a <div data-oembed-url> or <oembed> tag, depending on the `mediaEmbed.previewsInData`
Expand Down
9 changes: 9 additions & 0 deletions src/templates/_field-settings.twig
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@
data: {'error-key': 'entryTypes'},
}) }}

{{ forms.lightswitchField({
id: 'expand-entry-buttons',
name: 'expandEntryButtons',
label: 'Show toolbar buttons for entry types with icons'|t('ckeditor'),
instructions: 'Whether entry types with icons should be shown as separate buttons in the toolbar.' |t('ckeditor'),
on: field.expandEntryButtons,
reverseToggle: 'create-button-label-wrapper',
}) }}

<hr>

<a class="fieldtoggle" data-target="assets">{{ 'Assets'|t('app') }}</a>
Expand Down
3 changes: 3 additions & 0 deletions src/translations/en/ckeditor.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
'Link to an asset' => 'Link to an asset',
'Link to an entry' => 'Link to an entry',
'Link to the current site' => 'Link to the current site',
'New {type}' => 'New {type}',
'No transform' => 'No transform',
'Purify HTML' => 'Purify HTML',
'Raw content only' => 'Raw content only',
'Removes any potentially-malicious code on save, by running the submitted data through {link}.' => 'Removes any potentially-malicious code on save, by running the submitted data through {link}.',
'Show toolbar buttons for entry types with icons' => 'Show toolbar buttons for entry types with icons',
'Show word count' => 'Show word count',
'Site: {name}' => 'Site: {name}',
'The default transform that should be applied when inserting an image.' => 'The default transform that should be applied when inserting an image.',
Expand All @@ -48,6 +50,7 @@
'This field doesn’t allow nested {type} entries.' => 'This field doesn’t allow nested {type} entries.',
'Toolbar' => 'Toolbar',
'View available settings' => 'View available settings',
'Whether entry types with icons should be shown as separate buttons in the toolbar.' => 'Whether entry types with icons should be shown as separate buttons in the toolbar.',
'Who should see the “Source” button?' => 'Who should see the “Source” button?',
'Words' => 'Words',
'You can save custom {name} configs as {ext} files in {path}.' => 'You can save custom {name} configs as {ext} files in {path}.',
Expand Down
2 changes: 2 additions & 0 deletions src/web/assets/ckeditor/CkeditorAsset.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ public function registerAssetFiles($view): void
'Edit {type}',
]);
$view->registerTranslations('ckeditor', [
'Add nested content',
'Entries cannot be copied between CKEditor fields.',
'Entry toolbar',
'Entry types list',
'Insert link',
'Link to the current site',
'New {type}',
'Site: {name}',
'This field doesn’t allow nested entries.',
]);
Expand Down
2 changes: 1 addition & 1 deletion src/web/assets/ckeditor/dist/ckeditor5-craftcms.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/web/assets/ckeditor/dist/ckeditor5-craftcms.js.map

Large diffs are not rendered by default.

71 changes: 62 additions & 9 deletions src/web/assets/ckeditor/src/entries/entriesui.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from 'ckeditor5/src/ui';
import {Range} from 'ckeditor5/src/engine';
import {Collection} from 'ckeditor5/src/utils';
import {IconPlus} from 'ckeditor5/src/icons';
import {isWidget, WidgetToolbarRepository} from 'ckeditor5/src/widget';
import {DoubleClickObserver} from '../observers/domevent';
import CraftEntryTypesButtonView from './entrytypesbuttonview.js';
Expand Down Expand Up @@ -107,26 +108,78 @@ export default class CraftEntriesUI extends Plugin {
}

/**
* Creates toolbar buttons that allow for an entry of given type to be inserted into the editor
* Creates a single toolbar button that allows for an entry to be inserted into the editor
*
* @param locale
* @private
*/
_createToolbarEntriesButtons() {
_createSingleToolbarEntriesButton(locale) {
const editor = this.editor;
const entryTypeOptions = editor.config.get('entryTypeOptions');
const insertEntryCommand = editor.commands.get('insertEntry');

if (!entryTypeOptions || !entryTypeOptions.length) {
return;
}

this.editor.ui.componentFactory.add(
'createEntry',
(locale) =>
new CraftEntryTypesButtonView(locale, {
entriesUi: this,
entryTypeOptions: entryTypeOptions,
}),
const dropdownView = createDropdown(locale);
dropdownView.buttonView.set({
label: Craft.t('ckeditor', 'Add nested content'),
icon: IconPlus,
tooltip: true,
withText: false,
});

dropdownView.bind('isEnabled').to(insertEntryCommand);
addListToDropdown(
dropdownView,
() =>
this._getEntryTypeButtonsCollection(
entryTypeOptions,
insertEntryCommand,
),
{
ariaLabel: Craft.t('ckeditor', 'Entry types list'),
},
);
// Execute command when an item from the dropdown is selected.
this.listenTo(dropdownView, 'execute', (evt) => {
this._showCreateEntrySlideout(evt.source.commandValue);
});

return dropdownView;
}

/**
* Creates toolbar buttons that allow for an entry of given type to be inserted into the editor.
* If the entry type has an icon, it'll get its own button. Entry types without an icon are grouped in a dropdown.
*
* @private
*/
_createToolbarEntriesButtons() {
const editor = this.editor;
const entryTypeOptions = editor.config.get('entryTypeOptions');

if (!entryTypeOptions || !entryTypeOptions.length) {
return;
}

const expandEntryButtons = editor.config.get('expandEntryButtons');

if (expandEntryButtons) {
this.editor.ui.componentFactory.add(
'createEntry',
(locale) =>
new CraftEntryTypesButtonView(locale, {
entriesUi: this,
entryTypeOptions: entryTypeOptions,
}),
);
} else {
this.editor.ui.componentFactory.add('createEntry', (locale) => {
return this._createSingleToolbarEntriesButton(locale);
});
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default class CraftEntryTypesButtonView extends View {
label: item.model.label,
icon: item.model.icon,
withText: false,
tooltip: Craft.t('app', 'New {type}', {
tooltip: Craft.t('ckeditor', 'New {type}', {
type: item.model.label,
}),
class: classes.join(' '),
Expand Down
Loading