Plugin: Collapsible Sections

I wrote a plugin to easily create collapsible blocks in notes. The blocks are unobtrusively styled, remember whether they were left opened or closed, and can be nested as much as desired. Headings within notes can also be made automatically collapsible. Works on desktop and mobile, and in both the webview and editor. Markdown within the title and body of blocks is typically respected.

The basic format is something like this:

:{Title
Body
}:

becoming something like this:

<details><summary>Title</summary>Body</details>

(see below for screenshots)

Although it's rather forgiving with how things are formatted.

There are settings to change the open/close tokens from :{ and }: to anything else, plus options to enable/disable the color coding that can be applied to deeply nested blocks in the editor and webview.

GitHub link: GitHub - ntczkjfg/joplin-plugin-collapsible-block

Full documentation:

Joplin Plugin - Collapsible Sections

This Joplin plugin allows you to create collapsible blocks with a title and extendable body. The blocks:

  • Can be nested within one another
  • Remember if they were left opened or closed
  • Can color-coordinate between the editor and webview
  • Collapse in both the editor and the webview
  • Support the use of markdown within them

Additionally, this plugin allows you to collapse headings within notes, in both the editor and the webview, with no additional syntax.

There are many settings available to customize the desired features and behaviors.

This plugin works on both Desktop and Mobile.

Version: 1.9.0

Installation

  • Open Joplin and navigate to Preferences > Plugins
  • Search for Collapsible Sections and click install
  • Restart Joplin

Uninstall

  • Open Joplin and navigate to Tools > Options > Plugins
  • Find the Collapsible Sections plugin
  • Press Delete to remove the plugin, or click the toggle to disable it
  • Restart Joplin

Usage

Collapsible blocks

In order to create a collapsible block, you can:

  • press on the Collapsible block toolbar button to create a template collapsible, or
  • highlight text then press on the Collapsible block toolbar button to convert it to a collapsible, or
  • or manually type in the following format:
:{Block title
Block body here
And here
And here...
}:

Nothing but whitespace may come before the :{. The title of the block must always appear on the same line as the :{. A title may be omitted. You can choose to put the }: on the same line as the last line of body text, or on its own line, but nothing is allowed to come after the }:. In general, this plugin is designed to be extremely forgiving with how things are formatted and indented. The following examples (and more!) are all valid:

Examples:

:{}:

:{
}:

:{

}:

:{Title}:

:{Title
}:

:{Title

}:

:{
Body}:

:{
Body
}:

:{Title
Body}:

:{Title
Body
}:

(for readability, the last way is recommended)

The text in the editor will use CSS to automatically indent blocks, based on how deeply nested the blocks are. This can be disabled or configured in the settings.

