Chapter 4. Core Pustefix tag library

Table of Contents

4.1. Defining the structure of a document
4.1.1. Structure of a Type 1 document
4.1.2. Structure of a Type 2 document
4.2. Creating links to internal and external pages
4.2.1. pfx:button
4.2.2. pfx:url
4.2.3. pfx:elink
4.3. Including text and images
4.3.1. Include parts (<pfx:include>)
4.3.2. Generated include requests (<pfx:maincontent>)
4.3.3. Displaying images (<pfx:image>)
4.4. Handling HTML forms
4.4.1. Form creation
4.4.2. Submitting forms
4.4.3. Arguments, comands and anchors
4.4.4. Form elements
4.4.5. Handling error conditions
4.4.6. Avoiding duplicate form submission
4.5. Miscellaneous utility tags
4.5.1. Checking page status
4.5.2. Displaying content based on the language
4.5.3. Displaying content based on the theme
4.5.4. Using the Pustefix console

Pustefix includes a small library of tags defined as XSLT templates which implement low level functionality common to all Pustefix applications. These templates are mostly concerned with creating links to Pustefix pages or external URLs, sending data via HTML forms (including the necessary error handling) and including XML ressources (Include Parts).

All core tags reside in their own namespace. The prefix usually used is pfx, and the namespace is http://www.schlund.de/pustefix/core. You are not supposed to enter your own private project specific tags into this namespace.

The following table lists these tags together with a very short explanation of what they do. Refer to the relevant subsections below to find a detailed explanation on their relevant attributes, subnodes and how to use them.

Table 4.1. The Core Pustefix XSLT Tags
Tag name Short information
pfx:document The top-most container for all Pustefix pages, see Section 4.1, “Defining the structure of a document”
pfx:frameset, pfx:frame Used to define pages with framesets and frames, see Section 4.1, “Defining the structure of a document”
pfx:button This tag creates simple links to internal Pustefix pages (possibly submitting parameters for requests), see Section 4.2.1, “pfx:button”
pfx:url Used to create only the content of the href attribute of a link to an internal page, see Section 4.2.2, “pfx:url”
pfx:elink This tag creates links to external URLs where care must be taken to strip the session ID from the referer header to not leak sensitive information to the outside world, see Section 4.2.3, “pfx:elink”
pfx:include This tag references a file via its href attribute, and includes a named snippet of xml content contained in this file via the part attribute, see Section 4.3.1, “Include parts (<pfx:include>)”
pfx:maincontent This tag is used to include "computed" include parts, see Section 4.3.2, “Generated include requests (<pfx:maincontent>)”
pfx:image This tag references images to be included in the final page (via img-tags), see Section 4.3.3, “Displaying images (<pfx:image>)”
pfx:forminput This tag creates a HTML form, see Section 4.4.1, “Form creation”
pfx:xinp Used to create HTML form elements, see Section 4.4.4, “Form elements”
pfx:checkfield This tag supplies content depending on the error state of a special form field, see the section called “Errors attached to a field”
pfx:checkerror Used to check for the presence of any error condition, see the section called “Errors attached to a field”
pfx:checkmessage Used to check for the presence of any page message, see the section called “Checking for pagemessages”
pfx:checkactive, pfx:checknotactive These tags check for visibility (or not) of pages or for the activity (or not) of handlers, see Section 4.5.1, “Checking page status”
pfx:themeselect, pfx:langselect Used to select content depending on a matching theme or currently selected language, see Section 4.5.3, “Displaying content based on the theme” and Section 4.5.2, “Displaying content based on the language”
pfx:editconsole, pfx:webserviceconsole create panels of shortcut links useful during development, see Section 4.5.4, “Using the Pustefix console”

4.1. Defining the structure of a document

This section describes the format for those documents serving as the structure defining xml source of the finally transformed documents. These can be found in the xml subdirectory of your project.

The explanation keeps an eye on the expected usage patterns of these documents.

There are basically two kinds of "pages" you deliver with Pustefix.

  • Pages that have no frames and may deliver html or any other text based format.

  • Pages that contain an arbitrary amount of frames and framesets. Those usually deliver html.

4.1.1. Structure of a Type 1 document

For a html delivering page without frames:

<pfx:document xmlns:pfx="http://www.schlund.de/pustefix/core">
  <html>
    <!--
      Any content valid for an html document
    -->
  </html>
</pfx:document>

If you don't want to deliver html, just omit the <html> tag. The following could be used to implement a CSS stylesheet.

