Creating an eDocLite Application

Overview

eDocLite is a simple, form-based system that is built into Kuali Enterprise Workflow (KEW). It facilitates rapid development and implementation of simple documents and validation rules using XML. Use it for simple documents with simple route paths. You can integrate it with larger applications using a database layer post-processor component.

eDocLite uses an XSLT style sheet for custom presentation and XML to define form fields. The actual form display is called an EDL. This diagram shows how these objects are related:

Key Ideas:

  • Rapid implementation and development solution for simpler documents

  • Easily re-configured

  • Easily manageable

  • Entirely web-based from design/development and user perspectives

  • No java code required for developments; only XML with optional javascript for client side editing (workflow handles execution)

  • Some validation javascript is automatically generated like regular expression editing and 'required field checking'.

Figure 3.23. EDL Controller Chain

EDL Controller Chain


Components

Field Definitions

You need to define eDocLite fields to capture data that is passed to the server for storage.

Key Information about eDocLite fields:

  • Save eDocLite data fields as key value pairs in two columns of a single database table.

  • Use the xml element name as the key.

  • You do not need to make any database-related changes when building eDocLite web applications.

  • Store documents by document number.

  • Make all field names unique within a document type.

The code example below focuses on the EDL section of the eDocLite form definition. The file Edoclite.xsd found in source under the impl/src/main/resources/schema/ directory describes the xml rules for this section.

Note that the first few lines proceeding <edl name="eDoc.Example1.Form" relate to namespace definitions. These are common across all eDocLites, so this guide does not discuss them.

In this example, any XML markup that has no value shown or that is not explained offers options that are not important at this time.

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
    <edoclite xmlns="ns:workflow/eDocLite " xsi:schemaLocation="ns:workflow/eDocLite  resource:eDocLite ">

    <edl name="eDoc.Example1.Form" title="Example 1">
        <security />
        <createInstructions>** Questions with an asterisk are required.</createInstructions>
        <instructions>** Questions with an asterisk are required.</instructions>
        <validations />
        <attributes />
        <fieldDef name="userName" title="Full Name">
            <display>
                <type>text</type>
                <meta>
                    <name>size</name>
                    <value>40</value>
                </meta>
            </display>
            <validation required="true">
                <message>Please enter your full name</message>
            </validation>
        </fieldDef>
        <fieldDef name="rqstDate" title="Requested Date of Implementation:">
            <display>
                <type>text</type>
            </display>
            <validation required="true">
                <regex>^[0-1]?[0-9](/|-)[0-3]?[0-9](/|-)[1-2][0-9][0-9][0-9]$</regex>
                <message>Enter a valid date in the format mm/dd/yyyy.</message>
            </validation>
        </fieldDef>
        <fieldDef name="requestType" title="Request Type:">
            <display>
                <type>radio</type>
                <values title="New">New</values>
                <values title="Modification">Modification</values>
            </display>
            <validation required="true">
                <message>Please select a request type.</message>
            </validation>
        </fieldDef>
        <fieldDef attributeName="EDL.Campus.Example" name="campus" title="Campus:">
            <display>
                <type>select</type>
                <values title="IUB">IUB</values>
                <values title="IUPUI">IUPUI</values>
            </display>
            <validation required="true">
                <message>Please select a campus.</message>
            </validation>
        </fieldDef>
        <fieldDef name="description" title="Description of Request:">
            <display>
                <type>textarea</type>
                <meta>
                    <name>rows</name>
                    <value>5</value>
                </meta>
                <meta>
                    <name>cols</name>
                    <value>60</value>
                </meta>
                <meta>
                    <name>wrap</name
                    <value>hard</value>
                </meta>
            </display>
            <validation required="false" />
        </fieldDef>
        <fieldDef name="fundedBy" title="My research/sponsored program work is funded by NIH or NSF.">
            <display>
                <type>checkbox</type>
                <values title="My research/sponsored program work is funded by NIH or NSF.">nihnsf</values
            </display>
        </fieldDef>
        <fieldDef name="researchHumans" title="My research/sponsored program work involves human subjects.">
            <display>
                <type>checkbox</type>
                <values title="My research/sponsored program work involves human subjects.">humans</values>
            </display>
        </fieldDef>
    </edl>
    </eDocLite>
</data>

In the EDL XML file, field definition is embodied in the edl element. This element has a name attribute that is used to identify this file as a definition of an EDL form. It often has a title for display purposes.

Examination of this code shows that

  • Individual fields have names, titles, and types. The types closely match html types.

  • You can easily use simple validation attributes and sub-attributes to ensure that a field is entered if required and that an appropriate error message is presented if no value is provided by the web user.

  • Regular expressions enhance the edit criteria without using custom JavaScript. (There are several ways that you can invoke custom JavaScript for a field, but they are not shown in this example.)

  • An important field named campus has syntax that defines the value used to drive the routing destination. (In more complex documents, several fields are involved in making the routing decision.)

XSLT Style Sheet

The next section of the EDL XML file is the XSLT style sheet. It renders the EDL that the browser will present and contains logic to determine how data is rendered to the user.

A major workhorse of the XSLT code is contained in a style sheet library called widgets.xml. In the example below, it's included in the style sheet using an xsl:include directive.

Workflow Java classes have API’s that offer methods that supply valuable information to the XSLT style sheet logic. XML allows you to interrogate the current value of EDL-defined fields, and it provides a variety of built-in functions.

Together, these helpers allow the eDocLite style sheet programmer to focus on rendering fields and titles using library (widget) calls and to perform necessary logic using the constructs built into the XML language(if, choose…when, etc.).

This is the area of eDocLite development that takes the longest and is the most tedious. Much of what the eDocLite style sheet programmer writes focuses on which fields and titles appear, in what order, to which users, and whether the fields are readOnly, editable, or hidden.

Below is the style sheet section of the EDL XML form for our example. It contains embedded comments.

<!-- widgets is simply more xslt that contains common functionality that greatly simplifies html rendering 
It is somewhat complicated but does not require changes or full understanding unless enhancements are required.  -->
<xsl:include href="widgets" />
<xsl:output indent="yes" method="html" omit-xml-declaration="yes" version="4.01" />

<!-- variables in the current version of xslt cannot be changed once set. Below they are set to various values often fed by java classes or to
values contained in workflow xml. Not all of these are used in this form but are shown because often they can be useful
The ones prefixed with my-class are methods that are exposed by workflow to eDocLite .-->
<xsl:variable name="actionable" select="/documentContent/documentState/actionable" />
<xsl:variable name="docHeaderId" select="/documentContent/documentState/docId" />
<xsl:variable name="editable" select="/documentContent/documentState/editable" />
<xsl:variable name="globalReadOnly" select="/documentContent/documentState/editable != 'true'" />
<xsl:variable name="docStatus" select="//documentState/workflowDocumentState/status" />
<xsl:variable name="isAtNodeInitiated" select="my-class:isAtNode($docHeaderId, 'Initiated')" />
<xsl:variable name="isPastInitiated" select="my-class:isNodeInPreviousNodeList('Initiated', $docHeaderId)" />
<xsl:variable name="isUserInitiator" select="my-class:isUserInitiator($docHeaderId)" />
<!-- <xsl:variable name="workflowUser" select="my-class:getWorkflowUser().authenticationUserId().id()" /> This has a unique implementation at IU -->
<xsl:param name="overrideMain" select="'true'" />

<!-- mainForm begins here. Execution of stylesheet begins here. It calls other templates which can call other templates.
Position of templates beyond this point do not matter. -->
<xsl:template name="mainForm">
    <html xmlns="">
        <head>
            <script language="javascript" />
            <xsl:call-template name="htmlHead" />
        </head>
        <body onload="onPageLoad()">
            <xsl:call-template name="errors" />
            <!-- the header is useful because it tells the user whether they are in 'Editing' mode or 'Read Only' mode. -->
            <xsl:call-template name="header" />
            <xsl:call-template name="instructions" />
            <xsl:variable name="formTarget" select="'eDocLite '" />
            <!-- validateOnSubmit is a javascript function (file: edoclite1.js) which supports edoclite forms and can be somewhat complicated 
                 but does not
 require modification unless enhancements are required. -->
            <form action="{$formTarget}" enctype="multipart/form-data" id="edoclite" method="post" onsubmit="return validateOnSubmit(this)">
                <xsl:call-template name="hidden-params" />
                <xsl:call-template name="mainBody" />
                <xsl:call-template name="notes" />
                <br />
                <xsl:call-template name="buttons" />
                <br />
            </form>
            <xsl:call-template name="footer" />
        </body>
    </html>
