How To: Programmatically change all link targets.
Provide a description of the task
Different users of our CKEditor implementation might have different preferences on if their links open in a new tab or inside _self. I know I can set the default value of the decorator to open in a new tab, true or false, but I was hoping to create a Toolbar button that calls an EditorCommand to change all existing links in the document to either _blank or _self so that users with many links in their content don't have to individually toggle the target state of each link.
What steps should be taken to fulfill the task? I know that to start the process would require a Custom Plugin, i've got some basic boilerplate put together from the plugin docs, but am struggling with the implementation. I'm pretty sure it would require targeting the linkHref model?
export class MakeLinksExternal extends Plugin {
init() {
const editor = this.editor;
const t = editor.t;
editor.ui.componentFactory.add("makeLinksExternal", () => {
const view = new ButtonView();
view.set({
icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path fill-rule="evenodd" clip-rule="evenodd" d="M20 14a1 1 0 0 0-1 1v3.077c0 .459-.022.57-.082.684a.363.363 0 0 1-.157.157c-.113.06-.225.082-.684.082H5.923c-.459 0-.571-.022-.684-.082a.363.363 0 0 1-.157-.157c-.06-.113-.082-.225-.082-.684L4.999 5.5a.5.5 0 0 1 .5-.5l3.5.005a1 1 0 1 0 .002-2L5.501 3a2.5 2.5 0 0 0-2.502 2.5v12.577c0 .76.083 1.185.32 1.627.223.419.558.753.977.977.442.237.866.319 1.627.319h12.154c.76 0 1.185-.082 1.627-.319.419-.224.753-.558.977-.977.237-.442.319-.866.319-1.627V15a1 1 0 0 0-1-1zm-2-9.055v-.291l-.39.09A10 10 0 0 1 15.36 5H14a1 1 0 1 1 0-2l5.5.003a1.5 1.5 0 0 1 1.5 1.5V10a1 1 0 1 1-2 0V8.639c0-.757.086-1.511.256-2.249l.09-.39h-.295a10 10 0 0 1-1.411 1.775l-5.933 5.932a1 1 0 0 1-1.414-1.414l5.944-5.944A10 10 0 0 1 18 4.945z" fill="#000"/></svg>',
withText: true,
tooltip: t("Make All Links External"),
});
view.on("execute", () => {
editor.model.change((writer) => {
// 1) Get all links on page. (linkHref model?)
// 2) Add target="_blank" and rel="noreferrer noopener" to each one
});
});
return view;
});
}
}
📃 Other details
- Browser: Brave
- OS: OSX
- CKEditor version: 39.0.1
- Installed CKEditor plugins:
Alignment, AutoImage, AutoLink, Autoformat, BlockQuote, Bold, Code, CodeBlock, DataFilter, DataSchema, DocumentList, DocumentListProperties, Essentials, FindAndReplace, FontBackgroundColor, FontColor, FontSize, GeneralHtmlSupport, Heading, HorizontalLine, HtmlComment, HtmlEmbed, Image, ImageCaption, ImageInsert, ImageResize, ImageStyle, ImageToolbar, ImageUpload, Indent, IndentBlock, Italic, Link, LinkImage, MediaEmbed, MediaEmbedToolbar, Paragraph, PasteFromOffice, RemoveFormat, SelectAll, ShowBlocks, SourceEditing, Strikethrough, Style, Subscript, Superscript, Table, TableCaption, TableCellProperties, TableColumnResize, TableProperties, TableToolbar, TextTransformation, Underline, WordCount,
Hey, there's a how-to on iterating, I think it will help you get started. Keep in mind that this will iterate on text nodes with an attribute.
Thanks for your time in responding! I'm able to iterate though all of the links successfully, thank you. However, the Set generated above only gives me the URL string values of my link.
When using value directly instead of value.item.getAttribute(href) I find some positional information about the link text, however based on what i'm seeing in the source code for the link plugin, I don't have access to any methods to set attributes on the item.
There has been no activity on this issue for the past year. We've marked it as stale and will close it in 30 days. We understand it may still be relevant, so if you're interested in the solution, leave a comment or reaction under this issue.
We've closed your issue due to inactivity. We understand that the issue may still be relevant. If so, feel free to open a new one (and link this issue to it).