layout | description | icon | title |
---|---|---|---|
documentation |
Overview of what is all included in Zazu Plugins |
fa-plug |
Creating Plugins |
- TOC {:toc}
There is a package boilerplate you can start your packages off of.
The best development workflow is to start the project on GitHub, install the
bare plugin inside of Zazu and work in the directory Zazu created itself. For
instance if you installed tinytacoteam/zazu-template
it would be located in
~/.zazu/plugins/tinytacoteam/zazu-template
and if you have GIT installed
locally, this will have origin
setup. Once you make your changes you can tell
Zazu to Reload Configuration
to see your change appear in Zazu.
Plugins, written in Node and JavaScript, provide all the end user behavior. Plugins use a workflow architecture, where some blocks return results, and other process data. You can have as many blocks as you want that can do their own specific tasks.
At the root of every plugin there is a zazu.json
file that tells Zazu how to
communicate with your plugin.
{
"name": "Demo Plugin",
"icon": "icon.png",
"stylesheet": "dist/main.css",
"blocks": {
"input": [
{
"id": 1,
"type": "Keyword",
"keyword": "play",
"title": "Test Notification",
"subtitle": "Click to test notifications",
"connections": [2]
}
],
"output": [
{
"id": 2,
"type": "SendNotification",
"title": "Hello world",
"message": "{value}"
}
]
}
}
icon
string: If the result does not provide an individual icon, the plugin icon will be used. The icon here is treated as a relative path.stylesheet
string: Optional. Relative path of a compiled stylesheet to be used when a single result is being previewed.blocks
object: Blocks are the foundations of every great plugin. They are so great, they have their own block page.
The input blocks in your plugins will need to return results to Zazu. Here is an example:
[
{
"id": "42",
"icon": "fa-calculator",
"title": "The answer is 42",
"subtitle": "Answer to the Ultimate Question of Life, the Universe, and Everything",
"preview": "<span>42!</span>",
"value": 42
}
]
id
string: Identifier for internal ranking.icon
string: Supports font awesome icons as well as relative paths to the icon in your project. If one is not provided it will fallback tot he icon for your project.title
string: Larger text you see in a result.subtitle
string: Optional. Smaller text under the title.preview
string: Optional. HTML that shows up next to an active result.previewCss
string: Optional. A css string to style preview.value
mixed: Value is the what is passed from block to block to make your plugin run. In this case the value42
as a number would be passed to whatever the connection block is, which could be to copy to the clipboard or it could run a custom user script.
If you provide results with an id
, Zazu will rank frequently clicked items
higher in the results list. This works well even if you sort the results
yourself. If you don't want this behavior, simply don't add an id
to the
result.
Zazu runs your application in the same thread, this is useful so your plugin can
share the same objects between blocks, however if you are planning on running a
long synchronous job, you should consider using a
child_process.fork
within your block.
In the Tray icon, under Development
there is a debugger called Plugin Debugger
that will output info, warnings and errors of all plugins in a
filterable interface. Select the plugin you are trying to debug and get logs
for all the blocks being executed.
The pluginContext
object passed to node scripts and contains some useful
functions to help enable your scripts.
The Plugin Debugger is useful, since we surface information to you to help you develop your plugins better. This API allows you to surface your own logs to the Plugin Debugger.
level
string: Log levelverbose
,info
,warn
orerror
message
string: Log message to be displayed.data
object: Other misc data that could be useful.
module.exports = (pluginContext) => {
pluginContext.console.log('verbose', 'hello world', {
ping: 'pong',
})
}
The current working directory of the node script being ran.
const path = require('path')
module.exports = (pluginContext) => {
const outputFile = path.join(pluginContext.cwd, 'output.json')
}
An instance of the Electron Clipboard instance.
const path = require('path')
module.exports = (pluginContext) => {
const clipboard = pluginContext.clipboard
}
An instance of the Electron Native Image instance.
const path = require('path')
module.exports = (pluginContext) => {
const nativeImage = pluginContext.nativeImage
}
Once you finish, submit it to the plugin page by making a package file in the documentation.