Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 40 Current »

Administering the client at a basic level is all done through the configuration xml file. The configuration allows multiple clients with different components depending on the user base of the client.

Layouts

The client is made up of three main parts, the toolbar, statusbar and the main content area. The toolbar is located at the top and the statusbar at the bottom. The administrator is free to move actions and components around the interface in order to customise the environment. The main content area is known as a perspective area, views can be added to a border layout within this area.

A border layout defines 5 regions that act as containers on the screen for views. The five areas are North (top), South (bottom), West (left), East (right) and Center (middle). Center is the only container that will dynamically resize all borders to fit within the area, all other regions only resize in one direction. For example, East and West Regions will resize their height depending on the size of the Application Window. North and South regions have fixed heights and will only resize their width depending on the size of the Application Window. This does not mean that the user does not have the ability to resize the views if allowed by the administrator, just that the initial size of the non-center panels is pre-determined.

Main Views can be added to a particular region. For example you might want the TOC and Search Views to be added to the West region. When multiple views are added to a region then they are added as tabs given users the ability to move between the Views. An alternative options allows the administrator to configure the region to use an accordion type layout rather than a tab based one.

The client now also allow for nesting regions within a region, so now each region can also be sub-divided into north, south, east, west and center. Also, regions can now be named, so they can be referred to by a logical name when adding views rather than having to refer to their physical location. See the section on Layouts for more information.

Both the Statusbar and Toolbar support adding both Actions and Components to them. Toolbars can also be added to some Views, for example the Map View. See the Toolbars and Actions sections for more information. 

Client Configuration

Weave supports the ability to configure multiple clients from one instance. Each Client needs to have a unique ID that is used in the url when opening the client.

...
<client:config id="main">
  ...
</client:config>

<client:config id="police">
  ...
</client:config>
...

In the above example there are two clients defined and each has a different id. When using the client open a browser and point to

http://server:port/weave/main.html

or

http://server:port/weave/police.html

Additionally, if there is more than one client configuration and the user views
http://server:port/weave
they will be presented with a list of the available client configurations.

Access Control

By adding an ACL to the client configuration you can restrict access to the entire client configuration based on the access level of the user.

For example to restrict the police configuration to only those users who are in the police access control list you would change the configuration to:

...
<client:config id="police">
  <acl id="acl.police">
  ...
</client:config>
...

this assumes that elsewhere in your configuration you have the ACL for acl.police, something like:

<acl:acl id="acl.police">
  <entry type="allow">ROLE_POLICE</entry>
  <entry type="deny">*</deny>
</acl:acl>

You should consult the section on Access Control Lists for more information.

Alternatively, you can add an ACL to individual items within the client configuration to have those items only available to users that have the appropriate level of access.

For example, to provide a generic client that has a single button that should only be available to users in a certain group you could either create two separate client configurations, one with the button for the selected users and the other without the button for everyone else, or you could create one configuration with the button but attach an ACL to the button.

...
<client:config id="main">
  ...
  <toolbar>
    ...
    <item action="au.gov.police.ShowSpeedCameras">
      <acl id="acl.police"/>
    </item>
    ...
  </toolbar>
  ...
</client:config>
...

This way anyone can access the main client configuration, but only those users that login and pass the acl.police ACL will be able to see the au.gov.police.ShowSpeedCameras button.

The ACL can be attached to anything within the client configuration, not just buttons/actions. When a user does not pass the ACL then the entire content of the tag containing the ACL tag is removed.

Additionally, you can have the same item added twice, each with a mutually exclusive ACL attached so that all users see one version and others see another.
This can be used for example to alter the map area that a user is allowed to view, if you have multiple groups of users, where each one should only be able to view part of the overall map then you could setup multiple extent tags for the map view and attach different ACLs to each one so that in the end each user only receives one of the available extents and that's the area they're limited to.

Structure

The actual content of the client configuration should follow the same basic outline regardless of the final layout of the client.

The absolute minimum requirements for a client configuration is shown below (where CONFIGID, TITLE and LABEL are configured by you)

<client:config id="CONFIGID">
  <title>TITLE</title>
  <perspective>
    <label>LABEL</label>
  </perspective>
</client:config>

Obviously, this creates a pretty useless client experience as it creates single center region with nothing in it.