</xsl:template>

<!-- mainBody template begins here. It calls other templates which can call other templates. Position of templates do not matter. -->
<xsl:template name="mainBody">
    <!-- to debug, or see values of previously created variables, one can use the following format.
         for example, uncomment the following line to see value of $docStatus. It will be rendered at the top of the main body form. -->
    <!-- $docStatus=<xsl:value-of select="$docStatus" /> -->
    <!-- rest of this all is within the form table -->
    <table xmlns="" align="center" border="0" cellpadding="0" cellspacing="0" class="bord-r-t" width="80%">
        <tr>
            <td align="left" border="3" class="thnormal" colspan="1">
<br />
<h3>
My Page
<br />
EDL EDoclite Example
</h3>
<br />
</td>
            <td align="center" border="3" class="thnormal" colspan="2">
<br />
<h2>eDocLite Example 1 Form</h2></td>
        </tr>
        <tr>
            <td class="headercell5" colspan="100%">
<b>User Information</b>
</td>
        </tr>
        <tr>
            <td class="thnormal">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'userName'" />
                    <xsl:with-param name="renderCmd" select="'title'" />
                </xsl:call-template>
                <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'userName'" />
                    <xsl:with-param name="renderCmd" select="'input'" />
                    <xsl:with-param name="readOnly" select="$isPastInitiated" />
                </xsl:call-template>
            </td>
        </tr>
        <tr>
            <td class="headercell5" colspan="100%">
<b>Other Information</b>
</td>
        </tr>
        <tr>
            <td class="thnormal">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'rqstDate'" />
                    <xsl:with-param name="renderCmd" select="'title'" />
                </xsl:call-template>
                <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'rqstDate'" />
                    <xsl:with-param name="renderCmd" select="'input'" />
                    <xsl:with-param name="readOnly" select="$isPastInitiated" />
                </xsl:call-template>
            </td>
        </tr>
        <tr>
            <td class="thnormal">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'campus'" />
                    <xsl:with-param name="renderCmd" select="'title'" />
                </xsl:call-template>
                <font color="#ff0000">*</font>
            </td>
            <td class="datacell">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'campus'" />
                    <xsl:with-param name="renderCmd" select="'input'" />
                    <xsl:with-param name="readOnly" select="$isPastInitiated" />
                </xsl:call-template>
            </td>
        </tr>
        <tr>
            <td class="thnormal">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'description'" />
                    <xsl:with-param name="renderCmd" select="'title'" />
                </xsl:call-template>
            </td>
            <td class="datacell">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'description'" />
                    <xsl:with-param name="renderCmd" select="'input'" />
                    <xsl:with-param name="readOnly" select="$isPastInitiated" />
                </xsl:call-template>
            </td>
        </tr>
        <tr>
            <td class="thnormal" colspan="2">
<b>(Check all that apply)</b>
</td>
        </tr>
        <tr>
            <td class="datacell" colspan="2">
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'fundedBy'" />
                    <xsl:with-param name="renderCmd" select="'input'" />
                    <xsl:with-param name="readOnly" select="$isPastInitiated" />
                </xsl:call-template>
                <br />
                <xsl:call-template name="widget_render">
                    <xsl:with-param name="fieldName" select="'researchHumans'" />
                    <xsl:with-param name="renderCmd" select="'input'" />
                    <xsl:with-param name="readOnly" select="$isPastInitiated" />
                </xsl:call-template>
                <br />
            </td>
        </tr>
        <tr>
            <td class="headercell1" colspan="100%">
