Editor app extensions (JavaScript)
The editor app is a React app built on WordPress's own React and wp.hooks. Snipfire Pro adds its part of the editor through the extension points below; you can use them for your own add-on.
Register at load time, before the app first renders: enqueue your script on the snipfire_before_app_script action (see PHP hooks), with wp-hooks and wp-element as dependencies.
wp.hooks.addFilter( 'snipfire.slot.settings.top', 'my-addon', ( fills, props ) => [
...fills,
MyField,
] );
Filters run on every render, so they may read the props they get. Everything on this page is the contract add-ons build against, and is kept stable.
Common props ("ctx")
Passed to slots, filters and views where noted:
| Prop | What it is |
|---|---|
config |
window.SnipfireApp: restUrl, nonce, schema, siteUrl, toolsUrl, … |
pro |
window.SnipfireApp.pro, or null without Snipfire Pro |
access |
{ level, canEdit, canPhp, canImport, canSettings, designHooks } |
api |
REST client: api.request( method, path, body, query ) → Promise (path relative to snipfire/v1/), plus list, get, update, …, and api.url( path, query ) for links |
toast |
toast( 'success' \| 'warning' \| 'error', message ) |
ask |
ask( { title, message, input?, confirmLabel, danger } ) → Promise: a confirm dialog |
openView |
openView( name, { value, params } ) opens a registered view (routed as #/name/value?params) |
openSnippet |
openSnippet( id ) opens a snippet (asks about unsaved changes) |
startSnippet |
startSnippet( fields ) opens a new, unsaved snippet with these settings and code ({ type, title, description, hook, priority, code, … }, the fields the server accepts). Asks about unsaved changes first. → Promise of true, or false when the person kept their changes. Snipfire Pro's Write with AI uses it |
Component slots
Filter snipfire.slot.<name>, starting value []. Return an array of React components (rendered with the slot's props) or elements. They're rendered in array order, in place.
| Slot | Where | Props |
|---|---|---|
settings.top |
Top of the settings panel | draft, onChange( patch ), readOnly (bool), items, schema, config, pro, access, openSnippet |
settings.afterWhere |
After How it runs / Where / Priority / Shortcode, before Load as | same |
settings.customHook |
Under the custom hook name field | same |
settings.where |
Under Where (and the paragraph or post number), before Priority, while the snippet runs automatically: the details of a location (Snipfire Pro's CSS selector) | same |
settings.bottom |
After Conditions | same |
editor.toolbar |
In the editor's toolbar, before History and ⋯ (Snipfire Pro's AI assistant button) | draft, dirty, busy, problems, readOnly (reason text or null), onChange( patch ), config, pro, access, api, toast, ask, … |
editor.banners |
Under the toolbar, after the read-only banner, before the error banner | draft, dirty, busy, problems, readOnly (reason text or null), onChange( patch ), save( patch? ) → Promise (merges the patch, then saves), config, pro, access, api, toast |
editor.side |
Beside the code editor, on the right (Snipfire Pro's live preview and AI panel). Hidden with the code while the Settings form tab is shown | draft, problems, readOnly, theme, onChange( patch ), config, pro, access, api, toast |
sidebar.itemBadges |
In each sidebar item, after the title | item (snippet settings, no code), config, pro |
sidebar.afterList |
In the sidebar, under the list of snippets (Snipfire Pro's From the network) | ctx + selectedId |
problems is what the Problems panel shows: { errors: [ { message, line } ], warnings: [ "…" ] }. draft.error is the error recorded when the snippet last crashed ({ message, line } or null).
Long snippet lists are drawn a screenful at a time (over 400 rows), so don't rely on every row being in the page; sidebar.itemBadges rows re-render when their item, the selection or the list changes.
Value filters
Filter snipfire.<name>:
| Filter | Arguments | Returns |
|---|---|---|
kinds |
kinds, { config, pro } |
The snippet kinds in the type picker and + New, in order: [ { kind, label, type, lang, language, tip } ]. kind is the id in #/new/<kind>; type/lang are what a new snippet gets; language is the Monaco language; tip() returns the hint under the editor |
statusFilters |
filters, { config, pro } |
Sidebar status chips: [ { key, label, match( item ) } ] |
toolbarStatus |
{ label, className }, draft, { config, pro } |
Text next to the Active switch, and a class for its label (e.g. is-testing) |
moreMenu |
items, ctx + { draft, readOnly } |
The ⋯ menu: [ { id, label, onClick, danger, disabled } ]. Built-in ids: duplicate, export, export-plugin, minimap, theme, settings, classic, delete |
newMenu |
items, ctx |
The sidebar's + New menu: [ { id, label, onClick } ]. Built-in ids: the kinds (php, html, css, js, …), generator, folder |
bulkActions |
actions, ctx + { ids, clear() } |
Extra buttons in the bulk actions bar while snippets are ticked: [ { id, label, onClick } ]. ids are the ticked snippets; clear() unticks them |
folderActions |
actions, ctx + { path, name, ids } |
Small buttons on a folder's row: [ { id, label, icon, onClick } ] (icon is shown; label is the accessible name and tooltip). ids are the snippets in the folder and its subfolders |
sidebarLinks |
links, ctx |
Sidebar footer links: [ { id, label, href } \| { id, label, onClick } ]. Built-in ids: tools, library, generators, import, welcome, export, classic |
runOptions |
options, the settings panel's slot props |
The choices for How it runs (PHP and HTML), in order: [ { value, label } ]. Built-in values: auto, shortcode, manual. A value kept for an add-on that isn't active is shown as needing Snipfire Pro |
prefill |
snippet, params, { config, pro, access } |
A new snippet opened from a link (#/new/<kind>?title=…&hook=…): return the snippet to start with. params are the link's parameters (strings, unchecked); title, hook and (PHP) code are already applied |
views |
views, { config, pro, access } |
Extra full-width views: { name: { component, label? } } (label names its tab on narrow screens). The component replaces the editor pane and gets ctx + { route: { value, params }, items, exists( id ), close(), reload() }. Names in use: snippet, new, import, library, generators, welcome, export-plugin, editor |
draftChange |
next, patch, previous |
Every edit of the draft in the editor: return the draft to keep |
historyFieldLabel |
label, field |
The name of a setting in the History view |
Actions
Action snipfire.<name>:
| Action | Arguments | When |
|---|---|---|
monaco |
monaco, { formatCode( language, code, options ), emmetCSS, emmetHTML } |
Monaco has loaded (once, when the first editor opens). Register languages, formatters, Emmet, themes |
Screens for another set of snippets
A page that shows the editor app for another set of snippets (Snipfire Pro's network screen uses it) points restUrl at its own routes and can set, in window.SnipfireApp:
| Setting | What it does |
|---|---|
features |
{ library, generators, import, welcome }: false hides that screen and its links (all on by default) |
contextLabel |
Shown next to "Snipfire" at the top of the sidebar, for example Network |
toolsUrl, classicUrl |
'' hides the Tools and classic view links |
In PHP, Snipfire\Admin\Admin::render_app( $config ) prints the app with such a config.
Opening the editor pre-filled
Links can open a new snippet with settings filled in:
/wp-admin/admin.php?page=snipfire#/new/html?hook=woocommerce_before_cart&title=Cart%20notice
/wp-admin/admin.php?page=snipfire#/new/php?code=…
The hook finder uses this for Add HTML here and Add PHP on this hook, and the element picker with its own parameters (#/new/html?hook=element:selector&selector=…&insert=…&match=…&post=…), which Snipfire Pro reads with the prefill filter. A link only fills in an unsaved draft; nothing is saved until the person clicks Save.
Something unclear or missing? Tell us