So the next this we could do would be to add content to the default center region that was created. We do this by adding Views to the perspective. A View is responsible for presenting its content the the user in whatever way is appropriate, it could be a map image, a text input form or just a fixed image. What's shown in the region is different depending upon the id of the view that's added to the perspective, so for now we won't bother looking at the actual content of the view tags.

<client:config id="CONFIGID">
  <title>TITLE</title>
  <perspective>
    <label>LABEL</label>
    <view id="VIEWID">
      VIEWCONTENT
    </view>
  </perspective>
</client:config>

Once we've added the view we would expect to see the content of the view displayed in the center region.

From there we can add additional views to show different content to the user.

<client:config id="CONFIGID">
  <title>TITLE</title>
  <perspective>
    <label>LABEL</label>
    <view id="VIEWID1">
      VIEW1CONTENT
    </view>
    <view id="VIEWID2">
      VIEW2CONTENT
    </view>
  </perspective>
</client:config>

The user will then be able to switch between displaying the two views because by default views are added to the center region and that region is configured to display multiple views using tabs.

This brings us on to layouts, which are covered in more detail at Layouts, but we'll cover them here to show where they fit within the client configuration.

Say we wanted to move one of our views to be to the left of the other one, rather than having them both within the same region. To do this we'd add a layout to the perspective and then configure each of the views to be placed in a specific region within the layout. Remember at the moment there's a default layout created for us that has a single center region defined.

<client:config id="CONFIGID">
  <title>TITLE</title>
  <perspective>
    <label>LABEL</label>
    <layout>
      <west width="WIDTH">
      <center>
    </layout>
    <view id="VIEWID1" location="west">
      VIEW1CONTENT
    </view>
    <view id="VIEWID2">
      VIEW2CONTENT
    </view>
  </perspective>
</client:config>

Once we have the new layout in place the first view will appear on the left and the second on the right, with the left view taking up an amount of room determined by the value of WIDTH and the second filling in the rest. The second view will still go into the center region since that's the default if none is explicitly set, and there must always be a center view defined within a layout.

From there we can fill out the client configuration with some other components. We can add a toolbar and statusbar (as mentioned earlier).

<client:config id="CONFIGID">
  <title>TITLE</title>
  <toolbar>
    TOOLBARCONTENT
  </toolbar>
  <statusbar>
    STATUSBARCONTENT
  </statusbar>
  <perspective>
    <label>LABEL</label>
    <layout>
      <west width="WIDTH">
      <center>
    </layout>
    <view id="VIEWID1" location="west">
      VIEW1CONTENT
    </view>
    <view id="VIEWID2">
      VIEW2CONTENT
    </view>
  </perspective>
</client:config>

These will always be shown at the top and bottom of the page irrespective of the layout. If you have more than one perspective then a perspective switcher component would be an obvious choice to include in the top-level toolbar or statusbar.
Note that perspectives can also have their own toolbar and/or statusbar, as can views (but it's up to the implementation of the view to provide support for it).

We can also include a set of default values at the same level as perspectives to provide defaults values for various components that are included on the client, for example indicating the initial map extent to use if a map view doesn't specify it explicitly, or determining if a report should be opened in a new browser window.

<client:config id="CONFIGID">
  <title>TITLE</title>
  <toolbar>
    TOOLBARCONTENT
  </toolbar>
  <statusbar>
    STATUSBARCONTENT
  </statusbar>
  <perspective>
    <label>LABEL</label>
    <layout>
      <west width="WIDTH">
      <center>
    </layout>
    <view id="VIEWID1" location="west">
      VIEW1CONTENT
    </view>
    <view id="VIEWID2">
      VIEW2CONTENT
    </view>
  </perspective>
  <defaults>
    DEFAULTCONTENT
  </defaults>
</client:config>

Again the contents of the default section are determined by what's being set, but generally, there could be a report section, a map section and a section for entities.

Aside from that, there are a couple of other minor items that could be added, one is a description, that's shown to the user if they get the option to choose between multiple client configurations. Another is a debug flag that indicates that the client should be loaded in debug mode which helps when modifying the client configuration. And finally, it's possible to specify a theme to be used for the configuration.

<client:config id="CONFIGID">
  <title>TITLE</title>
  <description>DESCRIPTION</description>
  <debug>true</debug>
  <theme>THEMENAME</theme>
  <toolbar>
    TOOLBARCONTENT
  </toolbar>
  <statusbar>
    STATUSBARCONTENT
  </statusbar>
  <perspective>
    <label>LABEL</label>
    <layout>
      <west width="WIDTH">
      <center>
    </layout>
    <view id="VIEWID1" location="west">
      VIEW1CONTENT
    </view>
    <view id="VIEWID2">
      VIEW2CONTENT
    </view>
  </perspective>
  <defaults>
    DEFAULTCONTENT
  </defaults>
</client:config>

Defaults

You can set various default options in the defaults section in the client configuration. For example, the default report format to generate, which entity to have active initially or which data to display when the user open a data grid.

<client:config id="CONFIGID">
  ...
  <perspective>
    ..
  </perspective>
  <defaults>
    <entities>
      <entity id="property" isDefault="true">
        <data>data.property.detail</data> <!-- set the default data definition for properties -->
        <search>search.property.byaddress</search> <!-- set the default search for properties -->
      </entity>
      <entity id="roads">
        <data>data.road.detail</data> <!-- set the default data definition for roads -->
        <search>search.road.byname</search> <!-- set the default search for roads -->
      </entity>
      <entity id="parks" remove="true"/> <!-- remove parks as being an available entity -->
      <entity id="lights" remove="true"/> <!-- remove lights as being an available entity -->
    <entities>
    <report>
      <format>html</format>
      <openExternal>true</openExternal>
      <openWithScript>true</openWithScript>
      <timeout>240</timeout>
    </report>
  </defaults>
</client:config>

In the above example we've set the property entity as the default, and set the initial search for properties to be search.property.byaddress and the initial data to be data.property.detail. For roads we've set the search to search.road.byname and the data to data.road.detail. We've also removed the parks and lights entities from being available to the user. The user will have access to all the other available entities, but they will have the default settings (for default search, data definition, etc).

We've also specified that the default report format will be html, format, report will open in a new window (or tab) rather than a window embedded within the weave client itself, openExternal, and it'll use JavaScript to open the window, bypassing the intermediate 'click to open' popup window, openWithScript,  and finally increased the report timeout to 240 seconds (from the default of 120 seconds), timeout.

You can specify exactly what entities are available on the client for a user by specifying the name of a user attribute that contains the id's of the entities that should be available.

Setting entities based on a user attribute
<client:config id="CONFIGID">
  ...
  <perspective>
    ..
  </perspective>
  <defaults>
    <entities userattribute="entities"/>
    ....
  </defaults>
</client:config>

In the above example the user attribute named entities should contain one or more entity id's and the user will have access to only those entities. In this situation you can still specify individual entity settings, for example the default search, within the entities tag (they just haven't been shown in this example), but you can also specify that information directly within the entity configuration rather than here in the default section.

It's also possible to have the list of entities listed in the entities section refine the available entities directly. By default specifying multiple entity tags within the entities tag just modifies the settings for those entities, but by setting filter to true for in the entities tag you can further specify that these entities listed will be the only ones available to the client.

Refining what entities are available
<client:config id="CONFIGID">
  ...
  <perspective>
    ..
  </perspective>
  <defaults>
    <entities filter="true"> <!-- user will only have access to property, roads and parks -->
      <entity id="property" isDefault="true">
        <data>data.property.detail</data>
        <search>search.property.byaddress</search>
      </entity>
      <entity id="roads">
        <data>data.road.detail</data>
        <search>search.road.byname</search>
      </entity>
      <entity id="parks"/>
      <entity id="lights"/>
    <entities>
    ....
  </defaults>
</client:config>

In this example users will only have access to the property, roads, parks and lights entities, with some additional settings being applied to the property and roads.

Entity selections

By default entity selections are preserved between client restarts, by setting the flag retainSelections to false for the client config the selections will be cleared when the client starts

<client:config id="editing" retainSelections="false">

  <!-- you could also set it like this -->
  <retainSelections>false</retainSelections>

  <!-- The rest of the client config goes here -->
</client:config>

Icons

You can create custom icons that can then be referred to in the client configuration by creating an icons directory within the ...\weave\platform\workspace directory, then any .gif or .png files within there will be available to use anywhere an iconCls attribute can be set. Note that if the icons directory doesn't exist when the server is started it will need to be restarted before icons are available for use.

