Tips & Tricks for Apps in Wolfram
Created Friday March 31, 2023
This document contains an overview of useful features and techniques for implementing apps that leverage the capabilities of Wolfram Notebooks. Several useful conventions are also described.
Background
Notebooks are a flexible document format supporting styled text, code, typeset expressions, hierarchy, images, videos, user-interfaces and more. Because they build-in support for such a wide range of textual, visual, and programmatic functionality, notebooks are a great starting point to build new tools and apps, which immediately benefit from access to so many powerful primitives.
This document is my attempt to record and share some of the things I’ve learned while developing notebook-based applications. Examples of applications I’ve written include:
Styling & Stylesheets
Inspect Settings for a Named Style
Learning how a built-in style works is often a great starting point to adding functionality to styles in your own app. CurrentValue
can be used to quickly query the FrontEnd about style options defined for a particular named style:
Creating Custom Stylesheets
Principles & Conventions
$PublisherID
.Programmatically Creating Notebooks With A Custom Stylesheet
When programmatically creating a new notebook or setting the StyleDefinitions
property of an existing notebook there are two types of values that are typically desirable to use.
1. Named Stylesheet Notebook File
Path to a named stylesheet notebook that is resolved by the FrontEnd at runtime:
StyleDefinitions -> FrontEnd`FileName[ {"ConnorGray"}, "NotebookWebsiteTools.nb", CharacterEncoding UTF-8 ]
2. Inline Notebook[..] Stylesheet
Inline stylesheet notebook, that may optionally inherit style settings from a named stylesheet notebook:
StyleDefinitions -> Notebook[{ Cell[StyleData[StyleDefinitions -> "ConnorGray/NotebookWebsiteTools.nb"]], (* Inline style definitions here *) ... }, StyleDefinitions -> "PrivateStylesheetFormatting.nb" ]
It is important the stylesheet notebook itself be styled by “PrivateStylesheetFormatting.nb”
so that selecting the Format > Edit Stylesheet
menu item shows a nicely formatted notebook like:
Instead of an unstyled raw stylesheet notebook like:
FrontEnd & User Interface
Adding Items to the File > New Menu
⚠️ This section makes use of undocumented features. Use these at your own risk.
FrontEndExecute[{ FrontEnd`AddMenuCommands["New", { MenuItem[ "<Something> Notebook", FrontEnd`KernelExecute[ MessageDialog["It works!"] ], FrontEnd`MenuEvaluator -> Automatic ] }] }]
Code Conventions
Organizing Package Code
A good notebook-based application should also provide an easy to use and coherent set of corresponding Wolfram Language functionality as well.
Convention: Create
Project
Notebook[..]
Principle: If your app uses notebooks that are specialized in some way, provide a function to create new blank notebooks.
Case Study: Organizer
ConnorGray/Organizer provides a CreateOrganizerNotebook[
type
,
title
]
function, where values of type
include:
“Log”
“Design”
“Tasklist”
Case Study: NotebookWebsiteTools
ConnorGray/NotebookWebsiteTools provides a CreateWebsiteNotebook[
type
,
title
]
function, where values of type include:
“BlogPost”
Convention: UI Actions ⇔ Code
Principle: Every UI action should correspond to a short piece of Wolfram code, ideally a simple function call.
The convention I follow is to back every interactive elements in the UI, for example buttons or popup menus, with an associated function in the UI`
subcontext of my app’s main Wolfram package.
Case Study: NotebookWebsiteTools
ConnorGray/NotebookWebsiteTools has a ConnorGray`NotebookWebsiteTools`UI`
context: