Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save candidexmedia/367711a80274b4c005fd5983df97d20c to your computer and use it in GitHub Desktop.
Save candidexmedia/367711a80274b4c005fd5983df97d20c to your computer and use it in GitHub Desktop.
Experiments in Publii TinyMCE WYSIWYG Editor Extensions (customElementsMode, Formats, Blocks, Templates)

Custom HTML Elements (via customElementsMode)

Custom Elements allow you to wrap selected text in the editor with the HTML tag and CSS class (optionally) of your choice <element>like this</element>. These wrappers can be given custom names and grouped in subfolders.

demo

A huge thanks to @b0fh for guidance on this in the forum and GH discussion.

Instructions

Go to [Publii sites directory] > [site folder] > input > [theme or theme-override] > config.json

Look for "customElements" (usually near the end of the file, and used for Custom Formats). If it's there, cut and paste that snippet out of the file and save it elsewhere for later. Once that done (or if you don't see it), create a new item at the end of the config.json (likely after the "files" item):

"customElementsMode": "advanced",
    "customElements": []

Place all of your custom toolbar items inside of "customElements". Here's an example:

"customElementsMode": "advanced",
    "customElements": 
    [
        { "title": "🗨️ Messages", "items": [
            { "title": "Info",      "selector": "p", "classes": "msg msg--info" },
            { "title": "Highlight", "selector": "p", "classes": "msg msg--highlight" },
            { "title": "Success",   "selector": "p", "classes": "msg msg--success" },
            { "title": "Warning",   "selector": "p", "classes": "msg msg--warning" }
        ]},
        { "title": "📦 Containers", "items": [
            { 
                "title": "Article", 
                "block": "article", 
                "wrapper": true, 
                "merge_siblings": true 
            },
            { 
                "title": "Aside", 
                "block": "aside", 
                "wrapper": true, 
                "merge_siblings": true 
            },
            { 
                "title": "Div", 
                "block": "div", 
                "wrapper": true, 
                "merge_siblings": true 
            },
            { 
                "title": "Details", 
                "block": "details", 
                "wrapper": true, 
                "merge_siblings": true 
            },
            { 
                "title": "Details - Summary", 
                "inline": "summary",
                "wrapper": true, 
                "merge_siblings": true 
            },
            { 
                "title": "Section", 
                "block": "section", 
                "wrapper": true, 
                "merge_siblings": true 
            },
            { 
                "title": "Span", 
                "inline": "span", 
                "classes": "",
                "merge_siblings": false 
            }
        ]},
        { 
            "title": "⌨️ Keyboard Key", 
            "inline": "kbd", 
            "wrapper": true, 
            "merge_siblings": false 
        },
        { 
            "title": "✍ Highlight", 
            "inline": "mark",
            "wrapper": true, 
            "merge_siblings": true 
        },
        { 
            "title": "🇦 Drop cap",   
            "selector": "p", 
            "classes": "dropcap" 
        },
        { 
            "title": "Superscript¹",   
            "selector": "sup" 
        },
        { 
            "title": "Subscript₁",   
            "selector": "sub"
        }
    ]

Save this file and restart your Publii app, OR switch to another project and come back again.

TinyMCE Documentation Reference

https://www.tiny.cloud/docs/configure/content-formatting/#formattype

Caveats

<details> and <summary>

<details> and <summary> are a bit iffy... When you select <details>, it will hide the text you selected. To reveal it again, save and close your post. When you re-open it, you'll be able to edit the contents of your <details> normally. Unfortunately, clicking on <summary> doesn't currently work, so you'll need to edit it manually using the Source Code editor.

Source Code editor button

OR see technique number 2 below.

<span>

<span> requires a CSS class to work. That said, I assume anyone wanting a <span> toolbar button would have a CSS class in mind for it already anyway...

Template Plugin

A template is a reusable code+content snippet which can be inserted in your post. It's great for situations where you need more complex / multiple HTML insertions.

Based on GetPublii/Publii#1340 (comment)

Instructions

Go to [Publii site's directory] > [site folder] > input > [theme or theme override] > config.json and add/edit the following:

{ 
  "extensions": { 
    "postEditorConfigOverride": true 
  } 
}

Next, go to [Publii site's directory] > [site folder] > input > [theme] and add tinymce.override.json. In the file, adapt Publii's postEditor.config.js file to enable and add a toolbar icon for the template plugin:

{
"plugins": "template advlist autolink autosave codesample link image lists hr pagebreak searchreplace media table paste autoresize emoticons textpattern toc",
"toolbar1": "bold italic underline strikethrough forecolor publiilink unlink emoticons blockquote alignleft aligncenter alignright bullist numlist image gallery media table toc",
"toolbar2": "template styleselect formatselect codesample searchreplace hr readmore undo redo restoredraft removeformat sourcecode",
}

Below the toolbar2 line of the same file (and inside the closing bracket), you can start adding your template snippets. Here's an example to add <details> and <summary>:

  "templates": [
    { 
      "title": "Details disclosure element", 
      "description": "The details HTML element creates a disclosure widget in which information is visible only when the widget is toggled into an 'open' state. A summary or label must be provided using the summary element.", 
      "content": "<details><summary>Summary of the details</summary>Something small enough to escape casual notice.</details>" 
    }
  ]

TinyMCE Documentation Reference

https://www.tiny.cloud/docs/tinymce/latest/template/

Caveat

This technique does NOT work with theme overrides, so make sure to safeguard these modifications before updating your theme.

Also note that Templates are a deprecated TinyMCE plugin, and will become a paid TinyMCE plugin in version 7 (see old forum discussion).

Custom Formats (as detailed in the docs)

"Formats" are CSS classes which are added to regions of text whose elements match a certain selector. For example, the "Button dark" format option in the screenshot below adds a "class="btn" to selected text, but only if that text has an <a> tag. "Formats" can't wrap selected text with the HTML tag itself -- they only add classes.

Custom formats can be added in config.json by using "customElements": [

This method supports theme overrides.

Publii Documentation Reference

https://getpublii.com/dev/post-editor-api/#customformats

Custom Blocks

"Blocks" can wrap selected text with an HTML tag, but only if the HTML tag is a block-level element (as Tomasz suspected) -- except <code>, for some reason?

Expanding this one is tricky, and seems to only work for <div> (as far as my tests have confirmed). To do so, you have to go to [Publii site's directory] > [site folder] > input > [theme] (as detailed here and in the docs) and add a file called "tinymce.override.json". In the file, you can add:

{
  "block_formats": "Paragraph=p;Heading 1=h1;Heading 2=h2;Heading 3=h3;Heading 4=h4;Heading 5=h5;Heading 6=h6;Address=address;Pre=pre;Code=code;Blockquote=blockquote;DIV=div"
}

Publii Documentation Reference

This is based on the postEditor.config.js.

Caveat

This technique does NOT work with theme overrides, so make sure to safeguard these modifications before updating your theme.

It's not possible to wrap selected text with other useful HTML tags like <kbd>, <aside>, <span>, <mark>, etc. To do see, use the customElementsMode detailed above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment