Handbook
CommandsCommands are used to process form input and create various effects.
Here's a list of commands currently available in BoltWire. Click one for more info:
Functions vs Commands
Commands and functions are similar in BoltWire. The difference is that functions are processed immediately when a page loads, whereas commands are processed only after the form containing them submits. Consider the following example:[(mail to=somewhere@boltwire.com from={~email} subject='I visited page {p}' body=report)]
This is a function--causing an email to be sent by simply viewing the page it is written on. Everytime you revisit or reload the page, another email is sent. It gets the return email address from the user's member page--assuming that information is stored there as a data variable. The page name will be showed in the subject line. The body of the message comes from a template.
A command allows you receive data from the user and then send the mail only after they submit that information. Here is a more useful example:
[form]
Subject: [text subject]
Message:
[box message rows=5 cols=50][box]
[submit]
[command mail to=somewhere@boltwire.com from={~email} subject={=subject} body={=message)]
[form]
Subject: [text subject]
Message:
[box message rows=5 cols=50][box]
[submit]
[command mail to=somewhere@boltwire.com from={~email} subject={=subject} body={=message)]
[form]
It looks similar to the function, but it inserts the subject and message supplied by the user into the email. I could have gotten the "from" email from a text input field if desired, but decided to use one already in the system.
Constructing Commands
A command is used in a form and always begins with the word "command" followed by the name of the command. If there is an underscore in the command name, only the part of the command up to the underscore is used. This allows you to use the same command multiple times. For example:[command time_1 '%Y-%m-%d']
[command time_2 '%h:%m:%s']
Note: the extension is only needed if you need to refer to the output of a specific command elsewhere in the form. BoltWire can otherwise keep each command separate with no problem.
You can put as many parameters in a command as desired and all are passed to the command function, but the first parameter (or the "value" parameter) is given special priority in most commands. In other words, the following two commands are essentially the same:
[command delete some.page]
[command delete value=some.page]
If there are spaces in the value (or any parameter argument) be sure to enclose it with quote marks.
Using Commands
When a form is submitted, BoltWire goes through a process to ensure the form is legitimate, and then filters and validates the input fields for security purposes and according to your instructions. See the forms tutorial for more information on this process.Then BoltWire begins to execute the commands in the order they appear in the form. Most commands return some value to the command which can then be used in future commands. Essentially you are writing a little script. Consider this example:
[form]
My favorite color today: [text color] [submit]
[command time %x]
[command log '{=time}: {=color}' page=log.color]
[form]
My favorite color today: [text color] [submit]
[command time %x]
[command log '{=time}: {=color}' page=log.color]
[form]
In this example, the user enters a color and the form is submitted. BoltWire then calculates today's date in the format 'MM/DD/YY' (see PHP's strftime function) and stores that value in the time command. Next the log command retrieves the time and color values and appends them to the specified page. That is log.color will be filled with lines that each look something like "05/23/14: Blue".
Complex Forms
Most forms in BoltWire are very simple. It's just a question of learning how each command works and supplying the correct parameters. However, there is no real limit to the complexity of the forms you can create with the ZAP form processor.Suppose you are doing a complex form but the final output is not working right--and you want to debug a specific line. You can use the warn command to peek at the value of a command at any time. In the example above, we could verify the time command is generating the right value by adding this line:
[form]
My favorite color today: [text color] [submit]
[command time %x]
[command warn {=time}]
[command log '{=time}: {=color}' page=log.color]
[form]
My favorite color today: [text color] [submit]
[command time %x]
[command warn {=time}]
[command log '{=time}: {=color}' page=log.color]
[form]
Once it is verified you would delete the warn command or move it to check a different value or a command's value at a different point in the form execution. If you thought the log command was changing the time command in some way, you could move the warn command immediately after the log command to show its state at that point in the form processing. You would, of course, find it unchanged in the example above.
Messages
BoltWire has a powerful built in messaging system that relays information back based on what's happening with the form processor. Consider the following example:[messages]
[form]
Delete some.page [submit]
[command delete some.page]
[form]
[form]
Delete some.page [submit]
[command delete some.page]
[form]
Normally, when you submit a form, it reloads the same page after the various commands are performed. In this case the form would report back a success or failure message based on whether or not the user had permission to delete that page.
If you wish to have the user forwarded to a different page, such as a thank you page or submission confirmation page, you could modify your form to look like this:
[messages]
[form]
Delete some.page [submit]
[command delete some.page]
[command nextpage another.page]
[form]
[form]
Delete some.page [submit]
[command delete some.page]
[command nextpage another.page]
[form]
In this case, if the delete command fails (lets assume they don't have permissions), the form will immediately abort, the page will reload, and the message will be displayed. But if the delete command succeeds, it will continue to the nextpage command and forward the user properly.
This is normally the desired behavior, but you could use the abort conditional to send them to a custom error page on a command failure:
[form]
Delete some.page [submit]
[command delete some.page]
[command nextpage another.page]
[form]
[if abort]<(forward error.page)>[if]
Delete some.page [submit]
[command delete some.page]
[command nextpage another.page]
[form]
[if abort]<(forward error.page)>[if]
Here, the abort conditional is only triggered if the form fails. Otherwise the page is delete and they continue on to another.page.
There are many more capabilities in the messaging system, that go far beyond this brief introduction. Please see the messaging tutorial in our concepts section of the handbook.
Page Shortcuts
Page shortcuts are automatically applied to the value of any command that ends with the letters 'page', and to the arguments of a page parameter in any command. Page shortcuts are a special shorthand used within BoltWire to refer to specific pages. Here is the list:.page | {p1}.page |
..page | {p1}.{p2}.page |
forum.+ | forum.1685831261 (timestamp) |
^ | {id} |
~bob | member.bob |
@admin | group.admin |
!edit | action.edit |
forum.# | forum.1000 (or next available number) |
So this command would create a new forum page:
[command create {=content} page=forum.#]
This line would forward a user to their member page:
[command nextpage ~^]
Action Pages
Action pages are normal pages that can be called in special ways. They often contain forms because of their special properties.If you call a page, say action.newpost, the browser will display whatever is on that page and treat the page variables as you would expect. If there were a form on this page, it would reload the same page when submitted, unless you set the nextpage value to some other page.
Because it is an action page, however, you can call it as an action and display it on top of another page. For example, if you pointed your browser to forum.1000&action=newpost, you would see the contents of action.newpost, but BoltWire would treat page variables as if you were on forum.1000. When you submitted the page, it would also revert to the underlying page (forum.1000). This makes action pages extremely useful.
Consider the following form which might appear on action.newpost, and notice how simplified it becomes:
[form]
Title: [text title '{:title}']
Content:
[box content cols=40 rows=5]<(source {p})>[box]
[submit]
[command savedata title]
[command edit {=content}]
[form]
Title: [text title '{:title}']
Content:
[box content cols=40 rows=5]<(source {p})>[box]
[submit]
[command savedata title]
[command edit {=content}]
[form]
First, the title data variable does not need to have the page specified, it will load the title of whatever happens to be the underlying page. The same with the source function, which preloads the content of the forum page into the content box. You simply point it to the current page. Similarly, you do not have to specify the target pages for the savedata and edit commands--it automatically goes to the right location.
To avoid overwriting the action page by accidentally calling it directly (ie action.newpost), you could add a simple line like the following:
[if equal {p} action.newpost]<(forward error.page)>[if]
Better still, to limit this to forum pages--consider this conditional:
[if ! equal {p1} forum || ! number {p2}]<(forward error.page)>[if]
Advanced Command Features
BoltWire has a number of advanced features connected with commands worth mentioning here. Some are slightly experimental or only work in certain situations. Use with caution.1) Conditionals. You can add a conditional parameter to any command except for list, info. In the example below, the command only processes if the current use is Bob. IE, only Bob can create the new forum page.
[command create {=content} page=forum.# if='equal {id} bob']
2) Translations. Suppose you are using a French language file. Command names are automatically converted from French to English. So [command creer...] is read as if it were [command create...].
3) Stop Watch. You can test how long it takes to perform the various commands in your form by setting $BOLTstopWatch to 'commands' in index.php before calling the engine. To see all commands and functions set it to 'all'. To only see functions set it to 'functions'. For commands, you also have to abort the form before it completes or the stopwatch results will disappear when the page reloads. The easiest way to do this is to temporarily add [command warn 'Abort for stopwatch'] just before the close of the form.
If you want to report the time for specific commands/functions, set $BOLTstopWatch to 'true' (or one of the other options) and then add stopwatch=true as a parameter to any command or function you wish. The times will appear immediately after the line that says "Page construction begun".
4) Output. You can modify the output of a command (the value passed back to the command after processing) by setting an output parameter to one of several options: output=false supresses all output. output=html returns the escaped html of the normal output. output=nolines replaces line breaks with a single space. output=csv replaces line breaks with commas to generate a csv list.
5) Escape. This can be set to true or false. Some commands return escaped values, and some do not. In certain cases you may wish to override the default behavior. For example, if you are using the output of one command that returns an escaped value as a parameter in a another command, the output will likely be garbled, because it doesn't have access to the raw data. Or if the output of a command contains unescaped markup that you want escaped for some reason, you can escape it. In most cases the default behavior is fine.
Toolmapping.
Toolmapping allows you to point a core command to a custom script, effectively overwriting the default behavior of the command. Suppose you wanted to customize how the login command works. Simply add the following line to index.php or config.php or a plugin, and when the login command is called, BoltWire will reroute the parameters to BOLTXmylogin (your script), rather than BOLTXlogin (the default script):$BOLTtoolmap['x']['login'] = 'mylogin';
It also works the opposite way. The following line would essential create a new "mylogin" command that maps to the default login command and functions exactly the same:
$BOLTtoolmap['x']['mylogin'] = 'login';
Toolmapping is a very powerful feature for customizing how BoltWire works. BoltWire can also remap functions (change the 'x' to 'f') and conditionals (change the 'x' to 'c').
Developer Information
All the commands available to BoltWire are included in commands.php and they are arranged in alphabetical order. There is a complicated forms input markup in markups.php used to generate BoltWire forms. Forms processing is a somewhat involved process in BoltWire, handled by several functions in library.php, and various lines of code in engine.php.To develop a custom command simply create a function prefixed by BOLTX modeled on one similar to your needs. Then add it to the config.php file or a plugin. It then becomes instantly available to your site. Suppose you wanted to create a command that allowed a user to self-join some group, perhaps the chess club on your site. You could use the following php function and then supply the form below it.
function BOLTXchessclub($args) {
global $BOLTid;
BOLTlog($BOLTid, 'group.chessclub', "\n", 'unique');
}
global $BOLTid;
BOLTlog($BOLTid, 'group.chessclub', "\n", 'unique');
}
[form]
[submit 'JOIN CHESSCLUB']
[command chessclub]
[form]
[submit 'JOIN CHESSCLUB']
[command chessclub]
[form]
You could of course do this with the log command using only core BoltWire functionality. This is just an example.
If you create a custom command it can be combined with other commands and all of BoltWire's built in forms processing capabilities. This means to do something quite complex you probably only need to add one or two small pieces to BoltWire's already robust core. If BoltWire can't get you all the way to your goal, it can definitely help get you most of the way!
If you develop an especially useful command consider posting it to our so we can put it in the Extensions area and share it with others.