Note
This help should be accurate and comprehensive. If you see anything missing or that needs to be fixed, see How to Contribute or let us know in the Juice Slack #documentation channel.
Commands are code that runs on the server that is triggered by clicking a button on a slice.
Custom commands for an app should be placed in a commands.py
file in the
top directory of the app.
app.yaml
theme.yaml
commands.py <== App commands go here
public/
stacks/
Commands are customized by changing the Command Meta class.
Here’s a simple example of a commands.py file.
from jbcommands.jbcommandbase import JBCommand
class NailedItCommand(JBCommand):
"""
The 'Hello World' of commands.
"""
class Meta:
name = 'nailed-it'
label = 'Make a comment'
icon = 'icon-comment-o'
response_action = 'display'
def execute(self):
return "It is now {}".format(datetime.now())
Here’s what this looks like when run from a slice.
A label to associate with this command. This label is displayed on the button.
Default: | ‘please-assign-me-a-label’ |
---|---|
Optional: | No |
An icon to associate with this command. This can be any icon available in
Font Awesome. The icon name should be
prefixed with icon-
. The icon is visible in both the button and the
success and failure messages.
Default: | None |
---|---|
Optional: | Yes |
Here’s an example with a custom icon.
class Meta:
name = 'nailed-it'
label = 'Make a comment'
icon = 'icon-comment-o'
success_message = 'Let\'s pencil this in as done'
TODO: point to JBCommand docs.
A message to show the user when the command runs successfully. If omitted, successful commands will complete silently. To change the success message dynamically:
Default: | None |
---|---|
Optional: | Yes class NailedItCommand(JBCommand):
"""
The 'Hello World' of commands.
"""
class Meta:
name = 'nailed-it'
label = 'Make a comment'
icon = 'icon-comment-o'
response_action = 'display'
def execute(self):
return "It is now {}".format(datetime.now())
|
A message to show the user when the command fails.
Default: | ‘Oops! Something went wrong!’ |
---|---|
Optional: | Yes |
This option is used to describe a list of inputs that define the dialog presented to the user in the UI to collect the input. Currently support is limited to input and textarea form elements.
The structure of the meta option is:
inputs: [
{
'name': 'username',
'type': 'input',
'label': 'Please enter your username',
'placeholder': 'your username'
}
]
where:
name: | The name of the input field |
---|---|
type: | The type of the input. Can be one of (‘input’, ‘input-multiline’) |
label: | The label of the field |
placeholder: | The placeholder of the input. This property is only for ‘input’ or ‘input-multiline’ types. |
Input validation is done in the command and notified via a failure toast.
The user input received from the UI is available on the command instance in the command_input property. The command can use this property to perform any validations in the validate_input method:
def validate_input(self):
if not self.command_input.get('username'):
raise JBValidationError('Username cannot be empty')
If the validation fails, a 400 Bad Request response is sent. The UI shows the error response received as a failure notification.
Default: | None |
---|---|
Options: | ‘print’|’download’|’display’|None |
Optional: | Yes |
What should happen to the response returned by the command.
print: | Response should return a url to print. A print dialog box will be shown with the url as content. |
---|---|
download: | Response should be a url to download. The content at this url will be downloaded. |
display: | Response should be html text. This will be displayed as the success message. |
None: | Ignore the response. |
Default: | False |
---|---|
Optional: | Yes |
Should the button to trigger the command be hidden. This is useful if you need the command endpoint but don’t want to show UI for that command.
Default: | slice |
---|---|
Options: | ‘slice’|’discussion’|None |
Optional: | Yes |
The context for this command. It is used by the front-end to pass the context this command was run in.
slice: | The command will be passed the id of the slice that ran it, in a parameter called slice_id . |
---|
Default: | None |
---|---|
Options: | ‘slice’|’state’|None |
Optional: | Yes |
The data type for this command. It is used by the front-end to pass the command any contextual data it requires.
slice: | The command will be passed the html and css of the slice that ran it, in parameters slice_html and
slice_css respectively. |
---|---|
state: | The command will be passed the state of the slice that ran it - its filters, selected data set and pagination params. |
Default: | ‘Use this to create some help text about this command’ |
---|---|
Optional: | Yes |
Default: | () |
---|---|
Optional: | Yes |
There are several built-in commands
download-data: | Creates a downloadable Excel file. |
---|---|
download-image: | Downloads an image of the slice. |
print-image: | Pops a print dialog to print an image of the slice. |
post-to-slack: | Posts an image of a slice to a Slack channel. Requires app metadata. |
Commands can receive configuration that is provided in application metadata.
See Apps for more about metadata.
Configuration should be placed in a commands
dictionary with a key
containing the name of each command that needs configuration. For instance:
metadata:
commands:
post-to-slack:
hook_url: {url}
text: "This is cool."
image_title: "Current status"
These values are available when the command executes in a dictionary
self.app_command_config
.
Built-in commands can be customized by subclassing a built-in command and giving it a new name and new Meta options.
from jbcommands.builtincommands import DownloadImageCommand
class CustomDownloadImage(DownloadImageCommand):
"""
A customized Download image command
"""
class Meta:
name = 'custom-download-image'
icon = 'icon-camera-retro'
label = 'Download an image'
data_type = 'slice'
context = 'slice'
response_action = 'download'
Here’s what this looks like.