Wednesday, November 28, 2012

WEF Profiling Explained

Profiling is a frequently misunderstood concept in web experience factory. This blog entry describes profiling by comparing it to java code, something that more developers are familiar with.

Comparing Profiles to Java Code
Many people struggle with the concept of profiling and profile sets, but it can be closely compared to a conditional statement in java. Suppose that we have a button that needs to be displayed if the application is accessed from an android device. Coding this using java would look something like this (depending on the framework):
if (request.getHeader("User-Agent") == "android"){
   button.visible = true;
}

The same can be accomplished with WEF profiling except we don't have any code to work with, only a button builder with inputs. Ideally, we would want to apply the results of profiling to the builder enable input, setting it to true or false which would effectively replicate what the java code above does.

Think of a profile set as a collection of profiles and the selection of a given profile is the result of a conditional statement. That conditional statement is controlled by a selection handler. Let's look at the code above again from this perspective
if (profileset.selectionHandler.result == "android"){
   button.enable = true;
}

The profile set selection handler is the engine that controls which profile is selected. In this particular case, we're using the mobile selection handler which contains logic that looks at the HTTP request user agent header to determine which profile is selected. Moving one step further, the selection handler doesn't really return a value like "android" per se, it chooses a profile.

Suppose we not only want to control the visibility of a button, but we also want to execute a call to a service provider operation when the application is accessed from an android device. In java, we would add some logic
if (profileset.selectionHandler.profile.name == "android"){
   button.enable = true;
   invokeSomeOperation();
}

For the sake of making this explanation clearer, let's also add some code to handle iPhones as well as a handler for the default case
if (profileset.selectionHandler.profile.name == "android"){
   button.enable = true;
   invokeSomeOperation();
}
else if (profileset.selectionHandler.profile.name == "iphone"){
   button.enable = false;
   invokeSomeOperationIPhone();
}
else{
   button.enable = false;
   // do nothing
}

That all seems very obvious if we were using java, but how is it implemented in WEF using profiling?


Here is the detailed profile entry for the button


Similarly, the action list is profiled



and below is the detailed profile entry


Only one profile in any profile set can be active at one time, and profiling is applied when the user session is first initiated. It is not possible to use two different profiles from the same profile set or switch profiles in the same session.





Wednesday, November 7, 2012

WEF and Custom HTML

Working with custom HTML is probably one of the most common patterns I've seen when building an application with web experience factory (WEF). Typically this is a situation where I'm given a really nice HTML stub from a professional web designer and I need to build an application around it.

Don't Fight with WEF
A common mistake I see all the time is a web developer trying to untangle or intercept the code generated by WEF. Don't do it, you're going to lose your mind or create an unmaintainable mess (or both). Here are a few tips that should help:

1 - Turn off the theme
2 - Don't let the data page builder create the UI
3 - Learn how to exploit page automation

Turn off the Theme
There are two ways to accomplish this, adding a theme builder to your model and selecting the individual components, or blanking out the theme file name in the project's override.properties.



The theme is great when using WEF's default user interface, but it just gets in the way of custom HTML.

Dumb Down the Data Page Builder
The data page builder is the heart of page automation in WEF, but sometimes it wants to do too much, and again, gets in the way of custom HTML. We want dumb it down a little by turning off the option to make the UI from data.

In many cases we'll also want to set the page type to view only if we're only displaying data, but this depends on the use case.

Exploit Page Automation
Now that we've turned off some of the noise that we don't need, how do we tell the page automation to place data on our custom HTML? This is easily done by adding our own name attributes to the HTML elements. Whenever page automation finds a value for the name attribute that matches the data specified in the data page variable, it inserts a data value. Take for example the following XML data
<contacts>
   <contact>
      <name>n1</name>
      <phone>p1</phone>
   </contact>
   <contact>
      <name>n2</name>
      <phone>p2</phone>
   </contact>
</contacts>

We can ask page automation to take this custom HTML
<html>
<head>
<title>Default Test Page</title>
</head>
<body>

    <table name="contacts" width="50%">

        <tr align="center">
            <th><span name="nameHeader">Name</span></th>
            <th>Click to update</th>
            <th><span name="phoneHeader">Phone</span></th>
        </tr>

        <tr name="contact" align="center">
            <td><span name="name"></span></td>
            <td><span name="btn"></span></td>
            <td><span name="phone"></span></td>
        </tr>

    </table>

</body>
</html>
to produce a user interface, and this is what we see in the browser when we launch the application







This is how page automation sees the HTML name attributes that we added


You may have noticed that we added sorting capability to the first column, this is standard practice using a data column modifier (DCM) builder. The DCM builder needs to be able to identify the location of the table headers, and since we have custom HTML, we have to do this ourselves by adding a suffix Header to the name attribute in the table header rows.

Also note that the table row identified with the name attribute contact refers to the repeating XML data element contact. Page automation will create a new HTML row for each contact element in our data.

The edit button is there to demonstrate that we can easily add builders that refer to named locations in our HTML, just as if the data page builder had done all the work for us.

More information about manually marking up HTML for page automation can be found here.