< Index | XML : Includes

XML : Includes

This guide will speak about two ways to use XML Includes (#inc(...)). The first one will show you a complete example on how to use it. The second will makes you discover what happend when it's used between attributes tags.

Basic include

Example without include

If you want to add two menus on the bottom bar which could be the same in each screen you create, you can repeat the code each time it is used. But this makes difficult a global modify and create useless repeated data which makes your application bigger. So the solution is to include XML in one another.
Example code :

mainscreen.xml:
<screen title="XML Include example">
    <text style="align: center" text="See the following bottom bar" />
    <!-- Bottom Bar -->
    <screenFirstMenu>Exit</screenFirstMenu>
    <screenSecondMenu>About</screenSecondMenu>
</screen>

 

Here is one screen which have a bottom bar.

Example with include

If you want another screen with the same bottom bar, instead of repeating obviously the code, you can include the bottom part in the screen code with #inc(...) statement:

mainscreen.xml:
<screen title="XML Include exemple">
    <text style="align: center" text="See the following bottom bar" />

    #inc(bottombar.xml)

</screen>

 

As you can see here, the path is relative. The parameter works same as Kuix.loadScreen() method. If you don't start with '/' then the choosen path is relative to '/xml/'. So, the bottombar.xml is located in /xml/bottombar.xml

bottombar.xml:
<screen>
    <screenFirstMenu>Exit</screenFirstMenu>
    <screenSecondMenu>About</screenSecondMenu>
</screen>

 

Include fundamentals

It's very important to notice that you are here facing an include of a Tree part into another Tree. Thinking that the include is same as merging file (such as PHP do for example) is a wrong way. The XML parser of mainscreen.xml will create a new parser on *#inc* statement. So the included XML must be well-formed and valid.

Due to the fact XML must be valid, we can't create a file with two nodes as root like this:

bottombar.xml:
<screenFirstMenu>Exit</screenFirstMenu>
<screenSecondMenu>About</screenSecondMenu>

 

To makes bottombar.xml well-formed, you can use the screen tag which "recover" the instance of screen (the parent screen where the file content tree will be included) and use it to add the menus.
Caution : If you give attributes to this screen in included files (like *title for example), they will override original attributes.*

Here is another example: If you want to add a list of widget in a file into a container, you must indicate the parent were it will be added.

Widgetlist.xml:
<container>
    <text>Text 1</text>
    <text>Text 2</text>
    <text>Text 3</text>
</container>

 

mainscreen.xml:
<screen title="XML Include exemple">
    <container style="layout:inlinelayout(false,fill); align: center">
        #inc(widgetlist.xml)
    </container>
</screen>

 

The 3 text widgets will be added to :
XML Include with text container example

If you specify, in the previous example, the screen tag instead of container, Kuix will create a new instance of screen and add it as a child of the container. This is due to the fact that screen is not the parent of included widgets (but container is).

If you want to include only one widget it's easier, simply put your widget definition in the included file.
With the bottom bar example, if you only want to include the second menu, we can write a shorter file like this:

bottombar.xml:
<screenSecondMenu>About</screenSecondMenu>

Here the XML is valid and this include works as well without the need to specify the parent.

Include and DataProviders

If you specify dynamic content, the screen which include the file will have his data provider given to included file. It is either possible to specify a DataProvider for this included part. The following example is based on a system wich log and disconnect a user and we want this information to appear on the bottom bar:

bottombar.xml:
<screen>
    <screenFirstMenu>Exit</screenFirstMenu>
    <screenSecondMenu onAction="toggleLog">@{isLogged}</screenSecondMenu>
</screen>

 

An action on the second menu widget will toggle the state between "Log in" and "Disconnect". To do that, you first create the dataprovider of the bottombar:

public class BottomBarDataProvider extends DataProvider {

    private static final String IS_LOGGED_PROPERTY = "isLogged";
    private boolean logged = false;

    public void setLogged(boolean logged) {
        this.logged = logged;
        dispatchUpdateEvent(IS_LOGGED_PROPERTY);
    }

    protected Object getUserDefinedValue(String property) {
        if (IS_LOGGED_PROPERTY.equals(property)) {
            return (!logged) ? "Log In" : "Disconnect";
        }
        return null;
    }
}

 

Then you could use this dataprovider when you load mainscreen.xml:

...
screen = Kuix.loadScreen("mainscreen.xml", new BottomBarDataProvider());
screen.setCurrent();
...

 

But in this case you can only acces to bottombar dataprovider.
Then how to be able to have a dataprovider for your screen and an other for your included file ?

You can create a parent dataprovider which will give the child dataprovider.

Let's create a new dataprovider:

public class MainDataProvider extends DataProvider {

    private static final String BOTTOM_BAR_DATA_PROVIDER_PROPERTY = "bottomBarDataProvider";

    private final BottomBarDataProvider bottomBarProvider = new BottomBarDataProvider();

    protected Object getUserDefinedValue(String property) {
        if (BOTTOM_BAR_DATA_PROVIDER_PROPERTY.equals(property)) {
            return bottomBarProvider;
        }
        return null;
    }

}

 

And modify your mainscreen.xml :

mainscreen.xml:
<?xml version="1.0" encoding="UTF-8"?>
<screen title="XML Include exemple">
    <text style="align: center" text="See the following bottom bar" />

    #inc(bottombar.xml, ${bottomBarDataProvider})

</screen>

 

As you can see, it will be MainDataProvider wich will give instance of BottomBarDataProvider:

Include in attribute tag

Takes note that if you use #inc(...) statement between attributes tags, the file is included but not parsed. Here is an example:

mainscreen.xml:
<screen title="XML Include exemple">
    <container style="layout:inlinelayout(false,fill); align: center">
        <text>
            <_text>
                #inc(bottombar.xml)
            </_text>
        </text>
    </container>
</screen>

 

which produce following result:

XML Include in attribute

This include usage could be usefull in case of a long text in a textarea (for example):

mainscreen.xml:
<screen title="XML Include exemple">
    <textarea style="padding: 0 5 0 5; align: left;">
        <_text>
            #inc(/myfolder/guide_xml_include.txt)
        </_text>
    </textarea>
</screen>

 

guide_xml_include.txt:
Here is the [...] statement.

 

Which result like following:
XML Include textarea attribute example