<pfx:document>.foo { color: #ffff00; font-family: Helvetica; }</pfx:document>

The rule of thumb is: Whatever you put between <pfx:document> is up to you and will be delivered just as you write it there. Just remember that the <html> is not automatically inserted for you, you have to write it yourself.

4.1.2. Structure of a Type 2 document

There are only subtle differences. A document is a Type 2 doc by definition whenever there is a <pfx:frameset> and possibly a <head> node as the only direct children of <pfx:document>.

<pfx:document xmlns:pfx="http://www.schlund.de/pustefix/core">
  <head>
    <!--
      Again, put anything you want to appear in the head of the _top frame! This means
      page title, script stuff or stylesheets.
    -->
  </head>
  <pfx:frameset rows="20,*">
    <pfx:frame name="navi">
      <html>
        <head>...</head>
        <body>
          <!-- Any HTML content -->
        </body>
      </html>
    </pfx:frame>
    <pfx:frame name="main">
      <html>
        <body>
          <!-- Any HTML content -->
        </body>
      </html>
    </pfx:frame>
  </pfx:frameset>
</pfx:document>

As you can see there is NO <html> tag just below <pfx:document>. This is the one important difference between Type 1) and Type 2). As a rule you could say that you only have to insert the <html> yourself wherever the "real" content is. In a Type 1) doc this is the whole content of the <pfx:document> tag, so we need to set it there. But for a Type 2) doc, the "real" content is the content of the <pfx:frame> tags, so you need to set it there.

4.2. Creating links to internal and external pages

Pustefix provides tags that allow you create links to internal and external pages.

4.2.1. pfx:button

The <pfx:button> tag is responsible for generating links to other pages inside the pustefix environment. In fact, it not always creates a link, but depending on the fact if the target page is accessible ("invisible") or not, or if the target page is the same as the current page ("active", aka "the target page is already active") it can display completely different content, and only when the target page is accessible and is different from the current page, a <a href="...">...</a> is put around it.

The template takes care of constructing the correct url with session information embedded and builds up valid, url encoded query strings.

<pfx:button page="APage" pageflow="AFlow" jumptopage="APage" jumptopageflow="AFlow" forcestop="true|false|step" startwithflow="true|false">
  <!--
    Control the submit commands
  -->
  <pfx:command page="APage" name="SUBWRP">prefix</pfx:command>
  <pfx:argument name="AName">AValue</pfx:argument>
  <pfx:anchor frame="AFrame">AnAnchor</pfx:anchor>

  <!--
    These three optional child nodes can be used to display different
    content depending on the situation:
  -->
  <pfx:invisible>
    <!-- Displayed when link is not accessible -->
  </pfx:invisible>
  <pfx:normal>
    <!-- Displayed when link is accessible -->
  </pfx:normal>
  <pfx:active>
    <!-- Displayed when current page == link target -->
  </pfx:active>
  <!--
    Displayed link content
  -->
</pfx:button>

The <pfx:button> tag supports the following attributes:

Table 4.2. Attributes of the pfx:button tag
Attribute name Mandatory? Description
page optional defaults to the current page. Used to give the target page where the link points to. Note: leaving this empty also implies mode="force".
pageflow / jumptopage / jumptopageflow / forcestop optional These attributes work the same as for form submit controls
startwithflow optional

Defaults to false. When set to true, the request will not go to a page directly, but start with the a processing of the chosen pageflow to determine the page to use.

The meaning of the page attribute also changes: If the submitted page is part of the chosen pageflow, the flow will be queried for the page to use up to the point in the flow where the given page is, which is then used in any case. In other words, this constitutes an end point for the search of a matching page in the flow.

mode optional

Default is empty. When set to force, a link is created and the matching CSS is used even in the active button state, i.e. whenever the target page is the current page.

When set to desc, the button state is not only active when the current page == target page, but also when the current page is a descendent page of the target page.

nodata optional Default to false. Normally, whenever you use a pfx:argument tag to attach parameters to the query string, the system automatically also adds the parmeter __sendingdata=1 to the query string, thereby signalling to the backend system, that it should process incoming data. Set this attribute to true to prohibit this behaviour.
frame / target optional Works the same as for submit controls
normalclass / activeclass / invisibleclass optional defaults are: core_button_normal, core_button_active and core_button_invisible. These three attributes define the CSS classes to be used for the three different states of a pfx:button

Commands and arguments

It is possible to use the same children to control the submit behaviour as it is done with form controls.

Link contents

The pfx:button template allows you to change the link content depending on the status of the target page.

  • Content of pfx:invisible will be only displayed when the target page is not accessible.

  • Content of pfx:active will be only displayed when the target page is the current page.

  • Content of pfx:normal will be only displayed when the target page is different from the current page and when it's accessible.

Content outside of these tags will be used in any case. If you only want to have different content for the invisible case, just put the content for the active and normal case inside pfx:normal, and add a pfx:invisible child with the differing content. The content of a pfx:normal node serves as the fallback for the other two cases.

[Note]Note

Note that only in the normal (regardless if the content comes from a dedicated pfx:normal child node or not) a link is put around the generated content.

Note also, that for differences between the three cases that can be expressed with CSS, you don't need to use these special child nodes. The system makes sure to use the three associated classes explained above to allow styling.

It is also possible to change to content, depending on whether a page has already been visited or not.

  • Content of pfx:visited will be only displayed when the link has been already visited at least once in this session.

  • Content of pfx:visited will be only displayed when the link has not been visited in this session.

The two tags above may also be put inside pfx:normal and pfx:invisible tags to express different content for accessible (or inaccessible) pages depending on the fact if they have been visited at least once already.

This makes of course not much sense with pfx:active, because a page where this applies is always the current page and by that is always visited.

4.2.2. pfx:url

