The AgileSites API uses a modern style of Java coding, with fluent interfaces, static imports and value classes without getter and setter.
In this section we introduce the peculiar Java idioms used in the API.
In every class you should add this line:
import static wcs.Api.*
This static import will include some common static methods that can be used as functions and will make easier to use the API.
Even if there is no such a thing like a proper function in Java, I will call in this seciont the imported static methods "functions".
ifn
and nn
In java you have to check often if something is null or not. The ifn
function does exactly this. For example, the following will check if l
is null and if it is not the it will converted to 0.
String cid = ifn(e.getId("Related"), 0l).toString()
Note that the whole stuff is a bit tricky with types. Both the parameters of ifn
are objects, so the 0l
will be autoboxed to a Long
. The result will be converted to a string avoiding the check for null using the toString
method always available. If you need a type different than String you will have to add a cast in front of ifn
For the specific case (very frequent) of avoiding a null string, converting it in a empty (but not null) string there is the nn
function. For example:
html.replace("somewhere", nn(e.getString("Title")))
In this way you can prevent a null pointer converting the eventual null value returned in an empty string.
id
The function:
id("Page", 123456l)
returns an instance of classe wcs.api.Id. This is simpler that invoking new Id("Page", 123456l). There are a number of API calls that expect an instance of class Id
, most notably SitePlan's.
Please note that the class Id
is a value class whose fields are public, so you access the 2 fields c
and cid
as id.c
and id.cid
(cid is a Long, so you need to verify it is not null, compare with equals and convert to String with toString() when needed).
arg
There are numerous cases when a sequence of pairs key/value must be provided. For example, when invoking a CSElement specifying c
and cid
.
Using the function arg
you can write the call like this:
e.call("Summary", arg("c", id.c), arg("cid", id.cid.toString()))
The function arg
actually creates an instance of class Arg
that is a value class with 2 public fields: k
and v
. The call is declared as having a variable number of arguments of type arg (declaration: Arg...args
)
range
A common code pattern, used for example to iterate all the occurrences of a Fatwire List (accessibile in the enviroment) is:
for(int i: e.getRange("List")) {
String x = e.getString("List", i, "value"));
// use x
}
Here you can note the range that is an iterator that produces a sequence of integers. Since multiple attributes and sequences are accessed by index, it is pretty useful (and easier to use than a classical for
loop with numeric integers).
tmp()
The tmp()
function generates a variable name that is always different so it is unique.
It is useful when you need to store a value generated by a tag in a temporary Fatwire variable and you don't want to risk conflicts with variable names. Note the generated names starts with "_" so just avoid it in your variable names to avoid conflict.
See the Asset Tag paragraph in this section for an example of a common use.
model()
The Picker
(see later) can take an instance of an interface Content
to get content from it. A content is basically a map of string to string.
Both the Env
and the Asset
are Content
but you can also create an instance of the class Model
on the fly. The api includes the static function model
that lets you to create a content of the fly.
model( arg("Title", "I am the title"), arg("Text", "<p>The text</p>"))
AgileSites has his own logging wrapper that can send logs to a visual log viewer, described here
To use it, you must use the wcs.core.Log
class, that can send logs to a log viewer, in addition to standard logging.
The code to use logs is very similar to stardard practices. In your application code, for the class X
add the following code at the beginning of your class:
private static final wcs.core.Log log = wcs.core.Log.getLog(X.class);
Then you can use the following logging methods:
log.error
log.warn
log.info
log.debug
log.trace
Note that all the logging methods are actually using a format string and a variable number of arguments, so you can use is as the StringFormat.printf
. For example:
log.debug("c=%s cid=%d", id.c, id.cid)
The complete Fatwire API described in tag documentation for JSP is available from Java code within AgileSites. Every method will receive an Env
object that is a wrapper around an ICS
object, and the current ics
is available as the field e.ics
of the current Env
.
Using ICS
is possible to use both the Asset API and all the tag libraries. While the Asset API is usable exactly as described in the developer manual (being a Java API) the numerous tag libraries are not, so AgileSites provides a wrapper.
Currently the tag libraries are available either in JSP or in XML in form like this:
Sites JSP:
<asset:load name="a" type="Page" objectid="12345"/>
Sites XML:
<asset.load name="a" type="Page" objectid="12345"/>
Tags in fatwire are divided in libraries. For each tag the documentation lists all the available attributes with her meaning.
All the tag are available in AgileSites from java importing the package wcs.core.tag.*
.
For each library library:
there is a corresponding class LibraryTag
(for example, for asset:
there is AssetTag
, for assetset:
there is AssetsetTag
and so on. Note that only the first letter is capitalized: it is not AssetSetTag
.
For each library, tags are accessible as static methods. So the tag asset:load
is accessible as AssetTag.load()
, the tag assetset:getmultiplevalues
as AssetsetTag.getmultiplevalues()
and so on.
You can then pass attributes to the tag invoking a sequence of chained methods, whose name is the attribute name. The sequence must end with the 'run' method that needs the current ICS
instance to run.
For example the equivalent of
<asset:load name="a" type="Page" objectid="123456"/>
is (assuming that is Env e
):
AssetTag.load().name("a"").type("Page").objectid("123456").run(e.ics);
Note that arguments are always string, so for example a Long as in id.cid
must be passed as id.cid.toString()
.
Each tag provides a method for each attribute defined in the tld. However it is also possible to pass arbitrary attribute values (accepted by some tags like calls) with set(key,value)
.
So this is equivalent, except you define the attribute with a string instead of calling a method.
AssetTag.load().name("a"").set("type", "Page").set("objectid", "123456").run(e.ics);
A very common occurrence with tags is returning a value storing it in a variable. You need to read the variable to use the value.
Here is an example of the common pattern you would use, using for example asset:get
and
String tmp = Common.tmp();
AssetTag.get().name("a").field("id").output(tmp).run(e.ics);
return e.getString(tmp);
Because this is so common there is the following shortcut:
return AssetTag.get().name("a").field("id").eval("output",e.ics)
This shortcut works exactly as the previous example: a temporary variable will be generated and stored as the value of the output
attribute in the previous example. Then the tag will be executed, the value of the variable read and returned.