<b>Supporting Materials</b></td>
        </tr>
        <tr>
            <td class="thnormal" colspan="100%">Use the Create Note box below to attach supporting materials to your request. Notes may be added with or without attachments. Click the red 'save' button on the right.</td>
        </tr>
    </table>
    <br xmlns="" />
</xsl:template>
<xsl:template name="nbsp">
    <xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
</xsl:template>
</xsl:stylesheet>
</style>

The beginning portion of this style sheet defines some XSL variables that are often useful to drive logic choices. For simplicity, this example uses very little logic.

The isPastInitiated variable drives whether a user-defined EDL field renders readOnly or not.

The mainform often serves to call some common widget templates that add canned functionality. The mainform then calls the mainBody template, which creates the html to render the EDL-defined fields. The mainform then (optional) calls the notes, buttons, and footer templates.

The majority of your programming effort goes into the mainBody, where calls to widget_render generate much of the field-specific title and value information. Various options can be passed into widgets_render to allow client events to be executed. The mainBody is usually one or more html tables and sometimes makes calls to programmer-defined sub-templates. The XSLT stylesheet generates the HTML rendered by the browser.

The main and repeating theme of the example involves calling widget_render with the title of an EDL field, followed by calling widget_render again with the input field. Widgets are a wrapper for XSLT stylesheets that offer the ability to create HTML. Paramters offer different ways to render HTML when making calls to widgets. Note that the variable value $isPastInitiated is passed as a parameter to widgets_render so that the html readOnly attribute is generated when the form is past the initiator’s node.

Lazy importing of EDL Styles

You can configure Rice to lazily import an eDocLite style into the database on demand by setting a custom configuration parameter.

  • Create a custom stylesheet file, e.g. myricestyle.xml containing a style with a unique name, e.g. "xyzAppStyle" and store it in a location that is locally accessible to your application server.

  • Set a configuration parameter named edl.style.<style-name> with the value being a path to the file containing your style. Following the example above, you would name your parameter "edl.style.xyzAppStyle".

The stylesheet file could referenced could contain a full EDL, or be a standalone EDL style. On first use of that named style by an EDL, the file will be parsed and the named style will be imported into the database. The following example contains just an eDocLite XSL stylesheet:

<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
    <edoclite xmlns="ns:workflow/EDocLite" xsi:schemaLocation="ns:workflow/EDocLite resource:EDocLite">
        <style name="xyzAppStyle">
            <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wf="http://xml.apache.org/xalan/java/org.kuali.rice.kew.edoclite.WorkflowFunctions">
                <!-- your custom stylesheet -->
            </xsl:stylesheet>
        </style>
    </edoclite>

</data>

Note that in a default Rice installation (starting in version 1.0.2), the "widgets" style is lazily imported using this mechanism. In common-config-defaults.xml (which is located in the rice-impl jar), the following parameter is defined:

<param name="edl.style.widgets" override="false">classpath:org/kuali/rice/kew/edl/default-widgets.xml</param>

If you wanted to override that file, you could define your own parameter in your Rice XML configuration file using the above example as a template, but removing the override="false" attribute.

Document Type

A document type defines the workflow process for an eDocLite. You can create hierarchies where Child document types inherit attributes of their Parents. At some level, a document type specifies routing information. The document type definition for our first example follows. It contains routing information that describes the route paths possible for a document.

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
    <documentTypes xmlns="ns:workflow/DocumentType" xsi:schemaLocation="ns:workflow/DocumentType resource:DocumentType">
        <documentType>
            <name>eDoc.Example1Doctype</name>
            <parent>eDoc.Example1.ParentDoctype</parent>
            <description>eDoc.Example1 Request DocumentType</description>
            <label>eDoc.Example1 Request DocumentType</label>
            <postProcessorName>org.kuali.rice.kew.edl.EDocLitePostProcessor</postProcessorName>
            <superUserGroupName namespace="KUALI">eDoc.Example1.SuperUsers</superUserGroupName>
            <blanketApprovePolicy>NONE</blanketApprovePolicy>
            <defaultExceptionGroupName namespace="KUALI">eDoc.Example1.defaultExceptions</defaultExceptionGroupName>
            <docHandler>${workflow.url}/EDocLite</docHandler>
            <active>true</active>
            <routingVersion>2</routingVersion>
            <routePaths>
                <routePath>
                    <start name="Initiated" nextNode="eDoc.Example1.Node1" />
                    <requests name="eDoc.Example1.Node1" />
                </routePath>
            </routePaths>
            <routeNodes>
                <start name="Initiated">
                    <activationType>P</activationType>
                    <mandatoryRoute>false</mandatoryRoute>
                    <finalApproval>false</finalApproval>
                </start>
                <requests name="eDoc.Example1.Node1">
                    <activationType>P</activationType>
                    <ruleTemplate>eDoc.Example1.Node1</ruleTemplate>
                    <mandatoryRoute>false</mandatoryRoute>
                    <finalApproval>false</finalApproval>
                </requests>
            </routeNodes>
        </documentType>
    </documentTypes>