This tag takes mostly the same attributes as <pfx:button>, but it only creates the URL and does not build up any content or generate a whole link. You can use this template if you just need the pure URL string.

4.2.3. pfx:elink

When creating links to external URLs care must be taken to ensure that no sensitive data (especially the session ID) leaks into log files of remote servers via the referer header. To make sure that this can't happen, all links to external sites must be propagated via a special servlet, the de.schlund.pfixxml.DerefServer.

Every Pustefix project has this servlet configured to be accessible under the path /xml/deref. To make the handling of external URLs easier, there also exists a special tag <pfx:elink> that automates the creation of the correct link.

<pfx:elink href="http://some.host/location" target="_popup|SomeName">
  <!--
    Optional, use the <pfx:host> child instead of the href attribute whenever you
    need to construct the URL with additional code (e.g. from data only available
    at runtime)
  -->
  <pfx:host>...</pfx:host>

  <!--
    Optional, use as many of <pfx:argument> tags as you need to supply the
    parameters for the query string.
  -->
  <pfx:argument name="SomeName">...</pfx:argument>

  <!--
    Place content of the link here
  -->
</pfx:elink>

4.3. Including text and images

There are two types of ressources that need to be included into a Pustefix page. Textual content ("Include Parts") is included with the help of the <pfx:include> tag while images are included via the <pfx:image> tag. Both tags make sure to register the ressources in the runtime system, so at all times the system knows which ressources a certain page uses. This information is used to check if the page is still up-to-date or needs rebuilding (by comparing file modification times of the ressources with the creation time of the page itself).

Of course this check can be disabled for a "live" system, as there is typically no need to check for changed ressources.

4.3.1. Include parts (<pfx:include>)

Include parts contain the content that is displayed on your pages. The parts are organized into include files. Every part has the same structure:

The children of the part tag are theme tags (at least one). The name attribute of the theme tag is the name of a theme as it is defined in the projects depend.xml.in file. Often these themes are just the project name or "default", which is used as the fallback when no more specific theme name matches (see here on how to define themes in the depend.xml.in file).

[Note]Note

Earlier versions of Pustefix had no special themeing, the only thing that was used was the project name itself and "default" as the fallback. Still today, the default value for the "themes" attribute in the root node of the depend.xml.in file (when not given explicitely) is just "<ProjectName> default", which makes the new system behave exactly as the old one did.

The resolution of the matching theme is done at the time the part is included (see below). Every page "knows" which themes are defined for it, and therefore it is possible to decide which product branch to use on generation time. The language on the other hand can be changed dynamically while the user clicks through the application, so the selection of the right language subtree (if more than one is present) is done at runtime.

<include_parts>
  <part name="Foo">
    <theme name="default">
      <pfx:langselect>
        <pfx:lang name="default">
          <!--
            The default content of part Foo goes here...
          -->
        </pfx:lang>
        <pfx:lang name="en_GB">
          <!--
            Default content in british english goes here...
          -->
        </pfx:lang>
        <pfx:lang name="en_*">
          <!--
            Default content in any other english language goes here...
          -->
        </pfx:lang>
      </pfx:langselect>
    </theme>
    <theme name="Theme_A">
      <!--
        The default content for theme Theme_A goes here...
      -->
    </theme>
  </part>

  <part name="Baz">
    <!-- Other parts -->
  </part>
</include_parts>

A part is referenced with two attributes: The filename of the include file that contains it, and the name of the part. The filename can be omitted, if you're referencing a part within the same file.

<pfx:include href="MyProject/txt/MyIncludefile" part="Foo" noerror="true|false" noedit="true|false"/>

Table 4.3. Attributes of the pfx:include tag
Attribute name Mandatory? Description
href optional If not given, it defaults to the current include part file. If it's not given and the module attribute is set, the path of the current include part file will be used as path within the module (omitting the first path component if the current file isn't already from a module).
part mandatory The name of the part to include
noerror optional Defaults to false. Set this to true to imply that no warning sign should be generated when the include is not found. Only set this when you know what you do.
noedit optional Defaults to false. Set this to true to imply that this include part should not be editable via the pustefix editor. Only set this when you know what you do.
level optional Not set by default. Set this to runtime if the part should be included at runtime (on the last transformation level).
search optional Not set by default. Set this to dynamic if a matching part should be dynamically searched. The search order is: current project, common folder, and if a module is specified: overriding module, specified module. See Section 6.3, “Dynamic resource inclusion”.
module optional Not set by default. Set this to the name of the module from which the part should be loaded. If dynamic search is set, the module just serves as fallback location if the part can't be found in the project or common location and isn't overrided by another module. See Section 6.3, “Dynamic resource inclusion”.

Using this tag results in the matching product branch of the include part to be inserted in place of the tag.

If you're deferring an include until runtime using level="runtime", you can also defer the creation of the href and part values until runtime using the pfx:href and pfx:part tags instead of the according attributes. The following example shows how to use values coming from the DOM result tree:

<pfx:include level="runtime">
  <pfx:href><ixsl:value-of select="/formresult/mypartinfo/@myhref"/></pfx:href>
  <pfx:part><ixsl:value-of select="/formresult/mypartinfo/@mypartname"/></pfx:part> 
</pfx:include>
[Note]Note
You should be aware that parts included at runtime aren't transformed with the master.xsl stylesheet, i.e. if the included part contains Pustefix tags (forms, buttons, etc.) they won't work. So the runtime inclusion is primarily intended for including simple text/HTML content.

4.3.2. Generated include requests (<pfx:maincontent>)

Looking at the example naturally leads to the question how it is possible to generate different pages with only a small number of structural xml files and always the same XSLT stylesheets. The answer is that at least one of the include parts isn't included via the pfx:include tag (which only handles static attribute values) but instead the filename of the include part is auto generated from the name of the page that is to be produced.

Looking at this page, one can see that the two transformations which produce BazPage.xml resp. BazPage.xsl have the page name supplied through the use of an XSLT transformation parameter. Using this parameter, the tag pfx:maincontent constructs an include request depending on the page name.

<pfx:maincontent part="content" path="MyProject/txt/pages" prefix="main_"/>

Table 4.4. Attributes of the pfx:maincontent tag
Attribute name Mandatory? Description
path optional If not given, but a XSLT parameter $maincontentpath has been defined in the depend.xml.in file, the value of the parameter is used. If there's even no $maincontentpath parameter, it defaults to PROJECTNAME/txt/pages
prefix optional defaults to main_
postfix optional defaults to .xml
part optional defaults to content
search optional Not set by default. Set this to dynamic if a matching part should be dynamically searched. The search order is: current project, common folder, and if a module is specified: overriding module, specified module. See Section 6.3, “Dynamic resource inclusion”.
module optional Not set by default. Set this to the name of the module from which the part should be loaded. If dynamic search is set, the module just serves as fallback location if the part can't be found in the project or common location and isn't overrided by another module. See Section 6.3, “Dynamic resource inclusion”.

For the page "home" this is equivalent to <pfx:include href="MyProject/txt/pages/main_home.xml" part="content"/> and of course similar for every other page.

Starting with this page specific include, the content of the page can be included from many different include parts.

4.3.3. Displaying images (<pfx:image>)

HTML <img> tags are usually not written directly, instead they are generated by using the <pfx:image> tag. Using this tag makes sure that the used image is registered in the runtime system as a dependency of the current target that's being generated.

One important feature of the <pfx:image> tag is that it inserts the natural height and width of the requested image unless they are explicitely given (as attributes width and height of course).

<pfx:image src="some/path/to/img.gif" themed-path="some/path" themed-img="img.gif"/>

Table 4.5. Attributes of the pfx:image tag
Attribute name Mandatory? Description
src optional

