Commands

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.

Writing app commands

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.

commands.py
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.

../../_images/commands-nailed-it-simple.gif

Meta options

name

The name is how slices refer to a command in include_commands.

Default:None
Optional:No

label

A label to associate with this command. This label is displayed on the button.

Default:‘please-assign-me-a-label’
Optional:No

icon

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'
../../_images/commands-icon-comment-o.gif

TODO: point to JBCommand docs.

success_message

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())
../../_images/commands-dynamic-success-message.gif

failure_message

A message to show the user when the command fails.

Default:‘Oops! Something went wrong!’
Optional:Yes

inputs

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.

response_action

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.

hide

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.

context

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.

data_type

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.

help_text

Default:‘Use this to create some help text about this command’
Optional:Yes

parameters

Default:()
Optional:Yes

Built-in commands

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.

Configuring commands

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.

Customizing built-in commands

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.

../../_images/commands-custom-download-image.gif