InputForms-Original
Summary: Adding Input form markup (out of date) Version: 2005-09-06 (last page update) Prerequisites: Status: superseded by PmWiki's Input? form markup Maintainer: Categories: Forms Superseded CookbookToDo
<< | Forms-related? | >>
WARNING: This recipe was broken by a change in PmWiki 2.0beta44. It will be fixed in due course, but it will take a while until I have sorted out the mess.
Note that the new version will have some changed defaults and parameter names for better uniformity with PmWiki core syntax. I also plan to move most of the documentation to Forms?, and maybe rename the recipe since it will be more an add-on to existing functionality than a separate recipe.
Joachim Durchholz September 06, 2005, at 02:23 PM
Update: Sorry, I haven't found the time to update the recipe, nor is it likely that this will happen within the next few months. The Real World keeps interfering... :-(
If anybody is willing to start work, I'll gladly help. Things to be done include:
- Check where this recipe and the PmWiki core for form input overlap, and where they conflict.
- For overlaps, simply remove the functionality from this recipe.
- For conflicts of syntax, it's probably an inconsistency. Adapt this recipe to be consistent to the way that the PmWiki core handles it.
- It might be a good idea to rip out most of the form generation engine and simply hook into what the PmWiki core does. The PmWiki core has very weak error-checking capabilities, so it's a pity to do that, but it doesn't make sense to keep error checking just for a few add-on input facilities.
- For semantic conflicts, investigate the situation and determine what to do.
The remains will probably be just a small add-on that defines those input controls that the PmWiki core neglected. Maybe it will define some additional options for the input controls already defined in the core.
Joachim Durchholz February 28, 2006, at 12:34 PM
Question
How do I create an input form?
Answer
Download Attach:input.php into your cookbook/
directory and add
include_once('cookbook/input.php');
to your config.php
.
input.php
will define the (:input ...:)
markup that allows to define an HTML input form. It does not cover receiving the input data or generating an HTML response - that's the domain of an external CGI script or yet another recipe.
Markups
Parameters in the (:input ...:)
markup are subject to the following rules:
Mandatory parameters are given as parts of the markup syntax, e.g.
(:input data name value:)
Text in monospaced font
must be given as shown, text in monospaced italics
is a placeholder.
Optional parameters may be inserted in any order between the last mandatory parameter and the closing :)
colon-and-parenthese.
An optional parameter can be a single name as in
readonly
or a name-value pair delimited by an equals sign as in
text=text
The equals sign can be surrounded by blanks.
Parameter values may be enclosed in double quotes; those that aren't end at the first blank.
To include a double-quote or backslash character in a parameter value, precede it with a backslash. (This applies even if the value isn't in double quotes.)
Most markups have a name
parameter. Such a name
is used to identify data that's submitted for processing, so in most cases, it must be unique between (:input start...:)
and (:inputend:)
.
Most errors in an (:input...:)
markup will result in an error message on the wiki page.
Forms
(:input start script:)
This starts an input form.
As an exception, this markup must be first on its line.
Parameters:
script
'http://your.domain.tld/path/to/pmwiki?action=handler'
.
method=method/submethod
post
or post/binary
POST
method with a multipart/form-data
encoding. It is the only method that can transmit arbitrary binary or UTF data without problems.
post/urlencoded
POST
method with application/x-www-form-urlencoded
data.
post/text
POST
method with a text/plain
encoding. This is mostly useful if the sent data is not processed by a program but by a human, e.g. if the script
URL is a mailto:
address; not recommended for other purposes, except for compatibility with CGI scripts that expect their data in text/plain
format.
get
name
. Provided for compatibility with existing CGI scripts that expect input data in the form of the GET
method with application/x-www-form-urlencoded
data.
name=value
pairs. CGI scripts written in PHP can pick these off from $_POST['name']
(or $_GET['name']
if method=get
). For most PHP versions, this data will also be available in $_REQUEST['name']
regardless of the method
setting, but some PHP versions didn't fully populate $_REQUEST
.
(:input end:)
This finishes the input form.
As an exception, this markup must be first on its line.
The blank space between input
and end
is optional.
You need not specify this markup; the recipe will automatically insert it before the next (:input start...:)
or the end of the page.
(:input button name label:)
This creates a button control that, when clicked, will submit the current state of the input form to the WWW server.
The label
parameter gives the label to show on the button.
The only available optional parameter is:
disabled
The clicked button will submit name=label; any other buttons will not submit anything.
(:input hidden name value:)
This provides data for the script without showing it to the visitor.
It creates a "hidden input field" that will submit name=value
.
Note that this control is provided only for compatibility with non-PHP scripts that can't access session variables. To pass hidden data to a PHP-based script, simply assign the value to a session variable like
$_SESSION['recipe_name']['name']
and the data will remain available throughout the browser session.
Text input
(:input line name:)
This creates a single-line input control.
Available optional parameters are:
columns=number
maxcolumns
, below.)
disabled
maxcolumns=number
:
password
readonly
text="text"
(:input text name:)
This creates a multi-line input control.
Note that it's impossible to limit the size of the input in such a control. However, both WWW servers and PHP installations are usually configured to reject any requests that exceed a given byte size.
It will submit name
= text
, where text
is the contents of the text field at the time of submission.
Available optional parameters are:
columns=columns
disabled
readonly
rows=rows
text="text"
Choices
(:input checkbox name:)
This creates a checkbox control.
Available optional parameters are:
disabled
checked
value=text
HTML allows that multiple checkboxes may have the same name
. This doesn't work properly with this recipe though: the values would all get written to the same variable, and you'd get only the last value written. So, it's better to use different names
for each checkbox.
(:input radiobutton name:)
This creates one of a set of radio-button controls.
Multiple radio-button controls may have the same name
. Together, these radio buttons form a radio button group: if one of them gets checked, all others in the group are automatically unchecked.
This control takes exactly the same optional parameters as checkbox
.
(:input menu name:)
This begins a menu. Optional parameters are:
disabled
lines
lines
lines visible if this is more than 1. The default is 1.
multiple
The only thing between (:input menustart...:)
and (:input menuend:)
should be (:input menuentry...:)
, (:input menugroup...:)
, or (:input menugroupend:)
markup.
If the multiple
option is set, name
will automatically have a pair of square brackets appended. If the data is sent to a PHP script, this will cause PHP to automatically extract any multiple values and place them in an array.
Example:
If a menu without multiple
is written like this:
(:input menu single-select-menu:) (:input menuentry 'menu entry #1':) (:input menuentry 'menu entry #2':) (:input menuend:)
and the user selects the first menu entry, a PHP script would see
$_REQUEST['single-select-menu'] == 'menu entry #1'
For a menu with multiple
like this:
(:input menu multi-select-menu multiple:) (:input menuentry 'menu entry #3':) (:input menuentry 'menu entry #4':) (:input menuend:)
with both menu entries selected, the PHP script would see
$_REQUEST['multi-select-menu'][0] == 'menu entry #3' $_REQUEST['multi-select-menu'][1] == 'menu entry #4'
A non-PHP script will see this:
single-select-menu=menu entry #1
and
multi-select-menu[]=menu entry #3 multi-select-menu[]=menu entry #4
Note: While this is called "menu" here and in the HTML standards, most browsers implement this as a scrollable list box or as a drop-down list.
(:input menugroup name:)
This begins a submenu. The only optional parameter is:
disabled
Note that MS Internet Explorer as of version 6.0 doesn't honor this option. If you disable the submenu, you should also disable each entry in it.
Note that the current HTML standard doesn't allow nested submenus. This limitation is expected to be lifted in the next version of HTML; in other words, it will take years until the majority of browsers can be expected to support nested submenus.
(:input menugroupend:)
This ends a submenu. Every (:input menugroup...:)
must be finished off with an (:input menugroupend:)
to generate standards-compliant HTML.
(:input menuentry value:)
This creates a menu entry that displays the value
. Optional parameters are:
checked
disabled
value
is never submitted to the script.
(:input menuend:)
This ends a menu. Every (:input menustart...:)
must be finished off with an (:input menuend:)
to generate standards-compliant HTML.
Testing your forms
There are two ways to easily test your forms.
One is specifying a mailto:
URL in the (:input start...:)
markup. Actually the HTML specification leaves the browser's behavior unspecified in this case, but at least Mozilla is known to open a mail window with the name=value
pairs ready for human inspection.
To make this work, you must specify method=post/text as well.
To sum it up, the first line of the form should read
(:input start script='mailto:any@where' method='post/text':)
The other is sending it to your own PmWiki installation with ?action=diag
. PmWiki will then dump all its global variables.
Just make sure you have
$EnableDiag
= 1;
set in your config.php
. The first form line would look something like
(:input start script='http://doma.in/path-to-wiki?action=diag':)
Just search the output for the names of your controls and you'll find the variables where the data is submitted (it's quite likely that you'll find the same data in multiple places). Note that the places where the form data can be found will be the same for all PHP scripts, whether they are part of a PmWiki script or stand-alone.
When comparing this approach to the mailto:
approach, it has the advantages that you can directly see the PHP variables that will get the form data, and that you don't need a specific browser; it has the disadvantage that you have to sift through lots of irrelevant data.
Notes and Comments
- This recipe was last tested on PmWiki version: 2.0beta37
- This recipe requires at least PmWiki version: 2.0
All positional parameters (such as script
in (:input start...:)
) can also be given in name=value
form. I.e. instead of
(:input start 'http://...':)
you can also write
(:input start script='http://...':)
so that both you and anybody who edits that markup sees a bit more precisely what's going on.
This effect was initially a side-effect of the way that parameter parsing was done, but it's considered a permanent feature now.
Note that the order must still be preserved. This is classified as an annoyance - please feel free to improve the code.
Joachim Durchholz July 06, 2005, at 05:18 PM
File controls are not covered. I didn't have the time to explore all the ramifications of allowing uploads, such as whether the uploads should go to the standard upload directory or a freely specified one. However, on the technical side of things, the recipe has been programmed to allow uploads.
Joachim Durchholz May 20, 2005, at 04:21 PM
Bugs
The (:input end:)
before the end of a page (or table cell) isn't generated automatically. This means the the generated HTML will be invalid, but it will still work fine on the vast majority of browsers.
This bug is currently unfixable, since the hooks that PmWiki uses to close off nested unclosed HTML structures aren't fit for use by a recipe.
The current workaround is to explicitly close off any (:input start...:)
with an (:input end:)
.
(:input menu...:)
isn't implemented yet. Actually the syntax may change drastically, since implementing the nearly-nested structure as described above carries some technical complications.
See Also
Change and contribution history
Date | Contributor | Ver. | Comments |
---|---|---|---|
2005-06-26 | Joachim Durchholz | First alpha release. | |
2005-06-28 | Joachim Durchholz | 0.1 | Adaption to Module Guidelines?. Made (:form end:) optional. |
2005-06-28 | Joachim Durchholz | 0.2 | Defined (:input start...:) and (:input end:) to be block markup, which is necessary to generate compliant HTML. This also implies that these markups must be first on a line (which is OK since HTML <form...> tags start a new paragraph anyway). |
2005-06-29 | Joachim Durchholz | 0.3 | Simplified session support (we don't need any...). (:input data...:) consequently renamed to (:input hidden...:) since its only purpose is now generating an <input hidden...> tag to communicate with non-PHP scripts. |
2005-06-30 | Joachim Durchholz | 0.4 | Implementation change: Reduced the number of markup rules to 1. This makes it easier to add markup before or after it (relevant improvement for "building block" recipes like this one). |
2005-07-04 | Joachim Durchholz | 0.5 | Fixed an embarassing bug in HTML generation. Thanks to Christian Schlatter for diagnosing it and providing a correction. |
2005-07-07 | Joachim Durchholz | 0.90 | Finished alpha tests. Slight improvements in error reporting. Fixed numerous bugs in HTML option generation. Changed keywords in (:input start method=...:) to better reflect the wikipage author's view of the world. |
2005-07-07 | Joachim Durchholz | 0.91 | Fixed recognition of second and subsequent (:input...:) markup on a wikitext line.Fixed inadvertent generation of paragraphs when an (:input...:) markup was first on a wikitext line. |
2005-07-07 | Joachim Durchholz | 0.92 | Added (:input menu...:) markup. |
2005-07-09 | Joachim Durchholz | 0.93 | Fixed a bug in the definition of INPUT_VERSION (that bug is inconsequential unless somebody else defined INPUT_VERSION). |
2005-07-11 | Joachim Durchholz | 0.94 | Bug fix: Will now generate default values for those HTML attributes that are required by the HTML standard. |