The procedures in this article apply to eZ Publish 3.10.0 with the Website Interface, although the overall principles should also apply to other versions of eZ Publish with and without the Website Interface.
Objects and information collection
There are two methods in eZ Publish to collect and process information from site visitors:
Information collection: creating forms using objects with attributes marked as information collectors
This method uses the “information collection” features of eZ Publish. The most obvious example of this is the contact form (see below) present in a standard Website Interface installation.
With this approach, you create an eZ Publish object that displays as a form to visitors. When visitors fill in the form, new eZ Publish objects are not created. Instead, the information is stored in a separate part of the system and, if configured to do so, emailed to a recipient. This tends to be the method of choice when the user’s input is not made public (for example, in contact forms); and when user responses are collected together for display purposes (for example, in polls).
Contact form, based on the Feedback form object
This article goes through an example with the information collection method. The image below (click to view the full-size image) is a road map for the collected information form functions. It is a useful outline to consult when creating your own forms and when following along in this article.
Collected information form functions road map
Enabling users to create objects
Under this method, the user’s input becomes part of the website as an object in the eZ Publish content node tree. An example of this is creating a new Comment object beneath an existing Article object (to be displayed when visitors view the article). For this to happen, the user must have the appropriate permissions to create the object at a given location within the content structure. Some other examples of this method are the Forum topic and Forum reply objects within an eZ Publish forum.
This approach may use eZ Publish workflows so that a site administrator must approve the user's object before it is visible on the website.
The table below outlines some of the characteristics of each method and is useful for readers who want to explore eZ Publish's features a bit more.
| Enabling users to create objects
| Information collection
|
Concept
|
User fills in a form that becomes a new object in the eZ Publish content structure.
|
User fills in a form, but this does not become a new object in the eZ Publish content structure - instead, the form is handled by eZ Publish's information collection modules and features.
|
Examples basic functions
|
- Article comments - Forum topics and replies
|
- Feedback forms ("contact us" forms) - Polls
|
Datatypes (see the Reference documentation on datatypes)
|
Class for the object does not use information collector datatypes. This means:
- More datatype options - Possible to use custom datatypes
|
Class for the object uses information collector datatypes. This means:
- Limited datatype options - Use of custom datatypes is more difficult. One method for dealing with this limitation is to pre-process form input in a custom edit template and then encode the input into a Text line datatype.
|
Permissions
|
Set via user and user group permissions in the Administration Interface.
|
May use permissions, although anonymous access can also be defined in settings in collect.ini.
|
What happens within eZ Publish?
|
A new object (or object awaiting approval) is created in the content node tree.
|
No new object is created in the content node tree. Instead, a new entry is made in the collected information area under the Setup tab in the Administration Interface.
|
Actions
|
Can be used in workflow processes.
|
Option to send email showing information collected (set in collect.ini).
|
Fetch functions - how can I access and use the data collected? (see the Reference documentation on fetch functions)
|
Normal eZ Publish content fetch functions - a rich range of access and sorting possibilities.
|
A limited range of fetch functions:
- collected_info_collection
- collected_info_count
- collected_info_count_list Some of the typical object access and sorting possibilities are unavailable in fetch functions for collected information.
|
Templates
|
Standard eZ methods, using edit and view templates, or create your own custom edit and view templates.
|
Expect to have to make your own template to view and edit the form. This can be done using elements from the Poll and Feedback form templates.
|
Creating a custom form
In this article, I will walk you through creating a custom membership application form on the eZ Tennis Club website.
The form will collect the following information from site visitors, storing it on the site and emailing it to a specified email address:
- Given name
- Surname
- Date of birth
- Phone number
- Email address
- Postal address
- Opt-in specifications about receiving certain club information
- Open-ended questions or comments
When we are done creating the form, it should look like this:
Final membership application form
The first step in creating the membership application form is to create a class for the object that will collect the information from visitors.
To do this, log in to the Administration Interface and click on the Setup tab. In the left menu, click the Classes link:
Click on the Classes link
Then, in the Class groups window, click the Content link. Our form will appear in the Content branch of the site's node tree and thus be under this group:
"Content" class group
You are then presented with a list of all the existing classes in the Content class group. At the bottom of this list, click the New class button:
New class button
This will then display the Class edit interface:
Class edit interface
In our example, the name of the form is “Membership Application Form”, its identifier is “membership_application_form” and the object name pattern is “<form_name>”.
To add an attribute, select the datatype from the dropdown list at the bottom of the page and click the adjacent Add attribute button. Then, fill in the necessary information for the attribute. Repeat this in order to add subsequent attributes:
Add attribute
Note that the attributes that will collect information (through form fields presented to the visitor) need to have the Information collector checkbox marked:
Information collector checkbox
Rather than repeating the explanation of the steps to add each attribute, the information for all the attributes is summarized in the table below:
Name
| Identifier
| Datatype
| Required
| Searchable
| Information collector
|
Form Name
|
form_name
|
Text line
|
Yes
|
Yes
|
No
|
Form Introduction
|
form_introduction
|
XML block
|
No
|
Yes
|
No
|
Given Name
|
given_name
|
Text line
|
Yes
|
No
|
Yes
|
Family Name
|
family_name
|
Text line
|
Yes
|
No
|
Yes
|
Date of Birth
|
date_of_birth
|
Date
|
Yes
|
No
|
Yes
|
Contact Phone Number
|
contact_phone_number
|
Text line
|
Yes
|
No
|
Yes
|
Email Address
|
email_address
|
E-mail
|
Yes
|
No
|
Yes
|
Postal Address
|
postal_address
|
Text block
|
Yes
|
No
|
Yes
|
Please send me information about the club's tennis tournaments
|
option_play_in_tournaments
|
Checkbox
|
No
|
No
|
Yes
|
Please send me information about tennis classes and professional coaching
|
option_classes_and_coaching
|
Checkbox
|
No
|
No
|
Yes
|
I would like to receive the monthly club newsletter by email
|
option_club_newsletter
|
Checkbox
|
No
|
No
|
Yes
|
Please keep me informed about the club's social events and competitions
|
option_social_events_ competitions
|
Checkbox
|
No
|
No
|
Yes
|
Can we help by answering any questions?
|
other_questions
|
Text block
|
No
|
No
|
Yes
|
Membership Coordinator E-mail Address
|
membership_coordinator_email_ address
|
E-mail
|
Yes
|
No
|
No
|
Re-organizing class attributes
Sometimes, when creating a class, it is useful to change the order of the attributes. This determines the order of attributes presented when a user creates an object (thus creating the form). If a custom template to display the form is not used, then this order also determines the order of the fields when the object / form is viewed on the front-end of the site. The elements highlighted below can be used to re-order attributes.
Reorganize class attributes
There are two ways to re-order attributes:
- Use the arrow buttons to shift the current attribute up or down one position in the class attribute list; or
- Change the attribute numbers, which can be faster than moving attributes with the arrow keys if you need to re-order many attributes at once.
When using the first method, the page will automatically reload with the attribute order changed. However, if the attributes are renumbered using the second method, you must click the Apply button (or OK button if you are finished editing the class) to store the changes.
Saving the new class
Once you have entered all the relevant attribute information, click the OK button to add the new class.
The next step is to modify the appropriate INI settings in order to configure the form.
Defining how information is collected
The settings/collect.ini file contains some useful form options.
Recall from the first article in this series that eZ Publish reads basic settings from the default INI files, which are overriden by any settings in the specific siteaccess overrides, which are overridden by settings in the global override files. You should never modify the default INI files.
The settings below should be created in the file collect.ini.append.php located either:
- In the directory for the siteaccess (in settings/siteaccess/[name_of_siteaccess]/) that will display the form; or
- In the override directory (in settings/override/), meaning it will apply to all siteaccesses.
If the override file does not already exist, you must create it.
The sections below show the settings that need to be included in the INI file. Note that lines starting with hash symbols are comments.
[InfoSettings] block
The setting below specifies that there is an information collector based on the class ID “membership_application_form”, and that the identifier for the information collector is the same as the class name.
[InfoSettings]
# Matches class id or identifier to information collection type
TypeList[membership_application_form]=membership_application_form
[EmailSettings] block
Sometimes it is useful to send an email summarizing the results of each form submission. This is not required for objects such as polls, but we will use it in our membership application form.
[EmailSettings]
# Matches class id or identifier to information collection type
# SendEmailList[poll]=disabled
SendEmailList[membership_application_form]=enabled
[DisplaySettings] block
The DisplayList setting specifies the page that should be loaded after the form is submitted. There are three main options:
-
Result – Displays a "result" template (such as a poll result or a confirmation page), typically located in
[design_extension]/templates/content/collectedinfo/. This is the option we will choose for our membership application form.
- URL – Load a specific URL.
- Node – Redirect back to the original content node. For example, a user filling in a form would be redirected back to the page containing the blank form. In this case, you can configure the form template to display some confirmation text above the blank form to acknowledge the submission.
[DisplaySettings]
# result - Display IC result, for instance poll result or your form data
# redirect - Redirect to a specific url
# node - Redirect back to content node
# Matches class id or identifier to information collection type
#DisplayList[poll]=result
DisplayList[membership_application_form]=result
[CollectionSettings] block
Some forms need to be available to anonymous users. This is determined by the setting below.
[CollectionSettings]
# if enabled then information from anonymous users can be collected
# CollectAnonymousData=enabled
# Same as CollectAnonymousData but is a list of IC types and
# their override settings, if specified it will override default setting
CollectAnonymousDataList[membership_application_form]=enabled
The CollectionUserData setting specifies how to handle users submitting a form multiple times, and is explained well in the comments to the setting.
# How information collection is handled in terms of user identification
#
# multiple - each user can submit multiple data
# unique - one set of data per user, if already exists give a warning
# overwrite - one set of data per user but new entry overwrites old one
CollectionUserData=multiple
# Matches class id or identifier to information collection type
#CollectionUserDataList[feedback]=multiple
CollectionUserDataList[membership_application_form]=multiple
Making the form visible in the site’s menus
eZ Publish does not automatically include objects of a new class in the default top or left site menus. For example, the top menu displays the objects that are directly below the top-level node of the Content branch, but only for the classes specified in menu.ini. Similarly, the left menu displays the objects that are directly below the second-level node that is currently being viewed, but also only for the classes specified in menu.ini. The new Membership Application Form class needs an entry in the relevant menu.ini file.
This example uses the Website Interface extension, so either of these settings override files can be edited:
/extension/ezwebin/settings/menu.ini.append.php
OR
/settings/override/menu.ini.append.php
The entries added are shown below.
menu.ini settings
This may not be necessary for all forms if you do not need them to be visible in the top or left menus (for example, if you are just going to link to the form in the body of an article). In our case, we have added the appropriate entries to both the TopIdentifierList setting (objects of these classes are shown in the flat_top menu template at extension/ezwebin/design/ezwebin/templates/menu/flat_top.tpl), and the LeftIdentifiersList setting (objects of these classes are shown in the flat_left menu template at extension/ezwebin/design/ezwebin/templates/menu/flat_left.tpl).
Menu areas
Form view template INI settings
Without an override template, eZ Publish will use the /node/view/full.tpl template to display the form, but that template does not include the elements required to display and process the form properly.
To point eZ Publish to the correct template (which we will create next), edit the override.ini.append.php file for each siteaccess, such as the “eng” siteaccess:
/settings/siteaccess/eng/override.ini.append.php
Add the following entry to the override file:
[full_membership_application_form]
Source=node/view/full.tpl
MatchFile=full/membership_application_form.tpl
Subdir=templates
Match[class_identifier]=membership_application_form
Creating the full view template
The next step is to create the template file that was defined in the override.ini.append.php settings file.
In this example, the new form template will be placed in the appropriate folder within the directories for the Website Interface extension:
/extension/ezwebin/design/ezwebin/override/templates/full/membership_application_form.tpl
The easiest thing to do is to copy the template for the default eZ Publish feedback form (feedback_form.tpl) from the same directory and adapt it to the new form. Our membership_application_form.tpl template is shown below. For more information about the eZ Publish template language, see the templates section of the technical manual or the eZ Publish Basics book.
{* Membership Application Form - Full view *}
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"></div></div></div>
<div class="border-ml"><div class="border-mr"><div class="border-mc float-break">
<div class="content-view-full">
<div class="class-membership-application-form">
<div class="attribute-header">
<h1>{$node.name|wash()}</h1>
</div>
{* validation *}
{include name=Validation uri='design:content/collectedinfo_validation.tpl'
class='message-warning'
validation=$validation collection_attributes=$collection_attributes}
{* form introduction *}
<div class="attribute-short">
{attribute_view_gui attribute=$node.data_map.form_introduction}
</div>
<form method="post" action={"content/action"|ezurl}>
{* Given Name *}
<h4>{$node.data_map.given_name.contentclass_attribute.name}</h4>
<div class="attribute-given-name">
{attribute_view_gui attribute=$node.data_map.given_name}
</div>
{* Family Name *}
<h4>{$node.data_map.family_name.contentclass_attribute.name}</h4>
<div class="attribute-family-name">
{attribute_view_gui attribute=$node.data_map.family_name}
</div>
{* Date of Birth *}
<h4>{$node.data_map.date_of_birth.contentclass_attribute.name}</h4>
<div class="attribute-date-of-birth">
{attribute_view_gui attribute=$node.data_map.date_of_birth}
</div>
{* Contact Phone Number *}
<h4>{$node.data_map.contact_phone_number.contentclass_attribute.name}</h4>
<div class="attribute-phone">
{attribute_view_gui attribute=$node.data_map.contact_phone_number}
</div>
{* Email Address *}
<h4>{$node.data_map.email_address.contentclass_attribute.name}</h4>
<div class="attribute-email">
{attribute_view_gui attribute=$node.data_map.email_address}
</div>
{* Postal Address *}
<h4>{$node.data_map.postal_address.contentclass_attribute.name}</h4>
<div class="attribute-postal_address">
{attribute_view_gui attribute=$node.data_map.postal_address}
</div>
{* Information – Play in Tournaments *}
<div class="attribute-option">
{attribute_view_gui attribute=$node.data_map. option_play_in_tournaments}{$node.data_map. option_play_in_tournaments.contentclass_attribute.name}
</div>
{* Information – Classes and Coaching *}
<div class="attribute-option">
{attribute_view_gui attribute=$node.data_map. option_classes_and_coaching}{$node.data_map. option_classes_and_coaching.contentclass_attribute.name}
</div>
{* Information – Newsletter *}
<div class="attribute-option">
{attribute_view_gui attribute=$node.data_map. option_club_newsletter}{$node.data_map. option_club_newsletter.contentclass_attribute.name}
</div>
{* Information – Social Events & Competitions *}
<div class="attribute-option">
{attribute_view_gui attribute=$node.data_map. option_social_events_competitions}{$node.data_map. option_social_events_competitions.contentclass_attribute.name}
</div>
<br/>
{* Information Other *}
<h4>{$node.data_map.other_questions.contentclass_attribute.name}</h4>
<div class="attribute-message">
{attribute_view_gui attribute=$node.data_map.other_questions}
</div>
{* Form buttons - Processing *}
<div class="content-action">
<input type="submit" class="defaultbutton" name="ActionCollectInformation" value="{"Send form"|i18n("design/ezwebin/full/feedback_form")}" />
<input type="hidden" name="ContentNodeID" value="{$node.node_id}" />
<input type="hidden" name="ContentObjectID" value="{$node.object.id}" />
<input type="hidden" name="ViewMode" value="full" />
</div>
</form>
</div>
</div>
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"></div></div></div>
</div>
The template above displays as follows:
Result of membership application form template
Note that this article does not cover CSS issues to customize the style of the form. See How to Skin an eZ Publish Site for more information about editing the CSS for a Website Interface site.
Translating form elements
In our template, the labels for the form fields (such as "Given Name" and "Postal Address") are pulled from the names of the content attributes for the corresponding fields. As a result, to translate the form in the future, you must edit the content class in the destination language.
For example, if one of your site languages is French and you want to translate the form into French, you would first access the list of classes in the Content class group. In the Administration Interface, click the Setup tab, then the Classes link in the left menu, then the Content link representing the appropriate class group. Then, click the link for the Membership Application Form class. You will be presented with the Class view interface that lists, among other things, the attributes for that class. At the bottom of the page, select "Another language" from the drop-down list, then click the Edit button. You can then edit the names of the attributes in French, which will be shown as the form field labels when someone accesses the form on the French siteaccess.
Submission confirmation template
The submission confirmation template for the form is loaded after the user clicks the Send form button (and after the system has validated the information in the form - for example, if an invalid email addresses is typed into the corresponding field, the form will reload with a warning). It acts as an acknowledgment that the site has received the form information.
For example, suppose our form was filled in as follows:
Application form filled
From the collect.ini.append.php file, eZ Publish knows it is working with an information collection form called “membership_application_form”. After the user clicks the Send form button, eZ Publish looks for the corresponding template in the /content/collectedinfo/design directory.
In this case, we will use form.tpl (the template for the default eZ Publish feedback form) in that directory as a model. Our new template is placed in /extension/ezwebin/design/ezwebin/templates/content/collectedinfo/ and looks as follows:
<div class="border-box">
<div class="border-tl"><div class="border-tr"><div class="border-tc"></div></div></div>
<div class="border-ml"><div class="border-mr"><div class="border-mc float-break">
{default collection=cond( $collection_id, fetch( content, collected_info_collection, hash( collection_id, $collection_id ) ),
fetch( content, collected_info_collection, hash( contentobject_id, $node.contentobject_id ) ) )}
{set-block scope=global variable=title}{'Form %formname'|i18n('design/ezwebin/collectedinfo/form',,hash('%formname',$node.name|wash))}{/set-block}
<h1>{'Thank you for your application.'|i18n('design/ezwebin/collectedinfo/form')}</h1>
<h2>{$object.name|wash}</h2>
{section show=$error}
{section show=$error_existing_data}
<p>{'You have already submitted this form. The data you entered was:'|i18n('design/ezwebin/collectedinfo/form')}</p>
{/section}
{/section}
{section loop=$collection.attributes}
<h3>{$:item.contentclass_attribute_name|wash}</h3>
{attribute_result_gui view=info attribute=$:item}
{/section}
<p/>
<a href={$node.parent.url|ezurl}>{'Return to site'|i18n('design/ezwebin/collectedinfo/form')}</a>
{/default}
</div></div></div>
<div class="border-bl"><div class="border-br"><div class="border-bc"></div></div></div>
</div>
On the front-end of the site, this is what is displayed after the form is submitted:
Submission confirmation page
Email template for form results
Upon form submission, we have also specified (in collect.ini.append.php) that eZ Publish send an email. This email is generated from a template named membership_application_form.tpl in this folder:
/extension/ezwebin/design/ezwebin/templates/content/collectedinfomail/
In this example, the existing eZ Publish feedback.tpl template can be used as a model. Our modified template is shown below.
{set-block scope=root variable=subject}{"Collected information from %1"|i18n("design/ezwebin/collectedinfomail/form",,array($collection.object.name|wash))}{/set-block}
{if and(is_set($object.data_map.membership_coordinator_email_address), $object.data_map.membership_coordinator_email_address.has_content)}
{set-block scope=root variable=email_receiver}
{$object.data_map.membership_coordinator_email_address.content}
{/set-block}
{/if}
{* Set this to redirect to another node
{set-block scope=root variable=redirect_to_node_id}2{/set-block}
*}
{"The following information was collected"|i18n("design/ezwebin/collectedinfomail/form")}:
{foreach $collection.attributes as $attribute}
{$attribute.contentclass_attribute_name|wash}:
{attribute_result_gui view=info attribute=$attribute}
{/foreach}
Note the "membership_coordinator_email_address" elements, which specify the recipient email address. In this case, they are referencing the identifier for the “membership_coordinator_email_address” attribute (the contents of which will be specified in the next section when we create the form object) of the Membership Application Form object.
Up until now, we have been configuring the membership application form, but we have not yet created the object! To do so, first click the Content structure tab of the Administration Interface.
In our case, we will place the form directly beneath the top-level node of the Content branch; therefore, we do not have to navigate any further in the Administration Interface. In the Sub items window at the bottom of the page (if it is missing, click the Sub items switch underneath the main menu of tabs), select the new form class from the dropdown list, then click the Create here button.
New Membership Application Form object
In this example, the only fields with content are shown below. Since all other attributes are information collectors, they can be left blank.
Object fields part 1
Object fields part 2
Once you are done filling in the object's contents, click the Send for publishing button.
The form information that is sent by email is also stored in eZ Publish. It can be accessed in templates using collectedinfo fetch functions (see the technical manual for more information about fetch functions). The main way to view this information is in the Collected information interface under the Setup tab of the Administration Interface.
From there you will see an entry for the Membership Application Form object:
List of collected information objects
To see the submissions that have been collected, click the number in the Collections column. This will load a page with the following information:
List of Membership Application Form submissions
You can see the individual form submissions by clicking on the corresponding number in the Collection ID column. This will show an entry similar to the following:
Form submission information
In this article, we discussed the two types of user forms in eZ Publish (for creating content objects and submitting information collectors), focusing on creating an information collecting form.
The example in this article touched upon the eZ Publish template system, information collection system, configuration (INI) file editing and content class creation.
Subsequent articles in this tutorial series will explain how to make use of RSS to syndicate content from other websites and more!
Resources