The icons aren't available directly, instead Weave will create a CSS rule to reference the image, and it's the CSS rule that you reference in the config. The name of the rule is based on the file name, but is given an icon- prefix, so for example test.png would create a rule named .icon-test which can then be referenced as icon-test in the config file.

It's assumed that if there are two icons with the same name, and one a .png and the other .gif, then the .gif will be used for Internet Explorer and the .png for other browsers, this is because of the poor support for .png images in earlier IE versions.
In this case, the icon is still referred to be the same name in the config files, the rule just ensures that the correct image is chosen at runtime.

Note that this is no longer strictly true and Internet Explorer has improved the level of support for .png images, so you should always use .png images rather than .gif

To see what current icons are available for use, open the HTML page /weave/styles/core.css on the Weave instance
e.g. http://localhost:8080/weave/styles/core.css
and any line starting with .icon- will be an icon available for use.

The actual bitmaps for most of these will be contained in the com.cohga.client.weave.main_*.jar bundle (which is just a .zip file), and they're stored under the /client/resources/images/icons/ directory inside that file.

Not all bitmaps are in that one file, others may be supplied by other bundles, but they should all be in the same directory, but any decent browser should provide an option to directly peruse the icons anyway.

Pretty much any component can have its icon set by setting the iconCls property to one of these icons, e.g. to use .icon-edit in a toolbar:

<item action="weave.toggleToolbar" text="Edit" iconCls="icon-edit">
  ...
</item>

If you want to remove the icon for a component set the iconCls property to be blank, e.g. to remove the icon from the Legend panel in your layout:

<view id="com.cohga.client.panel.legend" iconCls="">
	<label>Legend</label>
	<location>west</location>
     ...
</view>


Additionally, for the text/labelling, it can be a bit inconsistent, but a general run of thumb is to set a 'text', or 'label', property to add/alter the default text for a button/panel/component/control.

Aliases

As of version 2.22.9 of the com.cohga.client.weave bundle it's possible to specify an alias for a client configuration.

<client:config id="client">
  <alias id="alias"/>

  <!-- Other config items here -->
<client:config>

At the minimum this provides exactly the same client configuration under an additional url, so the above configuration would be available at
/weave/client.html
and
/weave/alias.html

This by itself isn't much, but by allowing you to publish the same client config under different url's you can provide different security contexts for them.
That is the security.xml file can now specify different security filters to be applied to the same client config (this is because the security chain is based on the initial URL).
This means it's possible to have a single client config, and point one group of users to one url to access it, where they'll need to login with a username and password, and have another group of people access the same client config, via a different url, where NTLM authentication is used.

The security implications described above rely on changes also being made to the security.xml, and will probably require advanced configuration of the security.xml file.

Additionally you can override some of the configurations in the client config. For example:

<client:config id="external">
  <alias id="internal">
    <title>Internal Client</title>
    <description>Client for access by internal users</description>
    <license xsi:nil="true"/>
  </alias>

  <title>External Client</title>
  <description>Client for access by external users</description>
  <license>
    <title>License</title>
    <text>By clicking OK you agree ....</text>
  </license>

  <!-- Other config items here -->
<client:config>

would be the equivalent of:

<client:config id="external">
  <title>External Client</title>
  <description>Client for access by external users</description>
  <license>
    <title>License</title>
    <text>By clicking OK you agree ....</text>
  </license>

  <!-- Other config items here -->
<client:config>

<client:config id="internal">
  <title>Internal Client</title>
  <description>Client for access by internal users</description>

  <!-- Other config items here -->
<client:config>

This example will alter the title and description for the internal version of the client config, plus it'll remove the license screen that the external user normally would have to click on.

You can also specify an ACL in the alias, but it doesn't affect the alias itself, as is the case if an ACL is attached to any other item in a client config, rather it'll replace the ACL for the client as a whole.

This means the following:

<client:config id="external">
  <alias id="internal">
    <title>Internal Client</title>
    <description>Client for access by internal users</description>
    <license xsi:nil="true"/>
    <acl id="internal"/>
  </alias>

  <title>External Client</title>
  <description>Client for access by external users</description>
  <license>
    <title>License</title>
    <text>By clicking OK you agree ....</text>
  </license>
  <acl id="external"/>

  <!-- Other config items here -->
