Apps and development tools - Basic App Kit

Customizing your app-kit App

Defining the HDBModel



    <storage sid="Customers">

        <content contentclass="Customer"/>


    <storage sid="Projects">

        <content contentclass="Project">

           <relation name="project-customer" targetclass="Customer"/>




Application Design

After you defined the HDBModel and reconnected the database you have a full working application.

Your storages appear in the left navigation panel and your storage contents are shown as views inside the content panel of the app. If you are EDITOR in your app, you can now create content inside each of your storages. You can search inside a storage, select one or more contents and delete them.

However all views have a default view layout and when you edit a document all you can do is to enter a title of the document. So ... you need to customize your app.

The basic concept of appkit is that you need to customize only that parts that really needs a customization. 

To customize your app first create a folder for each storage and each content class that needs customized code. What code you place inside the folder depends on how much you need to change the default behavior of of appkit.

  • If you want to fully control the behavior of a storage or content class create a tml with name "portlet.tml" inside the folder and code whatever you want in this tml.
  • if you need complete custom behavior but want to reuse the default panel layout of appkit, include content@base inside your portlet.tml and specify header, body and footer as options. Note that the module content@base does know nothing about your model and its dependencies. content@base does only create a layout without any default behavior.
  • If you are generally happy with the default behavior for storages and contents and only want to change special parts of the content/storage layout you may include hdb:storage:portlet@base for storages or hdb:content:portlet@base for contents and define your custom layout as options "header", "body" and "footer" in this include. the hdb:... modules are aware of your HDBModel and your need not to care about create/edit/delete actions.
  • If you are happy with the default behavior of storages and contents but want only define your own view layout or form layout, you don't need a portlet.tml. Instead you create a form.tml for contents and views.tml (or view.tml) for storages as described in the following chapters.


For each content class you defined in your model create a folder with the name of the content class in your design directory.

If you only whant to define a form that can be used to enter data:

  • Create a TML with name form.tml inside this folder. The simples way to do this is to copy the form.tml from the Template-Folder into you content class folder and customize it. The form.tml will automatically be called from the storages view component and emedded inside a <tml:form>. You don't nee a <tml:form> in your form.tml yourself.
    The form will be opened in view mode and actions to edit and delete are rendered inside the footer area. In edit mode a save action is rendered.
    You don't have to handle saves by yourself.

If there is a need to completely control the layout of your content class data:

  • Create a TML with name portlet.tml inside the folder and put inside whatever your content class layout should look like. The portlet.tml will automatically be called from the storages view component.
    The portlet.tml may include the TML hdb:content:portlet@base with some options. This will help you to customize the layout without havin to do everything by yourself. the hdb:content:portlet handels edit/delete/save actions for you for example.

Sample form.tml:







For each storage you defined in your model create a folder with the name of the storage in your design directory.

Inside this folder you need to create a TML with name "view.tml" if you need only a single view or views.tml if you need multiple views. The simpleas way to do this is to copy the views.tml from the Template-Folder into you storage folder and customize it.

Sample view.tml (for a single view):


    <search label="Filter By Title:"/>

    <col label="Firstname">firstname</col>

    <col label="Lastname">lastname</col>

    <col label="Created">CREATED</col>



Actions for create, edit and delete are generated automatically.

If you need to add your own action you have to create a custom portlet.tml inside your storage or content folder and add your actions inside this portlet.tml.

Typically you will include hdb:storage:portlet@base or hdb:content:portlet@base and add your actions inside a custom footer option like this:

<tml:include ref="hdb:content:portlet@base>

    <tml:option name="footer">

        <tml:include ref="hdb:content:default-actions@base"/>

        <a href="<tml:url type="action">...</tml:url>" class="btn">My Action</a>



The above example includes the "default actions" (edit/delete) inside the footer and adds one more custom action.

(Ajax-)Links to other resources

Basic AppKit apps are ajax enabled by default.

If you want to link to other HDBModel resources inside out custom module you can user data attributes inside the link tags.

The most important data attribute is data-wgakey="<some-key>". Each links containing data-wgakey is automatically converted to a link calling an ajax action and open the requested resource without loading the complete html page.


<a href="<tml:url"/> data-wgakey="<tml:meta name="key"/>">open ...</a>

Supported data attributes are:


Open the page referenced by the attribute value

data-portletmode (optional):

Open the the requested resource in a portlet with specified mode. Default value is "view".

data-contentclass (optional):

if the rquested resource id a storage and portletmode is "new" the requested content class will be available if edit mode.

data-wga-ajaxrefresh (optional):

Specifies with panel should be refreshed. The default value is "page", loading the complete page including appnav panel and header panel. If you want only the content panel to be refreshed user data-ajax-refresh="content"