</data>

The Parent element refers to a hierarchical order of the document types. Usually, you create one Root document type with limited but common information. Then, under that, you create more specific document types. In our example, there are only two levels.

The Root document type definition for our first example:

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
    <documentTypes xmlns="ns:workflow/DocumentType" xsi:schemaLocation="ns:workflow/DocumentType resource:DocumentType">
        <documentType>
            <name>eDoc.Example1.ParentDoctype</name>
            <description>eDoc.Example1 Parent Doctype</description>
            <label>eDoc.Example1 Parent Document</label>
            <postProcessorName>org.kuali.rice.kew.edl.EDocLitePostProcessor</postProcessorName>
            <superUserGroupName namespace="KUALI">eDoc.Example1.SuperUsers</superUserGroupName>
            <blanketApprovePolicy>NONE</blanketApprovePolicy>
            <docHandler>${workflow.url}/EDocLite</docHandler>
            <active>true</active>
            <routingVersion>2</routingVersion>
            <routePaths />
        </documentType>
    </documentTypes>
</data>

A Child document type can inherit most element values, although you must define certain element values, like postProcessor, for each Child document type.

A brief explanation of elements that are not intuitive is below. You can find additional element explanations by reading the Document Type Guide.

Parent DocType

postProcessorName - Use the default, as shown above, unless special processing is needed.

blanketApprovePolicy – When specified as NONE, this means that a user cannot click a single button that satisfies multiple levels of approval.

dochandler - Use the default, as shown above, so URLs are automatically unique in each environment, based on settings in the Application Constants (i.e., unique in each Test environment and unique again in Production).

active - Set this element to false to disable this feature.

routingVersion - Use the default, as shown above.

Child DocType

name - The name value must exactly match the value in the EDL Association document type element.

parent - The parent value must exactly match the name value of the parent document type.

superUserGroupName - A group of people who have special privileges that can be defined using the management service that’s part of the KIM module.

defaultExceptionGroupName - A group of people who address a document of this type when it goes into Exception routing

routePaths and routePath - The initial elements that summarize the routing path the document will follow. In our example, an initiator fills out an eDocLite form. When the initiator submits that form, where it is routed depends on the value in the Campus field. There is only one destination node in our first example. The submitted form goes to either the IUB person or the IUPUI person, depending on the selection in the Campus field.

In most cases, a workgroup of people is the destination for an EDL form, not a single person. Workgroups are used as destinations because anyone in the workgroup can open the document, edit it, and click an Action button that routes the document to the next node. This prevents delays when someone is out of the office and a document awaits their action.

When the initiator submits the document, KEW adds that document to the Action List of the destination person or workgroup. The destination person or workgroup can then open the document, edit it (if any fields are available for editing), and click an Action button such as Approve, which routes the document onward. In our case, there is no further destination, so when the destination person or workgroup approves the document, the document becomes Final (it is finished). Some real-life examples have ten or more nodes for approvals or other actions. A document may bypass some of those nodes, depending on data placed into the form by previous participants.

routeNodes- Redefines the route path.