Blocks will remember if you left them opened or closed. They will do so by editing the opener in the editor from :{ to :{:{ when opened, or back to :{ when closed. You may also do this manually.

If you don't want it to remember if you left a block opened or closed, you can turn this off globally in the plugin settings - or on a per-block basis by doubling the end token, from }: to }:}:. When you do this, you can still open and close the block in the webview, but they will not save their state in the editor - so the next time the note is loaded, they will be opened or closed again, depending on whether their opening token is :{:{ or :{, respectively. So a block like :{:{this}:}: will always be initially open when you open a note, while a block like :{this}:}: will always be initially closed when you open a note.

When nesting blocks within blocks, they can be color-coded in the editor, and may also be color-coded in the webview. These can both be controlled (enabled or disabled) in the plugin Settings tab.

Collapsible Headings

When you create headings within a note (by starting a line with #, ##, ###, ####, #####, or ######), this plugin automatically makes them collapsible, with no additional syntax required. This can be enabled or disabled in both the editor and the webview in settings. The collapsible region beneath a heading will extend to the next heading of equal or higher precedence. So, for example, a # heading will collapse to the next # heading, while a ### heading will collapse to the next #, ##, or ### heading. Collapsible headings and collapsible blocks do play nicely with each other, and can be nested freely.

Headings do remember if they should be left opened or closed (This can be disabled in settings). Due to the lack of special syntax, this is done by adding or removing a space from the end of the line with the heading. A heading with no space at the end is considered opened, while a heading with a space at the end is considered closed. For example:

# This heading does not end in a space, and so will render as opened when the note is loaded
This text will be visible when the note is loaded. 
# This heading does end in a space, and so will render as closed when the note is loaded 
This text will not be visible when the note is loaded. That is because there is a space ↑ here, after the word 'loaded', in the previous line. 

Screenshots

Various headings and collapsible blocks, all open, with colors enabled

The same note, with some headings and blocks collapsed

Settings

There is a settings page for the plugin in the Joplin options. There, you can:

  • Enable or disable the color coding in the webview and editor
  • Customize the start and end tokens away from the default :{ and }:
  • Globally disable the plugin's ability to remember if a collapsible block's opened/closed status was changed in the webview
  • Disable automatic CSS indentation of collapsible block text in the editor, or configure it to indent more or
  • Enable or disable collapsing within the editor as well as the webview
  • Toggle whether folding changes in one view automatically trigger folding changes in the other view
  • Enable or disable header-based collapsing in the webview or editor
  • Enable or disable remembering whether headers were left opened or closed

Advanced

Custom styles

If you would like to style the collapsible blocks to your preference, use the following in your userstyle.css file, which can be accessed in Joplin → Tools → Options → Appearance → Show Advanced Settings → Custom stylesheet for rendered Markdown:

/* Styling of the collapsible block */
details.cb-details {

}

/* Styling of the collapsible block title */
details.cb-details summary {

}

/* Below are used for coloring nested collapsible blocks, and will
only be applied if colors are enabled in the plugin settings */
:root {
    --cb-color-0: #a0a0a0;
    --cb-color-1: #6b5fd6;  /* blue-violet */
    --cb-color-2: #2bb0e6;  /* bright cyan-blue */
    --cb-color-3: #6b5fd6;
    --cb-color-4: #2bb0e6;
    --cb-color-5: #6b5fd6;
    --cb-color-6: #2bb0e6;
    --cb-color-7: #6b5fd6;
}

Troubleshooting

If the collapsible block is not showing up, or is showing up but you're unable to toggle it opened or closed, then you're likely accidentally in the Rich Text Editor, instead of the Markdown Editor. Joplin's Rich Text Editor does not support most Markdown plugins. To enter the Markdown editor, look for the controls in the image below, in the upper right of Joplin. Make sure the Markdown/Rich Text toggle is on the left (red) side, and then use the blue button to swap between the editor and webview.

Issues

Acknowledgement

Thanks to the creator of the Joplin Spoilers plugin, whose code helped me build this plugin. Our code bases and methodologies are wildly different at this point, but it got me started with Joplin plugins.

Other plugins

Check out my other plugins:

  • Click-to-Copy Spans! Easily lets you create spans of text that, when clicked, are automatically copied to your clipboard for fast and easy pasting.
  • Hotstrings & Hotkeys! Easily define custom hotstrings and hotkeys you can use in any note.
3 Likes

[placeholder]

I've updated this to 1.1.

The update adds support for doubling the end token from just }: to }:}:. Doing this causes a collapsible block to not save its state in the editor when it gets opened or closed in the webview - so you can have it be always opened or always closed when a note is initially loaded. There was already an option to do this globally in settings - now this option allows it on a block-by-block basis.

So a block like :{:{this}:}: will always be initially opened when a note is loaded, while a block like :{this}:}: will always be initially closed when a note is loaded. You can still open and close them in the webview, they just won't remember that state when the note is reloaded.

1 Like

I've actually gone ahead and updated again, to 1.2.

The major feature this time around is automatic CSS indentation in the editor - so it's no longer recommended to indent collapsible block bodies yourself. If you've already got your bodies manually indented, and don't feel like updating them, the new automatic indentation can be disabled entirely in the plugin settings.

I did also remove a custom CSS rule that suppressed the code block formatting on indented collapsible blocks, since indenting them is no longer recommended. If you'd like to re-add that rule, you can put this in your userstyle.css:

.cb.cm-codeBlock {
    border: none;
    background-color: transparent;
    font: inherit;
}

That said, I do recommend removing any indentation you have from the old system. The new system plays much nicer with other editor plugins and visuals - for example, it'll now display multiline code blocks and lists correctly in the editor, even when using WYSIWYG plugins like Extra Markdown editor settings.

The README was also updated for this release on GitHub - including updated (barely changed) screenshots, plus a couple new ones for settings and troubleshooting. I've edited the updated README into the second comment in this thread.

1 Like

Hi, first of all thank you for this plugin. I use joplin for maths notes and there seems to be no way to render katex in dropdown summary.

<details><summary> No KaTeX rendering here </summary>
</details> 

If could you please add the support for ipad. It will be super helpful.

Thank you.

1 Like

Hi :slight_smile: I tested it out, and it seems like KaTeX already works in my collapsible block summaries. You just need to make sure to wrap the KaTeX in $ and $, instead of $$ and $$: The single dollar sign syntax is for inline KaTeX, which the summary needs to be.

Hi,
You are absolutely right. Rendering was not possible earlier with the native <details> tag but it works with this plugin. I should have said more clearly :grinning_face_with_smiling_eyes:. The plugin is very helpful. If the support could be extended to ipad then it would be really greeeat.

Thanks

Right, the raw <details> tags seem to support neither form of KaTeX (or any markdown in general) - but that's not really relevant to this plugin: Any and all raw HTML is already built-in and works without plugins. The plugin just adds the custom markdown syntax and some CSS, and explicitly allows for the use of markdown within the title and body.

Are you saying that the inline KaTeX doesn't work with the plugin's Markdown syntax on iPad? I don't have an iPad to test with - but that would be strange to me: The plugin does support mobile, which I assume is the version of Joplin the iPad would use, and the inline KaTeX titles do show up in testing on my Android phone. Got any screenshots of the issue?

Hi,
The plugin is available for android but I could not find the plugin on iPad. Maybe it is not released there or something else. I have attached screenshot.

iPadOS Version: 18.5

Thanks for the screenshot - after a bit more research it unfortunately seems like this is intentional on Joplin's part, to comply with Apple's AppStore guidelines, as seen in the note on this page. Only officially recommended plugins are usable on iOS.

I don't know if this will work, as I have no iOS devices to test with - but on Android, if I expand that Advanced settings section, I have the option to install a plugin from file. If you have that option on iOS, you could try downloading the plugin's .jpl file from my GitHub, and use that to install the plugin manually.

If you don't have that option (or you do but it doesn't work with my .jpl file), then I unfortunately think it's simply not possible to use non-officially-recommended plugins on iOS.

