I moved this feature under the Editor entry because what I talk about here are the widgets of the inline editor offered as the editor plugin. For this reason I marked this page as Details only.
Some of the content of this page needs to be duplicated somewhere else and then this page removed. There are many important points such as the security entry at the bottom.
We want a way to make it really easy to create the HTML output.
At first I was thinking about forms, however, to make it really easy for the entire output we want to support widgets. This means we can create output only widgets (i.e. a table of data, a blog feed, etc.) and we can create forms (i.e. user can enter data and send it to a server.)
So... here and there this page may still talk about Forms instead of Widgets.
XML supports a language called XSLT which is used to transform one type of tags into another. For example, we can easily transform a <textfield> tag with a set of attributes and maybe some default data into a set of HTML tags such as <label>, <input>, etc. as may be required.
At this point we're thinking to use CppCMS (TBD, I think that CppCMS is not going to give us Widgets...) which generates the forms and parses the POST replies (TBD). However, there is an advanced server on SourceForge (name required) that has the ability to create Widgets1. That sounds like a much better plan than using fields. A widget includes many functions and is most often not just one <input> tag in a form.
The forms include fields that users can fill and a button to push to send the results to the server.
Forms need to be versatile enough to allow for:
This can be a problem if we don't also offer an escape (i.e. a link/button to "cancel") since the AJAX code could fail.
In some cases we may just want to hide the whole form (i.e. a form used as a survey and we want the user to answer just once...)
As a special button capability we want to support a double confirmation. So if someone asks to delete a page, he can click on the Delete button and that opens a pop-up that requires the user to confirm the feat: Do you really want to delete that content?
Also for pages the damage is minimal since they only get hidden (the Hidden state or category, opposed to Published, In Moderation, etc.) it would be a pain to allow easy deletion.
This should be applied to any button that does an action that's a bit harder than average to fix.
An example of functionality is how the title of a page is used to generate the URL for that page. As the user types the page title, we want to show the user how the URL will look like once published (i.e. a la WordPress, but without the bugs found in WordPress...)
We want to support the following types:
A Normal Widget shows up on the user screen and is expected to include all the normal functionality of a widget. This is certainly the most common in a standard form.
This can include complex widgets such a CAPTCHA or a Date Picker. It can also be a set of widgets (i.e. to enter a complete address.)
Widgets have many properties such as a description shown in the help area of the widget (maybe under the widget or as you enter the widget, it is displayed in the Help Box of the form) and when the widget allows free form data entry it could also include a regular expression used to check that the data entered is valid (i.e. a widget that only accepts digits could use /[0-9]*/ or /[0-9]+/.)
Note that in some forms data in one field depends on data in another field. For example, in an address widget, you could have one widget for the name of the country and depending on that selection, the state widget would display a specific list of states. This may require some AJAX since the list of states should be filled after a the country is selected. Other types of inter-widget specifications can require a test such as a limitation in the number of characters (say 140) between a select URL and a message that will use that URL. (i.e. imagine that someone is writing a twit about a page, we get a shorten URL for that page and know it's 20 characters, now the user can write a message of 119 characters maximum - URL is 20 + 1 space + 119 = 140.)
Finally, there are times when a form morphs as the user makes his selection. For example, if you have a choice between accepting comments or not on a page, when not accepting comments, that's it. When accepting comments, you may also let the user choose whether the comments should be displayed top to bottom or bottom to top or maybe you want to offer a limit on how long the users have to comment on a page (i.e. after 30 days, close the comments.)
Display Widgets are used to display data on the screen. Display widgets do not allow users to enter data, it is only to offer an easy way to display the data.
For example, we want a way to display tables (rows and columns of data.) This is very much in link with layouts that define the location where data shall be displayed (i.e. attach table A to box X, text message B to box Y, and image C to box Z,) although the layouts themselves only know about ready to be displayed HTML data to fit in their different boxes.
A Hidden Widget includes public data, which means the data is sent to the client's browser that is expected to send it back with the exact same value.
Hidden widgets are used for:
A Data Widget is something quite a bit peculiar. Data Widgets hold data on the server side, but do not send that data over to the client's browser. In other words, this can be private data.
It is used, for example, to hold the session identifier that the user is expected to post back to us when he's done filling out the form.
When getting a form ready, you can add data widgets that are saved in the session cache for that form. When the form is sent back, that data is available to the validation functions and the submit function which saves the data entered by the end user as required by that plug-in.
The "Normal Widgets" is a group of widgets including all the visible widgets (i.e. simple text fields, number fields, dropdowns, lists, etc.) The other two types are widgets by themselves.
The form capability should give users a way to create forms. This means a page can be composed of form elements and a submit button. All the form elements will behave just the same in a user defined page as it would in a plugin defined page, only submissions are saved by the user forms plugin for later review by administrators.
This capability gives the end users a way to create specialized contact forms, surveys (a la Drupal webform,) questions (a la Facebook,) etc.
The form can be saved in a submission list and it can be sent to a list of email addresses. The email address can be determine dynamically (i.e. if submitted on a user's page, then the destination would be that user's email address.)
When the form is a plugin form, then the POST goes to the plugin instead.
This must be built in the widgets. Default widgets should be defined (such as a widget to only enter a number, an US zip code, a UK postal code, etc.)
To allow translations, we want to offer widgets that display one or more languages and give one input widget to write the corresponding translation.
For a translator who can write multiple language, we can also mark several of the entries as input widgets instead of all but one. This way, a person who can read English and translate to Spanish and Portuguese would be shown:
Also we want to clearly detect whether a change was made in a language or another to properly propagate the need for further translation. Not only that, we want a little more than just one "Save" (publish) button. We do want to be able to say whether the translation(s) are considered finished or whether it still needs work.
Since IE8, Safari 4, and pretty old FireFox, we can make use of the DOM Storage facility as defined in Mozilla (for older versions of IE, we could make use of the userData object.) The Mozilla documentation actually includes a sample code with a fallback implementation so older browsers can revert to using cookies for that data. However, remember that Cookies are quite limited (about 64Kb per cookie, and a cookie lasts only for a small amount of time and may get deleted by the browsers to get the space for another cookie in another website.)
We want to have a way to tell whether we created the form or whether the user built a packet and sent a POST without us first creating said form (i.e. spammers do that big time.)
This is done by including a hidden field in the form that includes some random number. If that number is not found in our form sessions (or it got invalidated / out of date,) then the form either timed out or was sent by a spammer.
Considering caches, we want to make sure that the same session number can be reused multiple times. With AJAX we could get an extra authorization code too.
To Be Honest
Some forms will be posted just once (i.e. in most cases an edit form) those should prevent all other users from editing the same thing. Such a form offers ONE session. Once used up, that's gone. Other forms, such as the search form or a comment form, are for multi-uses. This means the same session could be reused multiple times since having multiple users using the same form is not a non-sense. (Of course, the distinction is really necessary only if you're caching forms since otherwise it doesn't really make sense: if always fully dynamic, you'd definitively get a session for each instance.)
All the data in the form must be checked for security reasons (i.e. SQL command, PHP code, etc.) This means removing any data that does not satisfy a certain validity (i.e. this entry much be a number, only digits are accepted!)
The Spam module is used to check out data that is posted on the site. That can include names, URLs, and a CAPTCHA widget.
We certainly want to offer a way for all forms to appear on secure pages (which is a problem with a log in block and / or search feature.)
We may also want to offer a way to send all forms over HTTPS, even if the user is currently on HTTP. This is 100% secure, although most people have no clue. I think that as long as we offer the feature, we're good.
Because a form may include some sensitive data, we need an auto-clear feature for forms.
This could be defined on a per widget basis and can ripple to the entire form (i.e. if one or more field is marked as an auto-clear, so is the form.)