<client:config>

is equivalent to:

<client:config id="external">
  <title>External Client</title>
  <description>Client for access by external users</description>
  <license>
    <title>License</title>
    <text>By clicking OK you agree ....</text>
  </license>
  <acl id="external"/>

  <!-- Other config items here -->
<client:config>

<client:config id="internal">
  <title>Internal Client</title>
  <description>Client for access by internal users</description>
  <acl id="internal"/>

  <!-- Other config items here -->
<client:config>

Some other things you could do would be to set the publish flag to false in the alias configuration so that the aliased client configuration won't show up in the users list of available configs (but they can still access it using a direct url), which is handy for client configurations that are used for third party integration.

<client:config id="main">
  <alias id="pathway">
    <title>Pathway Client</title>
    <description>Client to be used when called from Pathway</description>
    <license xsi:nil="true"/>
    <publish>false</publish>
  </alias>

  <title>Default Client</title>
  <description>General client for use by users</description>
  <license>
    <title>License</title>
    <text>By clicking OK you agree ....</text>
  </license>

  <!-- Other config items here -->
<client:config>

Adjusting the panel collapse buttons

The buttons used to expand and collapse the panel can be too small for some users, but since these buttons are just images they can be updated to use a different image.

Small collapse button

Here is a bundle that contains a set of replacement buttons, com.cohga.client.weave.themes.collapse_1.0.0.jar, that you can use to alter the appearance.

Larger collapse buttons

Installing the new expand/collapse button theme

To use the updated buttons you need to download the com.cohga.client.weave.themes.collapse_1.0.0.jar file and copy it to the ...\weave\platform\plugins\ directory.

Once you've done that you have to edit the ...\weave\platform\configuration\config.ini file to add the file you just downloaded to the list of bundles that Weave will start automatically each time Weave is restarted.

The image below shows the config.ini file after it's been edited, the line that needs to be added has been highlighted in the image. In this case, the line has been added after the lines that list the grey and olive themes that ship with Weave, the line that's added to config.ini is the line containing com.cohga.client.weave.themes.collapse@:start,\

Editing config.ini to add new bundle

After downloading and installing the file, and editing config.ini you should restart the Weave instance to ensure the new bundle is started and available for use.

Using the new expand/collapse theme in your client

After you have the new theme bundle installed and started you have to add the theme to the client config, along with any existing theme you're currently using.

The image below shows an existing client config that has been changed to add the line highlighted below. Note that your client config will not match the example below, the one below is just an example to show you where in your client config(s) you'd need to add the highlighted line to enable the larger expand/collapse buttons.

In the following example, the client config is already setup to use the grey theme, you may not be using a theme at all, in which case you won't have an existing theme entry and you should just add a new theme tag for the expand/collapse buttons.

Editing client config to add new theme

As of Weave 2.5.18 this bundle is already included and setup so all you need to do is the last step to add the collapse theme to your client config.

Licence agreement, startup tips and splash screens

It's possible to have the client display a licence that the user must agree to before continuing or to display some general text, by adding one of the following configs to the client file.

Displaying a licence agreement
<client:config id="main">
	<licence>
		<title>Licence Agreement</title> <!-- "Licence Agreement" is the default so this is not strictly required -->
		<text>This is where you would insert the agreement text you wish the user to confirm.</text> <!-- this must be set -->
		<url>http://example.com</url> <!-- optional link if the user does not agree -->
		<usetop>true</usetop> <!-- Since Weave 2.5.26: When Weave is embedded inside an IFrame, indicate that the top-level window has to be changed to the given URL. -->
	</licence>

	<!-- rest of client config goes here -->

</client:config>
Displaying a startup tip
<client:config id="main">
	<tip>
		<delay>1000</delay> <!-- how long before the tip should popup, default is 1000ms so this is not strictly required -->
		<title>Tip o' the day</title> <!-- title for the tip window -->
		<text>Don't run with scissors</text> <!-- required text for the tip -->
		<time>3000</time> <!-- how long the tip should show -->
	</tip>

	<!-- rest of client config goes here -->

</client:config>
Splash screens

New in 2.6.7 is the splash screen, which has the combined function of the licence and startup tip. A splash screen provides a way to display information to the user at startup similar in appearance to the licence agreement above but provides additional options to customise the experience.

