Webflows: Quick start tutorial
Webflows Quick start tutorial
NOTE: The following tutorial assumes you have a running Preside application running Preside 10.29 or higher.
1. Define a webflow
Webflows are added to the "library" by convention. Copy and paste the file below into a file at {webroot}/application/workflow/webflows/tutorial.yml
(all yml
files under /workflow/webflows/
directory will automatically be imported from extensions and your application):
version: 1.0.0
webflow:
id: webflowtutorial
singleton: true
steps:
- id: introduction
- id: aform
- id: alternativeending
finish: true
condition:
ref: bool.IsTruthy
args:
value: $aformfield
- id: ending
Next, copy and paste the following into {webroot}/application/i18n/webflow/webflowtutorial.properties
(convention is /i18n/webflow/{webflowid}.properties
):
title=TUTORIAL: Webflow tutorial
step.introduction.label=Introduction
step.introduction.description=A step to allow you to introduce the flow to your users (this is just an example)
step.aform.label=Step with form
step.aform.description=A step with a form in it to show form processing
step.alternativeending.label=An alternative ending
step.alternativeending.description=A final step to show conditional step logic
step.ending.label=Default ending
step.ending.description=The default final page where the flow ends
That's it, the extension will register this webflow with the id webflowtutorial
.
2. Configuring the webflow and steps
Reload your application, log in to the admin and visit the following URL (you may be able to find it via navigation): /{adminpath}/datamanager/object/?id=webflow_configuration
.
From the table of webflows, you should see a TUTORIAL: Webflow tutorial
entry. Click on it and you should see something like this:
i. Configure the webflow itself
Click on the green Edit button on the top right of the screen. You will be presented with a form with the following sections:
- Internal title/description: As it says, this is for internal use only. The title will be prepopulated from i18n.
- Eligibility: Here, editors can enter a message to show for users who do not meet any init conditions defined on the flow. We haven't defined any yet so its not relevant here.
- Timeout: Editors can configure idle timeouts for users within a flow. The default is currently 20 minutes. In addition, they can customize the message that shows to users who have timed out.
Make some changes and save the form. You should be taken back to the screen in figure 1, above.
ii. Configuring steps
Next, click into each step to edit it. What you see may depend on the step you enter:
- Title and copy: You'll see this for all steps. Editors can change the title, a short title (that can appear in a flow progress bar) and introductory text.
- Navigation buttons: Depending on the position of the step in the flow, you may be able edit the text that appears on the Next and Back buttons for flow navigation.
Make some changes and hit save.
3. Output and use the flow
Create a new view file at {webroot}/application/views/webflowtutorial.cfm
with the following content:
<cfoutput>
<div class="container">
#renderWebflow( "webflowtutorial" )#
</div>
</cfoutput>
Reload your application and visit /webflowtutorial/
. What you see will depend on your application layout, of course. But you should see the first step title and intro copy you entered + a next button.
Hit the next button and see how you can journey through the webflow steps until you get to the end.
Remove any query string params from the URL to get back to /webflowtutorial/
, you'll notice that you can go through the flow again from the start. Play with going back after step 2 and clicking the "progress bar" link (might appear as a plain ordered list, depending on your site's pre-existing css).
4. Add a form
Copy and paste the following form file into {webroot}/application/forms/webflow/webflowtutorial/aform.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<form i18nBaseUri="webflow.webflowtutorial:step.aform.">
<tab id="default">
<fieldset id="default" sortorder="10">
<field name="aformfield" control="select" values="true,false" labels="Yes,No" />
</fieldset>
</tab>
</form>
Tip: Notice how this is a convention:
/forms/webflow/{webflowid}/{stepid}.xml
.
Let's also add some i18n to our /i18n/webflow/webflowtutorial.properties
file:
# ...
step.aform.field.aformfield.title=Do you like alternative endings?
Reload the application and run through the flow. You should notice that on step 2, you get a form field. Choosing different options should mean that you finish on one of two alternative end steps.
5. Add a step display viewlet
Being able to supply a convention based form for a step is really useful. But sometimes you will need more power and flexibility. Here, we will add a viewlet into the aform
step.
Copy and paste the following file into {webroot}/application/handlers/webflow/WebflowTutorial.cfc
:
component {
private string function aform( event, rc, prc, args={}, wfInstance ) {
return renderView( view="/webflow/webflowTutorial/aform", args=args );
}
}
Then, paste the following in to a view file at {webroot}/application/views/webflow/webflowtutorial/aform.cfm
:
<cfoutput>
#( args.renderedForm ?: "" )#
<div class="form-field">
<label>
Tutorial input:
<input name="custom_input" placeholder="type 'tutorial' here to continue">
</label>
</div>
</cfoutput>
Reload your application and journey through the flow again. You should notice that you have an extra input in our aform
step. Of course, you can do much more here. Custom javascript, etc. Now let's add some processing to make the type "tutorial" here to continue
actually work.
6. Add a step submission handler
We can add logic to the handling of a form step submission. In this case we'll use it to add some custom validation for our new text input. Edit your {webroot}/application/handlers/webflow/WebflowTutorial.cfc
file to add the aformAction
handler:
component {
private string function aform( event, rc, prc, args={}, wfInstance ) {
return renderView( view="/webflow/webflowTutorial/aform", args=args );
}
private void function aformAction( event, rc, prc, args={}, wfInstance, persistData, validationResult ) {
var customInputValue = ( rc.custom_input ?: "" );
if ( customInputValue != "tutorial" ) {
validationResult.setGeneralMessage( "Please type in 'tutorial' in the box below to continue" );
}
// note: any validation errors set will result in the journey being
// halted and the user being returned to the step they just submitted.
// You can also achieve this by return 'false' from this method
// The persistData argument is a struct combining all the data from the
// form submission (with defaults and preprocessed fields), combined with
// any other data received in the rc scope. You can modify this, and the
// resulting persistData will be persisted to the state on success, or
// passed back to the calling page on validation failure.
}
}
Reload the application and journey through the flow, testing that you can only complete the flow by entering 'tutorial' in the custom input box.
7. Add custom step configuration for editors
Let's make the 'password' editable by administrators. We'll also make the label of the form field from our main form editable. Again, we'll use convention to achieve this. Create a new form xml file at: {webroot}/application/forms/webflow/webflowtutorial/aform.config.xml
(convention is /forms/webflow/{webflowid}/{stepid}.config.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<form i18nBaseUri="webflow.webflowtutorial:step.aform.config.">
<tab id="config" sortorder="20">
<fieldset id="config" sortorder="10">
<field name="custom_input_password" control="textinput" sortorder="10" />
</fieldset>
</tab>
<tab id="forms" sortorder="30">
<fieldset id="formfields" sortorder="40">
<!-- notice the convention here, you can make
form field labels, placeholders, etc.
editorial by supplying config field names
with the convention below
-->
<field name="form.field.aformfield.label" control="textinput" sortorder="10" />
</fieldset>
</tab>
</form>
Note: this form will be merged with the Preside's step configuration form
Add some i18n to /i18n/webflow/webflowtutorial.properties
:
# ...
step.aform.config.tab.config.title=Configuration
step.aform.config.tab.config.iconclass=fa-cogs grey
step.aform.config.tab.forms.title=Form fields
step.aform.config.tab.forms.iconclass=fa-check-square orange
step.aform.config.field.custom_input_password.title=Step password
step.aform.config.field.custom_input_password.placeholder=e.g. 'tutorial' (default)
step.aform.config.field.form.field.aformfield.label.title=Alternative endings label
step.aform.config.field.form.field.aformfield.label.placeholder=e.g. Do you like alternative endings?
Reload the application and edit the step through the admin interface. You should see something like:
Put in custom configuration for both new config options and test the flow. You'll notice that the form field label has changed, but the actual 'password' for getting past the step has not.
i. Add code to handle custom config
Edit the view at {webroot}/application/views/webflow/webflowtutorial/aform.cfm
:
<cfset pw = args.password ?: "tutorial" />
<cfset frm = args.renderedForm ?: "" />
<cfoutput>
#frm#
<div class="form-field">
<label>
Tutorial input:
<input name="custom_input" placeholder="type '#pw#' here to continue">
</label>
</div>
</cfoutput>
Edit the handler at {webroot}/application/handlers/webflow/WebflowTutorial.cfc
:
component {
private string function aform( event, rc, prc, args={}, wfInstance ) {
args.password = args.stepConfig.custom_input_password ?: "";
if ( !Len( Trim( args.password ) ) ) {
args.password = "tutorial";
}
return renderView( view="/webflow/webflowTutorial/aform", args=args );
}
private void function aformAction( event, rc, prc, args={}, wfInstance, validationResult, stepConfig ) {
var customInputValue = ( rc.custom_input ?: "" );
var password = stepConfig.custom_input_password ?: "";
if ( !Len( Trim( password ) ) ) {
password = "tutorial";
}
if ( customInputValue != password ) {
validationResult.setGeneralMessage( "Please type in '#password#' in the box below to continue" );
}
}
}
8. Perform actions before and after steps
The flow we have defined is pretty useless. You can go from start to finish, but nothing actually happens. We will edit our webflow yml file to add some actions. In {webroot}/application/workflow/webflows/tutorial.yml
:
version: 1.0.0
webflow:
id: webflowtutorial
singleton: true
steps:
- id: introduction
# add a post action that only fires when 'password' matches
- id: aform
postactions:
- direction: forward # this is default, and not required, options are 'forward', 'back' and 'both'
handler:
event: webflow.webflowtutorial.postFormAction
condition:
ref: string.IsEqual
args:
value: $custom_input
pattern: $webflow.step.aform.config.custom_input_password
# add a pre action, that will fire before transitioning to this final step
- id: alternativeending
finish: true
condition:
ref: bool.IsTruthy
args:
value: $aformfield
preactions:
- direction: forward # this is default, and not required, options are 'forward', 'back' and 'both'
handler:
event: webflow.webflowtutorial.alternativeEndingAction
- id: ending
Now, edit your WebflowTutorial.cfc
handler, adding the actions we just defined:
component {
// ...
private void function postFormAction( event, rc, prc, wfInstance ) {
log file="webflowtutorial" text="I just performed postFormAction";
}
private void function alternativeEndingAction( event, rc, prc, wfInstance ) {
log file="webflowtutorial" text="I just performed alternativeEndingAction";
}
// ...
}
Reload your application and proceed through the flow. Check your logs to confirm the actions were performed.
9. Conclusion
That's it! You have successfully completed the Webflows quick start tutorial. Hopefully you now have a good grounding in understanding of what they are and how to develop and maintain them.