2 Likes

This was what I was worried about. There is no option to install via file or anything else. I don't know if this is feasible or not, but if we could get the plugin approved / vetted by team then there could be some way. Could also try to get this merged with any other KateX/math related approved plugin (again not sure if this is possible).

The functionality is very useful for someone using KaTeX.

Recommended plugins are marked by a gold crown icon and have been vetted and recommended by the Joplin team
1 Like

I unfortunately think getting my plugin on the officially recommended list is a bit unlikely for now - per this page there's no (current) review process for getting on the list, and it's just plugins by Joplin team members and frequent contributors - of which I am neither (I just started with Joplin in May of this year).

1 Like

I had been using the collapsible block using regular HTML tags but things are much better with this plugin. The result looks better and the expand/collapse status is kept when moving from note to note.

However, on the android with pre-release 3.4.6 I noticed some unexpected behaviour. After starting the app, the first note opened that contains a collapsible block, is not rendered correctly. When I move to a different note and then return to the first, the note looks normal. It does not matter if the block state was expanded or collapsed. I have tested this multiple times and it always happens after I “Close all” apps on my phone.

Glad to hear you’ve been enjoying it :slightly_smiling_face: I don’t know what would cause that issue you’ve described, but I’ll look into it shortly. Hopefully it won’t be too difficult to diagnose/fix.

So far, I can confirm what you describe. This is actually an improvement from 3.4.5, which I was on before your report, where neither this plugin nor my click-to-copy plugin worked at all. Now both work after the note reloading you described.

It seems like this is all related to the recent addition of the mobile Rich Text Editor somehow - there are a couple of bug fixes in 3.4.6 that reference this plugin directly, even.

I don’t know if the fault with the remaining issue lies with my plugin or the Joplin updates, but I will do a deeper dive soon to figure out if it’s something I can fix on my end.

I went ahead and published version 1.2.1 as a hotfix.

I want to note that it’s a particularly low-quality hotfix - previously, the plugin would quit trying to render if it didn’t receive what the startToken and endToken should be from settings in time, and the intended behavior is that it should re-render once it gets those settings. For whatever reason that’s failing on just the initial load in 3.4.6 (a big improvement - it failed on every attempt in 3.4.5). The hotfix just hardcodes the values of startToken and endToken to the defaults, :{ and }:, in the case where it couldn’t get them from settings. So the hotfix will work for anyone using those defaults, but anyone who has changed the tokens will still experience the bug (and a new bug, if they happen to use the :{ }: tokens for something other than my plugin). I am hoping it will simply stop being an issue in future releases.

I have similarly updated the click-to-copy plugin.

1 Like

Amazing plugin, congratulations!!!

Is there a way to integrate it with Outline? Or, more simply, to write the titles in heading mode (# Title or ## Title)?

kindly
Stef75

Thanks! :blush:

I’m not sure what Outline is, sorry - but for the titles, did you mean being able to do things like this?

:{# Title
    Body
}:

and having the title render as a heading in the webview? If so, that’s not something I have planned - I’ve considered it before but couldn’t think of a clean way to make it work. Maybe it’s worth looking into again - but, assuming Outline is another plugin that detects and interacts with headers, I wouldn’t necessarily expect it to detect a header in this position. Maybe a workaround could be to add some special syntax that indicates the first line after the opening token contains the title, rather than the first line of the body, like this?

:{nottitle
    # Actual title
    Body
}:

It’s a little messy, but I don’t think it would be that hard to code, and it would likely work with other plugins that work with headers. I could maybe add it as an undocumented feature if this is the sort of thing you’re after?

If you meant something else - the next version of the plugin, which I haven’t actually worked on in over a month but which I got pretty far along on before I lost motivation, does include an option to make all headings into collapsibles by default, Obsidian-style (or so I’ve been told - I’ve never actually used Obsidian). These collapsibles don’t remember if they were left opened or closed, though, since they just attach to the regular heading syntax. Maybe I’ll make finishing that up a goal for October…

Thank you for your response;
Outline is a plugin that, by reading the headings, generates a Table of Contents (a sort of index, useful for very long notes) on the side.

I did some testing, and the solution, not very elegant but functional, was:

:{Description
# Description
Body
}:

or

:{Troubleshooting
# Troubleshooting
Body
}:

This allows me to have a title in the collapsible block and a title in the TOC:

I’ll try the future update.
Thanks
Stef75

alas