activationType

  • P stands for parallel and is almost always used. This value makes more sense when considered from a target node perspective. From that perspective, it means that if a workgroup of people all received the document in their Action List, any one, in any order, can approve it. Once it is approved by anyone in the workgroup, it is routed to the next node, and KEW removes the document from the Action List of all the people in the workgroup. activationType

  • S stands for sequential and is reserved for special cases where rules can specify that two or more people in a workgroup must take Action on a document, in a specific order, before KEW will route the document to the next node.

mandatoryRoute - Use false unless there is a special condition to solve. When this parameter is set to true, the document goes into exception routing if an approve request isn't generated by the ruleTemplate. This means that you are only expecting an approve, and nothing else.

finalApproval - Use false unless there is a special condition to solve. When this parm is set to true, the document goes into exception routing if approves are generated after this route node. This means this must be the last Action, or it will go into exception routing. (Be careful, because if this parameter is set to true and a user clicks a Return to Previous button, then the next action button clicked sends the document into exception handling.)

requests name= "..." - Defines the name of the node

ruleTemplate - A named entity type that helps define which routing rule fires. In our example, the ruleTemplate name is the same as the request name. These field values do NOT need to be the same. They are simply identifiers.

Rule Attributes

The RuleAttribute is a mechanism that can relate directly to an edl field. Most rule attributes are of the xml rule attribute type. This type uses an xpath statement which is used by the workflow engine to match to a rule that fires or does not fire.

In the below example, it can be seen that the edl defined field named 'campus' and its permissible values are defined. Then in the xpathexpression element says; when the value in the edl field named 'campus' matches the rule that contains 'IUB' the rule will fire. Or when the value in the edl field named 'campus' matches the rule that contains 'IUPUI' that rule will fire instead. Rules firing route a document to a person or a workgroup of people.

To make another rule attribute for a different field, clone this one, change all references to the field 'campus' to your different edl field name. Then cut and paste in the values section. Then in the edl definition, the new field must carry the extra syntax 'attributeName='. For example the eld definition for campus looks like this:

<fieldDef name="campus" title="Campus" workflowType="ALL">

Rule Routing

<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="ns:workflow" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="ns:workflow resource:WorkflowData">
    <ruleAttributes xmlns="ns:workflow/RuleAttribute" xsi:schemaLocation="ns:workflow/RuleAttribute resource:RuleAttribute">
        <ruleAttribute>
            <name>EDL.Campus.Example</name>
            <className>org.kuali.rice.kew.rule.xmlrouting.StandardGenericXMLRuleAttribute</className>
            <label>EDL Campus Routing</label>
            <description>EDL School Routing</description>
            <type>RuleXmlAttribute</type>
            <routingConfig>
                <fieldDef name="campus" title="Campus" workflowType="ALL">
                    <display>
                        <type>select</type>
                        <values title="IUB">IUB</values>
                        <values title="IUPUI">IUPUI</values>
                    </display>
                    <validation required="false" />
                    <fieldEvaluation>
                        <xpathexpression>//campus = wf:ruledata('campus')</xpathexpression>
                    </fieldEvaluation>
                </fieldDef>
                <xmlDocumentContent>
                    <campus>%campus%</campus>
                </xmlDocumentContent>
            </routingConfig>
        </ruleAttribute>
    </ruleAttributes>

</data>

Rule attributes can have a different types such a searchable, but this type does not have to do with routing. Instead it relates to additional columns that are displayed in doc search for a particular doc type.

Ingestion Order

Many components can go in at any time, but it is advisable to follow a pattern to minimize the conflicts that can occur. A few pieces are co-dependent.

  1. Basic Components:

  2. Widgets.xml (If changed or not previously in the environment)

  3. Kim Group(s)

  4. Rule Attributes

  5. Rule Template(s)

  6. Parent Doctype (often no routing so data is more generic, but do put routing here if children will use common routing.)

  7. Children Doctype(s) (routing defined here or on Parent)

  8. EDL Form

  9. Rule routing rule (Used if rules are created; explained later- 1 per parent doctype)

  10. Rules (Create or Ingest)

  11. Anything else - Like optional custom Email Stylesheet