Custom Sidebar Entries in Font View

Tutorial
by Rainer Erich Scheichelbauer
en fr zh

20 May 2015

You can customize your sidebar entries in the Font View. As it is very useful for verifying, sorting and filtering your glyph sets, and adding new scripts to Glyphs, it’s definitely worthwhile to learn how to do it. Plus, customizing your sidebar is quick to do!

You can add your own Categories or Languages to the sidebar in Font View (Cmd-Opt-1). Glyphs will look for a file called Groups.plist in ~/Library/Application Support/Glyphs/Info/. To navigate there quickly, choose Script > Open Scripts Folder (Cmd-Shift-Y), and look for a folder called Info next to Scripts. If it is not there, create it with the Finder command File > New Folder (Cmd-Shift-N).

And inside the Info folder, you create Groups.plist with a text editor, preferably one with syntax colouring for Apple Property list files (file suffix .plist). I can recommend Atom, TextMate, BBEdit, Xcode or SublimeText.

Custom entries for categories and languages have the following format:

{
    categories = (
        {
            name = "Compatibility";
            icon = compatibilityTemplate;
            subGroup = (
                {
                    name = "Web";
                    list = (
                        .notdef,
                        hyphen,
                        space
                    );
                },
                {
                    name = "Windows";
                    list = (
                        nbspace,
                        softhyphen
                    );
                }
            );
        },
    );
    languages = (
        {
            name = "Esperanto";
            icon = EsperantoTemplate;
            predicate = "script == \"latin\"";
            subGroup = (
                {
                    name = "Letters";
                    list = (
                        Ccircumflex,
                        ccircumflex,
                        Gcircumflex,
                        gcircumflex,
                        Hcircumflex,
                        hcircumflex,
                        Jcircumflex,
                        jcircumflex,
                        Scircumflex,
                        scircumflex,
                        Ubreve,
                        ubreve
                    );
                },
                {
                    name = "Marks";
                    list = (
                        circumflexcomb,
                        brevecomb
                    );
                }
            );
        },
    );
}

Copy and paste this sample Groups.plist content into your preferred text editor, adjust it to your liking, and save it as explained above. Then restart Glyphs, and the sidebar should look approximately like this:

Format details

When setting up your Categories and Languages, you have to stick to a few rules:

  • Put Category entries into categories=(...);.
  • Put Language entries into languages=(...);.
  • Each entry must have a name. You can leave out the straight quotes if the specified name has no spaces in it.
  • Each item in an entry must be terminated with a semicolon.
  • Each entry can either have a subGroup for nesting entries, or a comma-separated list list. They are mutually exclusive.
  • Top level entries can also have a script attribute. They will filter for the script tag if it is selected in the sidebar.
  • Entries can have an icon. The name specified must end in Template. You do not need to specify the file suffix. See below for details.
  • If you are confused about parentheses () and curly braces {}, here is the key:
    • parentheses () surround lists that contain comma-separated items of the same type, e.g., multiple language entries in languages=(...); or multiple glyph entries in list=();. There is always a semicolon after a closing parenthesis. The last item in the list does not need to have a trailing comma.
    • curly braces {} surround semicolon-separated items with unique names, and the structure is always name=content; and the content can be a number, a string or a list. If the curly brace is a list item, the closing curly brace may be followed by a comma.

Multiple Groups.plist files

You can have multiple Groups*.plist files in the Info directory. Filenames need to start with Groups and end with .plist, e.g., Groups-Batak.plist.

Adding icons

Glyphs will look for an image file with the specified name in a subfolder called Icons next to the Groups.plist file.

The icons can be in any image format that is supported by macOS. We recommend using black and white PDFs, because they scale. Make sure it is no more than 16 pixels high (16 pt at 72 dpi), and more or less as wide as it is high, so it fits nicely next to the name in the sidebar.

If you desperately want to use a pixel image, you will need to have two files in order to also support Retina screens: One must have 16×16 pixels, the other one 32×32 pixels. The large image needs to have a @2x extension in the file name, right before the dot suffix, e.g., esperantoTemplate.png and esperantoTemplate@2x.png. Again, the image name should end with Template. Then, the image is used as a mask to only use the alpha value. All color information is overwritten for the purpose.

Custom Filters

Do you want a sidebar entry just for a specific .glyphs file? Consider a Filter instead, the third section in the Font View sidebar, after Categories and Languages. For a filter, you need to create an XML file. Its name must start with CustomFilter, followed by a title, and must end with .plist, e.g., CustomFilter My Font.plist. Place it next to the .glyphs file. Next time you open the font, you will see a new section in the sidebar, under Filters, with the title you specified in the file name. In any event, the custom filter has the following basic structure:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    ...
</array>
</plist>

Yes, it is an XML file in spite of the .plist suffix. This is sometimes referred to as a ‘new-style property list’. The syntax further above (the one with parentheses and curly braces) is known as ‘old-style property list’.

Instead of the ..., you add dict entries representing your sidebar filters. You can have two kinds of dict entries: a smart filter or a list filter.

A list filter has the following structure:

    <dict>
        <key>name</key>
        <string>Legacy Marks</string>
        <key>list</key>
        <array>
            <string>circumflex</string>
            <string>tilde</string>
            <string>macron</string>
            <string>breve</string>
            <string>dotaccent</string>
            <string>ring</string>
            <string>cedilla</string>
            <string>hungarumlaut</string>
            <string>ogonek</string>
            <string>caron</string>
        </array>
    </dict>

So, it has two keys, name and list. The name consists of a string with the name of the filter. The list consists of an array of string entries, which in turn contain the glyph names. Sounds complicated? Maybe, but it is still simple, just look at the sample above and adjust it to your needs.

A smart filter has a slightly different structure:

    <dict>
        <key>name</key>
        <string>Exporting</string>
        <key>predicate</key>
        <string>export == 1</string>
    </dict>

Again, there are two keys: a name entry, just like in the list filter, but instead of the list key, there is a predicate key. The predicate contains a string representing the logical condition of the smart filter. Concatenate multiple conditions with AND or OR, nest conditions with parentheses (). For comparisons, you can use == and !=, but because it is XML, you will need to escape < with &lt; and > with &gt;. For string comparisons, you can also use CONTAINS, IN, ENDSWITH, STARTSWITH. In fact, use any of the NSComparisonPredicate Operators in all-caps.

As data for a predicate, use a GSGlyph property. The most important properties can best be explored by creating a smart filter in the UI and then examining the CustomFilter.plist in Glyphs’ Application Support folder. But in fact, you can use any of the GSGlyph properties for your predicates, even if they are not available in the UI. I’ll leave it at that for now. Happy exploring.


Update 2016-03-26: Fixed subGroup separation. Thx @zen and @kosbarts for reporting.
Update 2017-03-16: Fixed latin script tag in the sample. Thx @timahrens for reporting.
Update 2019-07-07: Fixed the script filter in top level categories. (script = latin > predicate = "script == \"latin\"";
Update 2020-03-23: Deleted extra space.
Update 2020-10-20: Update for Glyphs 3.