If you are more comfortable writing code than using UI-based tools like the Extension Builder, you can also build your extension with a script using the ExtensionBundle object from mojo.extensions.

The example script below is part of the Boilerplate Extension, and is written to work with the other files in that repository. If your files are organized differently, you may need to make some changes to the script.

'''build RoboFont Extension'''importosfrommojo.extensionsimportExtensionBundle# get current folderbasePath=os.path.dirname(__file__)# source folder for all extension filessourcePath=os.path.join(basePath,'source')# folder with python fileslibPath=os.path.join(sourcePath,'code')# folder with html fileshtmlPath=os.path.join(sourcePath,'documentation')# folder with resourcesresourcesPath=os.path.join(sourcePath,'resources')# load license text from file# see http://choosealicense.com/ for more open-source licenseslicensePath=os.path.join(basePath,'license.txt')# boolean indicating if only .pyc should be includedpycOnly=True# name of the compiled extension fileextensionFile='myExtension.roboFontExt'# path of the compiled extensionbuildPath=os.path.join(basePath,'build')extensionPath=os.path.join(buildPath,extensionFile)# initiate the extension builderB=ExtensionBundle()# name of the extensionB.name="myExtension"# name of the developerB.developer='RoboDocs'# URL of the developerB.developerURL='http://github.com/roboDocs'# extension icon (file path or NSImage)imagePath=os.path.join(resourcesPath,'icon.png')B.icon=imagePath# version of the extensionB.version='0.2.2'# should the extension be launched at start-up?B.launchAtStartUp=True# script to be executed when RF startsB.mainScript='hello.py'# does the extension contain html help files?B.html=True# minimum RoboFont version required for this extensionB.requiresVersionMajor='1'B.requiresVersionMinor='5'# scripts which should appear in Extensions menuB.addToMenu=[{'path':'doSomething.py','preferredName':'do something','shortKey':'',},{'path':'doSomethingElse.py','preferredName':'do something else','shortKey':'',}]# license for the extensionwithopen(licensePath)aslicense:B.license=license.read()# compile and save the extension bundleprint('building extension...',end=' ')B.save(extensionPath,libPath=libPath,htmlPath=htmlPath,resourcesPath=resourcesPath,pycOnly=pycOnly)print('done!')# check for problems in the compiled extensionprint()print(B.validationErrors())