One major difference between the splash screens and the licence panel/tips, is that you have to supply HTML content to be displayed. The content can either be embedded directly in the configuration or provided as a URL pointing to a web page to display. Note that this isn’t such an issue now because 2.6.7 also provides a convenient method of publishing your own custom HTML directly from Weave by storing the HTML in the ...\weave\platform\workspace\static\ directory. That HTML will then be available at the URL http://example.com/weave/static/. This allows much more control and flexibility with the content of the window, and because it directly supports multiple tabs, you can provide separate sections with different content. For example, the first tab can be a welcome text, the second a help guide and the third a contact page.

By providing a redirect URL as part of the configuration you can change the simple Close button into a choice between Yes and No and make this a replacement for the licence panel (as shown below).

<plugin id="weave.splash">
	<html>Splash content here</html>
	<redirectUrl>https://www.cohga.com/</redirectUrl>
</plugin>

If the user clicks Yes, the panel will close. If they click No, they will be redirected to where ever you set the redirect URL.

In addition, you can provide the user with an option not to display the splash screen again. This can be used in combination with a button added to a toolbar/statusbar to allow the user to open the panel again if they want (as shown below).

<plugin id="weave.splash">
	<html>Splash content here</html>
	<redirectUrl>https://www.cohga.com/</redirectUrl>
	<allowHide>true</allowHide>
</plugin>

<toolbar>
  <item action="weave.showsplash"/>
</toolbar>

Finally, you have the option to configure the splash panel to display only once. So once it’s closed the first time it won’t display on startup again unless you provide access to the button to re-show the splash panel (see toolbar item above) or update the config to give the panel a different id.

<plugin id="weave.splash">
	<html>Splash content here</html>
	<redirectUrl>https://www.cohga.com/</redirectUrl>
	<showOnce>true</showOnce>
</plugin>

Configuration for the splash panel is provided by a plugin, and the various configuration options for the panel are configured within the plugin. Some configuration examples are shown below.

Show a basic splash page with the content from a static web page (served by Weave from the content at ...\weave\platform\workspace\static\welcome.html)

<plugin id="weave.splash">
	<url>static/welcome.html</url>
</plugin>

Show a basic splash page with the content from a static web page (served by Weave from the content at ...\weave\platform\workspace\static\information.html) that the user only sees once.
Additionally, it has a splashId set which can be changed if the content of the information.html file changes and you want to force the panel to display again if it's been hidden. Note that the splashId defaults to "startup", so if you didn't set a splashId at the start but now want to force the page to display again you can just add a new splashId (that isn't "startup").

<plugin id="weave.splash">
	<url>static/information.html</url>
	<splashId>splash20211119</splashId>
	<title>Important News</title>
	<iconCls>icon-information</iconCls>
	<showOnce>true</showOnce>
</plugin>

Show a basic licence page with the content from a static web page (served by something else) and a custom window size.

<plugin id="weave.splash">
	<height>400</height>
	<width>600</width>
	<url>https://cohga.com/weave/licence.html</url>
	<redirectUrl>https://cohga.com/weave/<redirectUrl>
</plugin>

Show a basic splash page with embedded HTML that allows the user to stop it displaying at the start of each session.

<plugin id="weave.splash">
	<height>100</height>
	<html><![CDATA[
		<div style="padding: 15px; font-size: 15pt; background: #dee9f7; height: 100%; text-align: center">
			Welcome to the wonderful world of Weave
		</div>
	]]></html>
	<allowHide>true</allowHide>
</plugin>

Show a splash page with multiple tabs.

<plugin id="weave.splash">
	<tabs>
		<tab url="static/welcome.html" title="Welcome"/>
		<tab url="static/help.html" title="Help"/>
		<tab url="static/contact.html" title="Contact"/>
	</tabs>
</plugin>

Finally, the show splash button can be added to a toolbar and would allow the user to display the page at any time.

<item action="weave.showsplash"/>

If you have a different splashId specified in the plugin configuration you have to also provide that.

<item action="weave.showsplash" splashId="splash20211119"/>

If you want to specify a different tab on a multi-tab splash panel you can also do that, for example to show the Help tab in the above configuration when the button is pressed you can use the following (the tab number starts from 0).

<item action="weave.showsplash" tab="1"/>

Further Reading

  • No labels