Changes between Initial Version and Version 1 of DeveloperGuidelines/s3workflow


Ignore:
Timestamp:
09/21/13 13:28:06 (12 years ago)
Author:
hardik juneja
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DeveloperGuidelines/s3workflow

    v1 v1  
     1= S3Workflow Tutorial =
     2[[TOC]]
     3
     4This tutorial is on S3Workflow and will briefly explain how workflows works and created in Sahana Eden.
     5
     6== Starting a workflow ==
     7
     8Starting a workflow in Sahana Eden is very easy.[[br]]
     9To start a workflow just append {{{?wf_id=workflowname}}} where workflowname will be name of the workflow.[[br]]
     10Each workflow has a unique name.[[br]]
     11When you start a workflow a special uid get appended to the URL this uid is used to identify the current workflow.
     12
     13Eg -
     14
     15{{{
     16eden/req/req?wf_id=reqmanagement:a123b-asd23
     17}}}
     18
     19
     20here ‘a123b-asdc23’ is a special uid that identify current workflow.
     21
     22'''Note - ''' When we start workflow it enters the workflow hook in s3rest.py and then everything is handed over to S3Workflow class and then the request get processed normally.
     23
     24
     25== Defining Workflow ==
     26
     27All the workflows are defined in -
     28
     29{{{
     30private/templates/current_temp/workflow.py
     31}}}
     32
     33(where current_temp is the current template.)[[br]]
     34
     35This file contains all the workflow under a class
     36S3WorkflowConfig. [[br]]
     37
     38An small workflow example defnation can be-
     39
     40{{{
     41N = S3Workflow
     42Exit = S3WorkflowExitNode
     43
     44def reqmanagement(self):
     45    return N(“first node”).handle(next_status = “create request”
     46                                  controller = “req”,
     47                                  function = “req”,
     48                                  args = “create”) & \
     49           N(“first node”).handle(next_status = “add items to req 1”
     50                                  controller = "req",
     51                                  function = "req",
     52                                  args = [1,"req_items"],) & \
     53           N(“first node”).handle(next_status = “view reqs”
     54                                  controller = "req",
     55                                  function = "req",
     56                                  )
     57
     58}}}
     59
     60This will create a basic three steps workflow with name reqmanagement and having three steps as follows -
     61
     62 * Create request
     63 * Add item to a particular req
     64 * view requests
     65
     66Next section will try to explain how to make complex workflows with more configuration options.
     67
     68== Options to Configure Workflows ==
     69
     70Each node is defined using a S3WorkflowNode class.[[br]]
     71We provide different option to configure each node. [[br]]
     72for making things simple let us take [[br]]
     73
     74{{{
     75N = S3WorkflowNode
     76}}}
     77
     78=== Defining nodes ===
     79
     80{{{
     81N(“first node”)
     82}}}
     83
     84This defines a node with status “first node”
     85
     86{{{
     87N(“first node”).handle(next_status = “second node”)
     88}}}
     89
     90handle is used to add configuration options to each node.[[br]]
     91above code snippet defines a node with status “first node”[[br]]
     92and state that one possible next status that can be achived will be “first node”.[[br]]
     93
     94But Now the question is how to achieve this next status? [[br]]
     95
     96For that we can define actions in handle.[[br]]
     97
     98{{{
     99N(“first node”).handle(next_status = “create request”,
     100     controller = “req”,
     101     function = “req”,
     102     args = “create”)
     103}}}
     104
     105This code snippet defines a node with status “first node” and whose next status is “second node” [[br]]
     106which can be achieved by clicking on eden/req/req/create action.
     107
     108These actions are defined the same way we define our a url using URL() function.
     109
     110'''All arguments that handle accepts are -'''
     111
     112 * Controller - used to define controller.
     113 * Function - used to define function.
     114 * args - used to define args.
     115 * next_status - used to define next status.
     116 * http - used to define the http for the action. eg. get / post
     117 * action_text - text to display  on the action button (Default next_status)
     118
     119'''All arguments that S3WorkflowNode class accepts are- '''
     120
     121 * status - current status of the node.
     122 * postp - used to define postp for the node.
     123 * prep - used to define prep for the node.
     124 * display_text - used to define some information text in the middle of the node.
     125
     126You can define multiple handle to each node.
     127
     128=== Connecting Nodes ===
     129
     130Now let us point above node to a new node. [[br]]
     131In the above example while defining first node we defined next_status as “create request”. [[br]]
     132Now we will create a node with status “create node” which will create request for us.
     133And then we will connect them.
     134
     135{{{
     136N(“first node”).handle(next_status = “create request”,
     137     controller = “req”,
     138     function = “req”,
     139     args = “create”) & \
     140N(“create request”).handle(next_status = “add items”,
     141     controller = “req”,
     142     function = “req”,
     143     args = [1, “req_item”])
     144}}}
     145
     146when we will start this workflow, the status will be "first node" [[br]]
     147So to achieve “create request” node  from “first node” user will have to click on “req/req/create” [[br]]
     148and then to achieve “add items” from “create request” node user will have to click on “req/req/1/req_items” and so on.
     149
     150(Action button to navigate from one node to another get generated on the page using actions defined in handle.)
     151
     152
     153=== Branching ===
     154
     155In above example we connected nodes together.[[br]]
     156Now let’s see how to create branches or choice nodes.[[br]]
     157
     158This can be achieved by using multiple handles for each node.
     159
     160{{{
     161
     162N(“create req”).handle(next_status = “add item”,
     163                       controller = “req”,
     164                       function = “req”,
     165                        args = [1, “req_item”]) \
     166               .handle(next_status = “manage commitment”,
     167                       controller = “req”,
     168                       function = “req”,
     169                       args = [1, “commit”] )
     170
     171}}}
     172
     173
     174
     175The above code snippet say when at “create req” user can click on “req/req/1/req_items” to change the status to “add item” [[br]]
     176'''OR''' user can click on “req/req/1/commit” to change the workflow status to “manage commitments” [[br]]
     177
     178=== Receiving branched Nodes ===
     179
     180Now lets receive these branched nodes.
     181
     182To merge the branches and point them to one node do this.
     183
     184{{{
     185N(“create req”).handle(next_status = “add item”,
     186                       controller = “req”,
     187                       function = “req”,
     188                       args = [1, “req_item”]) \
     189               .handle(next_status = “manage commitment”,
     190                       controller = “req”,
     191                       function = “req”,
     192                       args = [1, “commit”] ) & \
     193( N(“add items”).handle(next_status = “view req ”)  | 
     194  N(“manage commitments”).handle(next_status = “view req”) )
     195}}}
     196
     197Here “|” is the “or” operator and “&” is “and operator”
     198
     199=== Loop node ===
     200
     201We can make loop nodes which will keep on looping until special actions is pressed.
     202
     203Eg-
     204
     205{{{
     206N(“add items”).handle(next_status = “add items”,
     207                      controller = “req”,
     208                      function = “req”,
     209                      args = [1,“req_items”]) \
     210              .handle(next_node = “view req”,
     211                      controller = “req”,
     212                      function = “req”)
     213
     214}}}
     215
     216=== Adding Prep and Postp to Node ===
     217
     218Just like we define Prep and  Postp for controller we can define one for each node too.
     219
     220{{{
     221def postp(r, output):
     222    …
     223    …
     224    return output
     225}}}
     226
     227now add this postp to node.
     228
     229{{{
     230N(“create request”,   postp = postp).handle(next_status = “view req”,
     231                                            controller = “req”,
     232                                            function = “req”)
     233}}}
     234
     235== Customising Workflow header ==
     236
     237Workflow Header is used to inject special buttons and progress bar during the workflow.
     238Developers have full permission to customise these.
     239Customising the workflow header can be done by adding wheader in controllers, like we add rheader.
     240So there can be different wheader for different nodes
     241
     242We have Default wheader defined in modules/s3/s3workflow.py
     243
     244=== Limitations ===
     245
     246 * When we specify action like org/index they redirect to URL(f = organization) and don’t catch the workflow id. so we have to be careful with this till this issue is not solved
     247
     248