Code snippet pattern

Code snippet pattern

Goals

Code clarity

A key goal is code clarity - the user should be able to identify the code they need, either to copy and use or as a reference example. It should be clear that the user is looking at code (rather than prose) and that the code is readable.

Ease of use

Code is not particularly resistant to errors: a missing character (or in some languages, a space or tab) can lead to errors so the user should be able to select and copy the code easily. It should be clear which version, platform or other switchable type is being used - in addition, showing a title and description can help a user who is skimming the page (or arriving from a search engine) to immediately understand the significance of the code snippet.

Modularity

Not all code examples are the same and this pattern should be modular and extensible - allowing the documentation author to decide which elements to use and which are not required.

Code Title

The code snippet should have an optional title - this is to help orient the user, particularly users arriving at a page (or internal page anchor) from a link or search engine results page.

States

The title has one state which is visible.

Behaviours

The title is a string of text which truncates with an ellipsis if too long.

Anatomy

A string of text in Vanilla-standard typeface and weight.

Code Description

The code snippet can show an optional description. For many applications this will be self-evident, but it can be useful to leave the user in no doubt as to how this code works or in what applications it can be used.

States

If present, an ‘i’ (information) icon appears next to the code snippet title.

On hover, a tooltip is shown over the ‘i’ icon which contains the text of the description.

Behaviours

On hover, a tooltip is shown over the ‘i’ icon which contains the text of the description. It should truncate with an ellipsis if it passes a reasonable length so as not to break the view.

On a device with no hover (touch screen), a single tap displays the tooltip and a second tap anywhere on the view will close the tooltip.

Anatomy

Title and description

Version switcher

It should be possible to show a version switcher on a code snippet. This could be automatically displayed if the component detects more than one version of the example in the markdown/schema used to describe the code snippet. If one example is included, there should be no version switcher control displayed.

States

  • Hidden: The version switcher is not shown if only one code example is present.
  • Visible: The version switcher is shown, and displays the currently selected example title
  • Focused: The control is highlighted using the Vanilla standard focus highlight
  • Opened: The select menu is opened, showing the possible choices
  • Selected: The user has tapped a selection and the relevant code snippet is displayed

Behaviours

A Vanilla standard select menu which allows the user to pick from a list of items. Immediately on selection, the relevant code snippet is displayed.

Anatomy

Version switcher

Command Prompt

Showing a command prompt character can be useful for users to aid recognition and build familiarity that “yes, I am on the right track”.

Care should be taken to avoid the command prompt character being accidentally selected if the code is copied, as pasting the command prompt as part of the command will cause an error.

States & Behaviours

A character in the Vanilla monospace font, ahead of the code snippet, but not selected on;

  • Drag-select
  • Triple-click (line select)
  • Command / Control - A

The character itself can be specified in the markdown/schema for the example, but the code author can optionally leave it blank and no command prompt will be shown.

Each code example (code “version” - as controlled by the version switcher) can optionally have its own command prompt (for example “>” on Windows).

Anatomy

Command prompt (dollar sign)

Code Panel with Syntax Highlighting

The code panel shows the code the author wishes to display, complete with syntax highlighting and line-numbering, optionally selected by the author.

States

  • Visible: The code output panel shows the code in a monospace typeface.
    • The code is syntax-highlighted with relevant colours, if the author has specified a language for the highlighting.
  • Selected: The code output panel allows word, line, or ‘all’ selections to be made - no command prompts or extraneous characters are included in selections.

Behaviours

The author should be able to specify a language (from a list of supported languages) in their markdown / schema and this language applied to the code example for syntax highlighting.

Example:

```python
{code}
    ```

Authors can optionally leave this directive blank and utilise no highlighting.

The panel should not display an internal scroll control upon displaying long content, the code should appear in full, as part of the parent page. In cases of extremely-long content we’d advise the document author to reconsider if such a long example is necessary.

Wrapping: The panel will not wrap long lines by default, and will instead allow horizontal scrolling to accommodate long lines of code. The author can optionally force wrapping which will break code onto a newline visually, within the same line number.

Anatomy

Syntax highlighting

Output panel

In some applications it’s useful for the author and user to see an example of system output (along with any input in the previous panel).

