Share Flow Technical Info
A technical overview and how to add new panel types
#Important: this is currently a work in progress!
Overview
- The Share Flow collects information for a user submitted blog post in a step by step process (ie, a 'wizard'). See the Overview page for more intro and screenshots.
- The share flow system can be configured for multiple moments (ie, Share You Why, My Mihi, Stories of Te Reo etc). It is designed to be flexible and handle user flows that might be required in the future.
- The user works through each step filling out each form, then clicking "Next" to move to the next step.
- Each single step can show a 'Content Panel' (usually containing instructions) and/or a 'Form Panel' (using containing fields to enter information).
- On mobile, only one panel Content or Form panel is shown at once. An extra navigation bar is shown which allows the user to switch between Form and Content panels.
- A progress panel is always shown which shows the step numbers and indicates which step the user is currently on.
- The share flow is based on an underlying Nationbuilder Feedback page (this was changed from a Signup page, Nov '22). The blog post is created using the API, and then the Feedback page form is submitted. Using the Feedback page gives additional functionality, such as: notifying admins when a submission happens; capturing user information with custom fields; emailing the user after submission; tagging the user; Nationbuilder automation; and so on.
Modules
List of the main modules
- _z_page_share_layout.html - the main parent module. Hosts all other modules and contains the logic to show the various content panels and form panels at the correct steps for that flow.
- _z_module_share_admin_setup.html - the share flow can be configured for different moments by setting page tags. All configuration and variables are set in this module. If required variables aren't all set, a admin popup appears with instructions. See the Setup page for more information on configuring the Share Flow for a new moment.
- _z_module_share_controller.js - this script manages the panels and data moving through the steps in the wizard. It automatically loads the Content Panels and Form Panels active on the page, and connects to the Share Form Modules
- _z_module_share.scss - top level styling of the desktop panels (using grid) and mobile (using flexbox)
- _z_module_share_progress.html - module for the progress panel which lists the steps in the flow and highlights which step in the flow the user is on.
- _z_module_share_progress_step.html - renders a single progress step and which step the user is currently on.
- _z_module_share_progress.scss - stying of the progress steps
- _z_module_share_content.html - shared module to show panel content, either hard coded or pulled from a subpage. This is currently used for all the content panels.
- _z_module_share_form_XXXX.html - there is a module for each form in a step. These modules manage their own form data. See below for more detail on these modules.
- _z_module_share_preview_helper.js - most modules show a preview of the current state of post as it is being completed. This module renders the preview.
- _z_module_share_preview_helper.scss - styling for the preview
- _z_module_share_submit.html - contains the code to finalise the blog post and send it via the API, and then submit the Feedback form.
Blog Post Data Object
The Share Flow process builds a blog post JSON object that is submitted to Nationbuilder using the API. The blog post object structure is defined in the Nationbuilder API documentation:
https://nationbuilder.com/blog_posts_api
This is an example of the blog post JSON object from the NB documentation.
{
"blog_post": {
"slug": "perspective_misalignments",
"status": "published",
"author_id": 5,
"site_slug": "foobar",
"name": "Perspective Misalignments",
"headline": "Perspective Misalignments",
"title": "Perspective Misalignments - Foobar Softwares",
"excerpt": null,
"id": 11,
"content_before_flip": "<p>Some people just don't see eye to eye</p>",
"content_after_flip": "<p>Lorem ipsum dolor sit amet</p>",
"external_id": nil,
"tags": ["funny"],
"published_at": "2013-04-25T10:47:06-07:00"
}
}
As we do not have control over the allowed fields in a blog post object then additional data is added to the post using blog post tags, usually in a prefix:value format. See the Data and Testing page for more information on these tags.
Panels - Content and Form
The core of the system is showing the relevant panels at each step.
The system scans the page on load and will automatically show or hide the relevant panels. Not code changes are needed, just follow these rules:
- Each step in the flow can show a 'Content Panel' and/or a 'Form Panel'. Usually both panels are shown but there are some steps where a single panel is shown full screen.
- Content panels appear on the left and contain information/content about the step.
- Content panels must have the class**
share-content-panel** - Form panels appear on the right and usually contain a form for the user to add information.
- Form panels must have the class
share-form-panel - Both Content and Form panels must have a data attribute
data-step-no="X"which determines which step number the panel will show. - Some panels show on more than one step, in which case a comma separated list of step numbers can be used, for example:
data-step-no="1,2,3" - As mentioned the panels are automatically discovered on page load, but the developer needs to make sure that the correct panels are being shown at each step, otherwise strange behaviour will happen!
Example of simple Content Panel that will show on steps 2 and 3:
<div data-step-no="2,3" class="share-content-panel">
Hello, I am a content panel
</div>
Share Form Modules
- A Share Form Module displays some kind of form to collect the information for that step.
- Share Form Modules currently must sit inside a Form Panel.
- Share Form Modules must have the class
module-share-form - When the user has finished filling out the form and moves to the next step in the flow, the Share Form Modules adds its data to the blog post data object.
- Each Share Form Module is designed to be an independent "plugins" that manages collecting and adding the data in that step.
- Share Form Modules implement a javascript helper object that provides an interface to connect to the share controller.
- If this interface exists the controller can automatically find and manage the share form module.
- See the section below on how to implement this interface.
Share Form Module List
Each step in the share flow is handled by a specific share form module. The current modules are:
- module-share-form-upload (_z_module_share_form_upload.html) - handles uploading photos and video
- module-share-form-write (_z_module_share_form_write.html) - collects written content
- module-share-form-stories-of-te-reo (_z_module_share_form_stories_of_te_reo.html) - Moment specific form that collects extra information about a Stories of Te Reo post (region, decade, moment, categories).
- module-share-form-kohanga (_z_module_share_form_kohanga.html) - Moment specific form that collects info about Kohanga posts.
- module-share-form-tag-group (_z_module_share_form_tag_group.html) - tagging groups into post
- module-share-form-signup-info (_z_module_share_form_signup_info.html) - Collects additional info about user such as language level and iwi (aka About You step above). This module has a few special differences, described below.
- module-share-form-preview (_z_module_share_form_preview.html) - Display only module that shows a preview of the post.
Share Module Interface
Why this module interface?
- The core idea is that each module manages its own data. This keeps all the relevant code in one place and means the parent/management module doesn't need to worry about the details of managing the data.
- The other idea is that a parent 'wizard' module can easily find and load the modules and that modules can easily be swapped in and out in future signup flows that will require slightly different steps.
- Each Share Form Module connects to the controller by implementing one or more of the following functions:
-
- load(data) - called when the form is shown so it can update itself if necessary
-
- validate() - called when the next button is clicked - the form validates itself and returns true or false
-
- save(data) -> called after validation - the form adds its data to the blog post object.
- See "_z_module_share_controller.js" for detailed info on how it connects to Share Form Modules.
Module Interface Functions
Signup Module Structure
Each step in the sign up flow is handled by a specific module. The current modules are:
- module-share-form-upload (_z_module_share_form_upload.html) - handles uploading photos and video
- module-share-form-write (_z_module_share_form_write.html) - collects written content
- module-share-form-stories-of-te-reo (_z_module_share_form_stories_of_te_reo.html) - Moment specific form that collects extra information about a Stories of Te Reo post (region, decade, moment, categories).
- module-share-form-kohanga (_z_module_share_form_kohanga.html) - Moment specific form that collects info about Kohanga posts.
- module-share-form-tag-group (_z_module_share_form_tag_group.html) - tagging groups into post
- module-share-form-signup-info (_z_module_share_form_signup_info.html) - Collects additional info about user such as language level and iwi (aka About You step above). This module has a few special differences, described below.
- module-share-form-preview (_z_module_share_form_preview.html) - Display only module that shows a preview of the post.
var module_share_form_example = function(config) {
// returns an object with the interface functions...
return {
load: function(data) { /* TODO */ },
validate: function() { return true; /* TODO */},
save: function(data) { return data; /* TODO */ }
}
}
Slightly more advanced notes
(This is not an issue right now, so you can ignore this bit if you are not interested)
The above code will work, but to future proof it, the current modules do one more step. The problem with the above code is that it will not work if there ever is more than one of the same kind of module needed in the share flow.
The extra code change is:
...
var module_share_form_example = function(config) {
config = config || {}; // config optional
const module = config.module || $('.module-share-form-example');
return { ...etc \
When running the init function, the parent passes the jquery element in as a module config parameter. Then the code can use this module variable to target the exact module on the page.
Automatically loading modules
A parent page can automatically load modules with the following steps:
- Find all the share modules loaded into the page by finding all elements with the class:
$(".module-share-form").each(..) - For each $module..
- Use the data-module-init attribute to get the init function name:
const module_init_function_name = $module.data("module-init"); - Get the function from the globals window object:
const module_init_function = window[module_init_function_name] - Call the init function to create the module functions (passing in the $module as config) :
const module_helper = module_init_function({ module: $module}); - It's then possible to call the module interface functions, ie:
module_helper.validate()
TLDR
There is a working test code that automatically loads modules in _z_z_phase_4_test_api.html - https://www.reomaori.co.nz/z_test_phase_4_api_calls?preview=true