The src path references an image in the file system. It must be given as a path relative to the docroot (typically this means something like MyProject/img/foo.gif. Note that you need to define an alias for the image directories in your project.xml config file for Apache to be able to find the image.

Note that you can either specify the src attribute OR both of themed-path and themed-img

themed-path & themed-img optional

These two attributes allow for themed images. The mechanism uses the same theme fallback queue as it is used for include parts. The algorithm to find the image to use is quite easy:

Build an image path by concatenating themed-path, a / sign, the most specific theme, a / sign, and themed-img. Check if this image exists. If yes, use it as the src attribute for the resulting img tag. If not, take the next specific theme from the fallback queue (if it exists) and try again, until the image is found.

Example: The themes fallback list is "foo bar default", themed-path is "MyProject/img" and themed-img is "test.gif". The image file names that are tried one after the other are

  • MyProject/img/foo/test.gif
  • MyProject/img/bar/test.gif
  • MyProject/img/default/test.gif
search optional Not set by default. Set this to dynamic if the image should be dynamically searched. The search order is: current project, common folder, and if a module is specified: overriding module, specified module. The search ends if a matching image is found, regardless if there are matches with a more specific theme down the search chain. See Section 6.3, “Dynamic resource inclusion”.
module optional Not set by default. Set this to the name of the module from which the image should be loaded. If dynamic search is set, the module just serves as fallback location if an according image can't be found in the project or common location or another overriding module. See Section 6.3, “Dynamic resource inclusion”.
other attributes optional

All other attributes given (e.g. alt, width, height, title, etc. are copied unchanged into the resulting img tag

4.4. Handling HTML forms

Pustefix supplies a complete set of tags that replace the standard HTML form element tags. The advantage of using these tags is that they are automatically pre-filled with values delivered from the backend.

4.4.1. Form creation

The creation of a html form is done with the help of the tag <pfx:forminput>. Most often you don't need to set any attributes, the defaults should work just fine.

<pfx:forminput send-to-page="APage" send-to-pageflow="APageFlow" frame="AFrameName" target="ATargetName" type="auth|data">
  <!-- place form elements here -->
</pfx:forminput>

Table 4.6. Attributes of the pfx:forminput tag
Attribute name Mandatory? Description
type optional

Defaults to data. Must be set to auth, if the submitted information contains authentication data (e.g. userid, password).

target optional

Defaults to the parent frame (if frames are used, current window otherwise)

frame optional

This is used to select which named frame is about to be loaded into the target frame after submit. The default when frames are used is the parent frame.

Most often you have to set neither frame nor target.

send-to-page optional

Selects the page the submitted data is send to. Default is to use the current page. Most of the time, this is the right thing to do.

send-to-pageflow optional

Should not be used. Selects the pageflow to use. Default is to not set a pageflow name explicitely, but let the backend reuse the current flow or select a matching one. Leave it that way if you don't know why you want to change it. If you want to select a pageflow to use, better do so via the submit button as explained below. Note that this mechanism will most likely not work when using the send-to-pageflow attribute here.

4.4.2. Submitting forms

Make sure that all the other form related tags detailed below are contained inside a pfx:forminput block.

The form can be submitted by clicking on submit controls which can be realized in two ways: The simple html submit button is made with the tag <pfx:xinp type="submit">, while using an image as the submit control is done with <pfx:xinp type="image">.

A very useful ability of both submit controls is that it's possible to attach additional form parameters to them, that are only transmitted when that exact submit control is pressed. This way it's possible for a form to have two or more submit controls, each with different additional data attached and submitted, depending on which submit control the user clicks on.

<pfx:xinp type="submit|image" pageflow="APageFlow" jumptopage="APage" jumptopageflow="APageFlow" forcestop="true|false|step">
  <!--
    Attach additional information to the controls
  -->
  <pfx:command page="APage" name="SUBWRP">prefix</pfx:command>
  <pfx:argument name="AName">AValue</pfx:argument>
  <pfx:anchor frame="AFrame">AnAnchor</pfx:anchor>
</pfx:xinp>

Table 4.7. Attributes of form submit controls
Attribute name Mandatory? Description
type mandatory

submit creates a simple html submit button, image uses an image as the submit button.

pageflow optional

Used to explicitely set a pagflow to use after the submit has been handled sucessfully. Note that there is no corresponding way to set the page the submit is directed at, you need to set the send-to-page attribute of the pfx:forminput tag.

jumptopage / jumptopageflow optional

If you don't want the pageflow mechanism to control which page to display as the next page after a successful submit, you can set this page via the jumptopage attribute. In this case, you also have the possibility to set the pageflow to use for this follow-up page and submit circle via the jumptopageflow attribute.

forcestop optional

Default is false. If you don't want the pageflow mechanism control wether to stay on the current page after a successful submit or not, you can unconditionally force it to stay on the current page (when setting the attribute to true). Alternatively, if you want the pageflow mechanism to stop at most no more than one step further in the flow (e.g. a wizard like application) you can set this attribute to step.

When setting the type to image, you may also specify the attributes src, themed-path, themed-img, search and module. These attributes work exactly as described in Section 4.3.3, “Displaying images (<pfx:image>)”.

4.4.3. Arguments, comands and anchors

Command controls (like described in Section 4.4.2, “Submitting forms”) and links (like described in Section 4.2.1, “pfx:button”) can contain child tags that are used to pass additional data when the link or button is clicked.

Anchors

The <pfx:anchor> tag is used to supply an anchor for a link or submit button.

<pfx:anchor frame="AFrame">AnAnchor</pfx:anchor>

The content gives the name of the anchor as it's defined in the target page.

Table 4.8. Attributes of pfx:anchor
Attribute name Mandatory? Description
frame optional

You need to set it if the page uses frames or not. In this case you can use more than on pfx:anchor tag, one for each frame you want to define an anchor for. This way it's possible to scroll each frame independently to the desired position with one request (without the need for JavaScript). If you don't use frames, only one pfx:anchor tag makes sense, without a frame attribute.

Arguments

The <pfx:argument> tag is used to supply additional parameters for the request.

<pfx:argument name="AName">AValue</pfx:argument>

The content gives the value of the parameter to submit. It's also possible that this value is only known at runtime by using values dynamically supplied from the DOM tree. This may be handled like here:

<pfx:argument name="foo"><ixsl:value-of select="/formresult/bar"/><pfx:argument>

Table 4.9. Attributes of pfx:argument
Attribute name Mandatory? Description
name mandatory

The name of the argument to submit.

Commands

The <pfx:command> tag can be used to explicitly select the wrappers on a page, which should be used for handling the submitted data or retrieving the updated data after a successful submit.

 <pfx:command page="APage" name="SUBWRP|RETWRP">prefix</pfx:command>

The content gives the prefix of the wrapper to select as defined on the target page.

[Note]Note

If you don't give any selected wrappers for submit handling (SUBWRP), all wrappers defined on the target page become selected for submit handling.

If you don't give any selected wrappers for retrieving data after successful submits (RETWRP), no wrappers are selected for retrieving data.

It's recommended to use actions instead of commands. Actions let you define the selected wrappers within the configuration, which is a much cleaner approach.

Table 4.10. Attributes of pfx:command
Attribute name Mandatory? Description
name mandatory

The name of the command. Currently, the supported commands are SUBWRP, RETWRP and the deprecated SELWRP, which is an equivalent of SUBWRP and only supported for backwards compatibility.

All commands select a wrapper with the matching prefix on the page that is designated by the page attribute (or the current page, when empty).

SUBWRP selects a wrapper that should be used for handling the data that is submitted.

RETWRP selects a wrapper whose data should be retrieved/updated after a successfull submit.

You can use more than one pfx:command to select as many wrappers as you want.

Note: As the recommended way to select wrappers for submitting/retrieving data is the action mechanism, it is possible that the whole pfx:command stuff will go away in future releases.

page optional

Most often empty. This should be set to the page the request is directed at if it's not the current page.

4.4.4. Form elements

Using these form element tags ensures that values, that are supplied by the backend application are used as values for the generated html form elements. This is done dynamically by generating the necessary ixsl: statements that will check the DOM tree for matching values and adding them as value attributes (text, password and hidden input fields) or content (text areas) or selecting them according to their value (check boxes, radio boxes, option menus).

Another thing these tags do is to automatically check if the runtime DOM tree contains an error attached to their name. In this case, the resulting html input field is augmented with special CSS classes to help with styling these fields depending on the state they have (error/no error).

Typically the CSS used when no attached error is detected is just the value of a class attribute given to the pustefix input tag. On the other hand, if an error is attached, the class attribute looks like this:

[@class] PfxError PfxInputTextError [PfxErrorLevel_$level]

where @class is the user supplied class attribute mentioned above (if it's there at all) and $level is an optional attribute of the error element in the runtime DOM tree. The example works the same for other input fields of the form <input type="...">, by replacing "Text" with "Password", "Check" or "Radio" (Hidden input fields are not visible anyway. Select menus and text areas don't need a special class as they can be easily selected via CSS rules. For the last two, the error CSS looks like this:

[@class] PfxError [PfxErrorLevel_$level])

Creating a text input field

Text input fields are created using the <pfx:xinp> tag.

<pfx:xinp type="text" name="AName" default="AValue" position="1|..|n" class="ACssClass">
  <!--
    name and default can also be set at runtime
  -->
  <pfx:default>
    <ixsl:value-of select="/some/runtime/value"/>
  </pfx:default>
  <pfx:name>
    <ixsl:value-of select="/some/runtime/name"/>
  </pfx:name>
 </pfx:xinp>

Table 4.11. Attributes of pfx:xinp[@type="text"]
Attribute name Mandatory? Description
name or <pfx:name> mandatory

The name of the parameter. Use the name attribute when the name is a known literal value. If it must be computed at runtime (e.g. from the runtime DOM tree), you can use the <pfx:name> child element. In the end, the form of a parameter name should be prefix.InternalName.

name or <pfx:default> optional

The difference between the attribute and the child element form is analog to the description given above. You can use the default specification to pre-set a value for the case that the backend doesn't set one on it's own.

position optional

Default is 1. Useful only for parameters which are defined to occur multiple times, i.e. the same parameter name may appear more than one time in the output from the backend system to pre-fill elements on the UI. Wiht position you can decide, which of those multiple outputs under the same name you want to reference for the pre-filled value.

class optional

See Section 4.4.4, “Form elements” for an explanation on how the CSS class(es) for the html element are constructed.

Creating a text area field

Text area fields are created the same way as text input fields (see the section called “Creating a text input field”), you only have to set the type attribute to area.

Basically the same attributes as for <pfx:xinp type="text">, with the exception that there's no default attribute or child node. The same way as it works for the html textarea tag, the content of the element (minus the special <pfx:name> child) becomes the default value for the form input element.

Creating a password field

Password fields are created the same way as text input fields (see the section called “Creating a text input field”), you only have to set the type attribute to password.

Similar to <pfx:xinp type="text">, but without the ability to set a default value from the UI and the position is fixed to be "1".

Creating a hidden field

Hidden fields are created the same way as text input fields (see the section called “Creating a text input field”), you only have to set the type attribute to password.

Basically the same attributes as for <pfx:xinp type="text">. Of course no special class attribute handling, as the result is invisible anyway.

Creating a radio or check box

Radio buttons and checkboxes are created using the <pfx:xinp> tag as well.

<pfx:xinp type="radio|check" name="AName" value="AValue" default="true|false" class="ACssClass">
  <pfx:name>
    <ixsl:value-of select="/some/runtime/name"/>
  </pfx:name>
  <pfx:value>
    <ixsl:value-of select="/some/runtime/value"/>
  </pfx:value>
  <pfx:default>
    <ixsl:value-of select="/runtime/true/or/false"/>
  </pfx:default>
</pfx:xinp>

Table 4.12. Attributes of pfx:xinp[@type="radio|check"]
Attribute name Mandatory? Description
name or <pfx:name> mandatory

The name of the parameter. Use the name attribute when the name is a known literal value. If it must be computed at runtime (e.g. from the runtime DOM tree), you can use the <pfx:name> child element. In the end, the form of a parameter name should be prefix.InternalName.

A group of radio- or checkboxes share the same name and differ by the value they submit when they are checked.

value or <pfx:value> mandatory

Needed to set the value that is to be submitted when the element is checked. The difference between the attribute and the child element form is analog to the description given above.

default or <pfx:default> optional

Allowed values are true and false. The difference between the attribute and the child element form is analog to the description given above. You can use the default specification to decide if the form element is checked for the case that the backend doesn't supply which of the group's members are to be checked.

class optional

See Section 4.4.4, “Form elements” for an explanation on how the CSS class(es) for the html element are constructed.

Creating option menus

Radio buttons and checkboxes are created using the <pfx:xinp> and <pfx:option> tags.

<pfx:xinp type="select" name="AName" class="ACssClass" multiple="true|false">
  <pfx:name>
    <ixsl:value-of select="/some/runtime/name"/>
  </pfx:name>

  <!--
    One option tag per option that is available in the menu
  -->
  <pfx:option value="AValue" default="true|false">
    <pfx:value>
      <ixsl:value-of select="/some/runtime/value"/>
    </pfx:value>
    <pfx:default>
      <ixsl:value-of select="/runtime/true/or/false"/>
    </pfx:default>
  </pfx:option>
</pfx:xinp>

Table 4.13. Attributes of pfx:xinp[@type="select"]
Attribute name Mandatory? Description
name or <pfx:name> mandatory

The name of the parameter. Use the name attribute when the name is a known literal value. If it must be computed at runtime (e.g. from the runtime DOM tree), you can use the <pfx:name> child element. In the end, the form of a parameter name should be prefix.InternalName.

class optional

See Section 4.4.4, “Form elements” for an explanation on how the CSS class(es) for the html element are constructed.

multiple optional

Defaults to false. Set to true when you want to have a select menu with multiple selectable options.

Table 4.14. Attributes of pfx:option
Attribute name Mandatory? Description
value or <pfx:value> mandatory

Needed to set the value that is to be submitted when the element is checked. The difference between the attribute and the child element form is analog to the description given above.

default or <pfx:default> optional

See Section 4.4.4, “Form elements” for an explanation on how the CSS class(es) for the html element are constructed.

multiple optional

Allowed values are true and false. The difference between the attribute and the child element form is analog to the description given above. You can use the default specification to decide if the option is selected for the case that the backend doesn't supply which of the options are to be selected.

All other attributes are copied to the resulting HTML element.

4.4.5. Handling error conditions

Errors in Pustefix come in two variants:

  1. Field errors that are attached to a form input field and which must be handled on the page the form element is defined on.

  2. Page messages which are (not neccessary fatal) errors or warnings which may or may not be displayed on the current or the following page.

    Page messages are not associated to a single form element, but are used for general feedback on the status of the application.

Errors attached to a field

The <pfx:checkerror> tag is used to display content depending on the fact if a field error (or possibly a field error with a special level attribute) is present in the runtime DOM tree.

<pfx:checkerror level="AString">
  <!--
    Content to be displayed when any error with the matching level attribute is present in the
    runtime DOM tree. The level attribute is optional, when it's missing, any error will trigger
    the display of the content of the pfx:checkerror tag.
  -->
</pfx:checkerror>

The <pfx:checkfield> tag is used to display error messages depending on the form field they are attached to.

<pfx:checkfield name="prefix.Name">
  <pfx:error>
    <!--
      Content that's displayed when an error associated to the form field referenced
      in the name attribute is present in the runtime DOM tree.
    -->
  </pfx:error>
  <pfx:normal>
    <!--
      Content that's displayed when no error associated to the form field referenced
      in the name attribute is present in the runtime DOM tree.
    -->
  </pfx:normal>
  <!--
    Content outside of the two child nodes is displayed in both cases.
  -->
</pfx:checkfield>

There can be more than one of <pfx:error> and <pfx:normal> child nodes. These can be used to display completely different content based on the presence or not of an error.

The <pfx:checkfield> tag defines a set of ixsl variables that can be used inside its body. These are

  • $pfx_scode: The StatusCode node that represents the error. This can be used to call ixsl:apply-templates on to display the error message.
  • $pfx_level: The level attribute of the error in the runtime DOM tree (or empty, if there's no level attribute).
  • $pfx_class: The CSS class that has been constructed depending on the presence of the error. If there's no error, this variable is empty. Else, if the error is present and has no level attribute set, the value is just PfxError. If the error has a level attribute, the class is set to be PfxError PfxErrorLevel_{$pfx_level}.

Example 4.1. Using <pfx:checkfield>

<tr>
  <pfx:checkfield name="addr.Street">
    <td class="{$pfx_class}">Street:</td>
  </pfx:checkfield>
  <td><pfx:xinp type="text" name="addr.Street"/></td>
</tr> 
<pfx:checkfield name="addr.Street">
  <pfx:error>
    <tr>
      <td colspan="2" class="{$pfx_class}">
        <ixsl:apply-templates select="$pfx_scode"/>
      </td>
    </tr>
  </pfx:error>
</pfx:checkfield>

You can see how the second <pfx:checkfield> inserts a whole new row in the table structure when and only when a matching error happens. Also note how the defined $pfx_class variable is used to style content depending on the presence of an error.


Checking for pagemessages

The <pfx:checkmessage> tag is used to display content depending on the fact if a page message (or possibly a page message with a special level attribute) is present in the runtime DOM tree.

<pfx:checkmessage level="AString">
  <!--
    Content to be displayed when any page message with the matching level attribute is
    present in the runtime DOM tree. The level attribute is optional, when it's missing,
    any page message will trigger the display of the content of the pfx:checkmessage tag.
  -->
<pfx:checkmessage>

The <pfx:messageloop> tag can be used to repeat content for every page message that is present in the runtime DOM tree.

<pfx:checkmessage level="AString">
  <pfx:messageloop>
    <!--
      This content is repeated for all the page messages that match the restrictions imposed by
      the parent's level attribute (or all page messages, if the attribute isn not given).
    -->
  </pfx:messageloop>.
</pfx:checkmessage>

The <pfx:messageloop> tag defines a set of ixsl variables that can be used inside its body. These are

  • $pfx_scode: The StatusCode node that represents the error. This can be used to call ixsl:apply-templates on to display the error message.
  • $pfx_level: The level attribute of the error in the runtime DOM tree (or empty, if there's no level attribute).
  • $pfx_class: The CSS class that has been constructed depending on the presence of the error. If there's no error, this variable is empty. Else, if the error is present and has no level attribute set, the value is just PfxError. If the error has a level attribute, the class is set to be PfxError PfxErrorLevel_{$pfx_level}.

4.4.6. Avoiding duplicate form submission

You may face situations where you want to prevent, that the same form is submitted multiple times (e.g. by double-click, back button) or that a form, opened in a new window/tab, but already opened in another window/tab, can still be submitted from the old window/tab.

Using the <pfx:token> tag a hidden field with a random token is included into its parent form. The token is stored in the Context, keyed by a customizable name (by default pagename#elementid, which can be overwritten/replaced using the name attribute). After the form is submitted, the token is invalidated and submitting the form again causes the setting of a page message. Via the errorpage attribute you can optionally jump to an error page.

<pfx:forminput>
  <pfx:token errorpage="multisubmiterror"/>
  <!-- place form elements here -->
</pfx:forminput>

You should be aware that this mechanism depends on the caching behaviour of the used browser, e.g. for browsers, which don't cache but reload pages accessed via the back button, it can't prevent the repeated form submission, because the form in fact is a new instance and we can't detect or decide that the submit is illegal.

This mechanism by default only prevents forms with illegal tokens from being processed. If you want to ensure that form submits including no token will fail too, you can force this behaviour by setting the requirestoken attribute at the pagerequest's input element to true. This will force tokens for every form that's submitted to this page.

<contextxmlserver>
  <!--
    servlet config options
  -->
  <pagerequest name="...">
    <input requirestoken="true">
      <interface prefix="..." class="..."/>
    </input>
  </pagerequest>
</contextxmlserver>

4.5. Miscellaneous utility tags

Pustefix also provides several utility tags, that might be helpful in your application.

4.5.1. Checking page status

The <pfx:checkactive> and <pfx:checknotactive> allow you to check from the XSL-stylesheet, whether a specific IHandler currently is active or not.

<pfx:checkactive page="APageName" prefix="AHandlerName">
  <!--
    Content to be displayed, if the handler is active
  -->
</pfx:checkactive>

Table 4.15. Attributes of the pfx:checkactive and pfx:checknotactive tags
Attribute name Mandatory? Description
page optional

When using the page attribute, the content of the tag is only displayed if the referenced page is accessible. This is an easy way to display complete subparts of a page depending on the accessibility of another page.

prefix optional

When using the prefix, the content of the tag is only displayed if a referenced handler on the current page is active. The prefix is the same name as used in the servlet property file for the handler.

You can only use one of the attributes page and prefix.

4.5.2. Displaying content based on the language

The selection mechanism of <pfx:langselect> allows to select matching content anywhere inside a include part depending on the current language that is set in the running session. The <pfx:lang name="default"> tag is acting as the fallback for all languages that don't have a better, more specific named <pfx:lang> node.

<pfx:langselect>
  <pfx:lang name="en_*">...</pfx:lang>
  <pfx:lang name="en_GB">...</pfx:lang>
  <pfx:lang name="default">...</pfx:lang>
</pfx:langselect>

The system doesn't enforce but expects languages to be of the standard form of ISO language codes. In this case, a <pfx:lang> node with a name attribute ending in an asterisk (*) can be used to create a fallback for a whole "family" of languages. In the example above, the en_* node will serve as a fallback for all language codes starting with en_ except en_GB (which has a more specific node below).

4.5.3. Displaying content based on the theme

The selection mechanism of <pfx:themeselect> allows to select matching content anywhere inside a include part depending on the same selection mechanism that is used to select the include part the first hand as described in Section 4.3.1, “Include parts (<pfx:include>)”

<pfx:themeselect>
  <pfx:theme name="ATheme">...</pfx:theme>
  <pfx:theme name="default">...</pfx:theme>
</pfx:themeselect>

Of course this makes most sense, when the containing include part uses a general theme, so there are specialized themes in the theme fallback queues to select from.

[Note]Note

This tag is only to be used in very special situations. Normally you would like to use different themes for the include part to register itself correctly with the runtime system.

4.5.4. Using the Pustefix console

Pustefix provides an edit-console and webservice-console that are helpful during debugging.

Those consoles can be included in your pages using the <pfx:editconsole> and <pfx:webserviceconsole> tags. The webservice-console may also be included within the editconsole using the following form: <pfx:editconsole webserviceconsole="true">.