States

  • Visible: The code output panel shows the code in a monospace typeface.
  • Selected: The code output panel allows word, line, or ‘all’ selections to be made

Behaviours

The output panel should behave in the same way as the code panel with syntax highlighting.

Anatomy

Output panel

Examples

Minimal example

All features utilised

No description, one version, no output

On-page mockup

Audit

We use these components in different implementations on both websites and products.

  • Docs
  • Tutorials
  • Blog posts
  • Websites
    • Micro websites (e.g. Microk8s, Multipass)
    • Product websites (e.g. MAAS.io)
  • Internal Tools
  • JAAS Dashboard
    • Juju Shell
    • Logs
  • MAAS App
    • Test results
    • Logs
    • Scripts
    • Cloud Init
    • DHCP Snippets
    • KVM host address
    • Instructions for adding a controller
  • Snapcraft.io
    • Release UI
    • Snap install pages
    • First snap flow
    • Publicise tap
    • Build logs
  • Charmhub.io
    • Charm/bundle detail pages

Have you considered making this a separate pattern? I don’t think anything about it is specific to code snippets. For example, we have an almost identical element in CVE listing table cells. It’s an alternative to a caption when there isn’t enough space to display the text all the time.

Same here — a useful function, but not just for code snippets.

2 Likes

Overall, I like this a lot. It uses familiar markdown syntax to denote and title code blocks. It addresses the problem of adding command prompt characters elegantly. And the dropdown to specify language or platform specific alternatives is nifty. I see myself using it frequently.

I’m not sure about the info pop-up. It feels more natural to me to just drop comments inline, in the comment style unique to that coding language.

For example:

# Generate a public/privatekeypair to use for authentication
openssl genrsa ...

This allows an author to tie comments to specific lines of code, in a way that will be intuitive and familiar to anyone familiar with code comments. And I think that it ups the chances that the comments will be read – I’m not sure how many people will know to click, tap, or hover over the i.

1 Like

For the info-pop-up, I think it’s helpful to imagine / provide examples when it would be most helpful:

  • where experts understand everything from the heading, but many would be left with questions?
  • where explaining the heading would seem obvious or tautological to seasoned users, who are consulting the material as a reference, or reminder, rather than as a tutorial
  • where a tooltip can reasonably be used to explain, i.e. the topic isn’t need enough to need a link elsewhere.

Thanks @cassiocassio - I think the reasons you list are sound, I’d add one thing: the reason this was added was to address a recognised need around visitors landing from search engines.

A large proportion of our documentation traffic derives from users;

  1. Landing from a search query and trying to get a specific example or to troubleshoot something, or
  2. By following a link from a Stack Exchange, or other forum post

In these cases it’s an effective way to orient the user that yes, this is the code snippet they’re looking for, without having to read around the code block too much for context.

I’d agree with @mpt also, this could very well be split out to a different bit of Vanilla UI as it does have much wider use than just within this pattern.

This is cool.

With the selection mechanism, it states that when focused, Ctrl+C will copy the entire code block.
Is there a visual indication that the entire block has been selected? I imagine it may be easy for a user to think that the code block has focus and they hit Ctrl+C but maybe they were mistaken. By way of comparison, on github, there’s a Raw button you can press to get a plain text view of the code with no bling then Ctrl+A and Ctrl+C will select all and copy. That’s a lot more keystrokes but it does give visual feedback as to what has been copied.
I assume also in the mocked up screen shot, if you click and drag with the mouse to select only a portion to be copied the line numbers are excluded? Sometimes you don’t want to copy everything, just a portion to get started or something.

Looks good, questions, is the intention for all these patterns to work with discourse primitives?

The version switcher looks more like a context switcher (Python, Dart, … or Windows, Linux, …) and not something I would related to version (Python 2, Python 3, … or Snapcraft using core20 or core18)

Good point. We should show the highlight explicitly, and probably not default to ‘select all’. I’d like to explore this interaction in more depth, but it’s a little misleading - will go and edit.

Yes, correct - we’d need to allow all of these elements to be specified within Discourse.

Edited. Added guidance about extremely-long content after discussion with @lyubomir-popov and the rest of the team.