Fragment Layout: Using xml files

 

 

WORK IN PROGRESS

This page is currently under construction. Please stay tuned

 

There are a set of fragment layouts that are created by default when deploying uPortal for the first time. These fragment-layout entities are stored in the quickstart_entities directory at  ../uportal-war/src/main/data/quickstart_entities/fragment-layout. Each of these fragment-layouts also have an audience defined in ../uportal-war/src/main/data/quickstart_entities/fragment-definition and a fragment owner.

These layouts can be used as a basis to create your own fragment-layout. Let's use one of these as an example.

Step 1: Taking a look at an existing fragment-layout xml file

Below is an example of one of the quickstart fragment-layout entities, welcome-lo.fragment-layout.xml. This particular fragment is the "Welcome" tab, which is the first tab after logging into the portal after your first deployment.

<layout xmlns:dlm="http://www.uportal.org/layout/dlm" script="classpath://org/jasig/portal/io/import-layout_v3-2.crn" username="welcome-lo">
  <folder ID="s1" hidden="false" immutable="false" name="Root folder" type="root" unremovable="true">
    <folder ID="s2" hidden="true" immutable="true" name="Header folder" type="header" unremovable="true">
      <channel fname="fragment-admin-exit" unremovable="false" hidden="false" immutable="false" ID="n3"/>
    </folder>
    <folder ID="s4" hidden="false" immutable="false" name="Footer folder" type="footer" unremovable="false"/>
    <folder ID="s5" dlm:deleteAllowed="false" dlm:editAllowed="false" dlm:moveAllowed="false" hidden="false" immutable="false" name="Welcome" type="regular" unremovable="false">
      <structure-attribute>
          <name>externalId</name>
          <value>welcome</value>
      </structure-attribute>
      <folder ID="s6" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
        <structure-attribute>
          <name>width</name>
          <value>60%</value>
        </structure-attribute>
        <channel fname="email-preview-demo" unremovable="false" hidden="false" immutable="false" ID="n7" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
        <channel fname="weather" unremovable="false" hidden="false" immutable="false" ID="n8"/>
        <channel fname="pbookmarks" unremovable="false" hidden="false" immutable="false" ID="n9" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
      </folder>
      <folder ID="s10" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
        <structure-attribute>
          <name>width</name>
          <value>40%</value>
        </structure-attribute>
        <channel fname="calendar" unremovable="false" hidden="false" immutable="false" ID="n11"/>
      </folder>
    </folder>
  </folder>
</layout>

In the fragment-layout above there are some key attributes to take note of:

  1. username (ie., username="welcome-lo") - The username is the fragment owner. A fragment owner needs to be created for your new fragment layout (Add Local User Accounts).
  2. dlm:deleteAllowed (true or false) - This attribute defines if you want to allow the tab and/or portlet to be deleted by the user. If you want the tab and/or portlet to be required and not able to be deleted by the user then set the attribute to "false". 
  3. dlm:editAllowed (true or false) - This attribute defines if you want to allow the tab to be edited by the user. For example, if you do not want the user to add columns or edit the column widths then set the attribute to "false".
  4. dlm:moveAllowed (true or false) - This attribute defines if you want to allow the tab and/or portlet to be moved by the user. If you do not want the user to move the tab and/or portlet then set the attribute to "false".
  5. <structure-attribute> - These sections of the xml file define characteristics of the layout, such as the width of a column. 
  6. <channel> - These sections are used to define a portlet to be used inside a column. You can have multiple <channel> definitions in a column.
  7. fname - The unique id of a portlet. 
  8. <folder> - The folder elements define different sections of our fragment, such as a tab and each of the tab's columns. 
  9. ID - This is one of the "trickiest" xml nodes, which might result in you receiving a "uniqueness constraint" issue.
    1. XML node ID attribute uniqueness must be observed within a given *-fragment-layout.xmlfile.
    2. Furthermore, the integer portion of node IDs must be unique within a given *-fragment-layout.xml file.
    3. This example illustrates non-unique integer IDs that will result in an error because the integer portion of the ID of both folder node and channel node are '6':

      <folder ID="s6" hidden="false" immutable="true" name="Footer Second" type="footer-second" unremovable="true">
            <channel fname="page-bottom" unremovable="true" hidden="false"immutable="false" ID="n6"/>
      </folder> 

      Tweaking that so that the integer portion of the IDs differ solves the ID collision problem:

      <folder ID="s6" hidden="false" immutable="true" name="Footer Second" type="footer-second" unremovable="true">
            <channel fname="page-bottom" unremovable="true" hidden="false" immutable="false" ID="n8"/>
      </folder>

      Note that while these examples just show little snippets of what might be in fragment-layout.xml files, the identifier uniqueness constraints must be respected throughout each of those files individually, regardless of parent-child relationships of nodes within the file.

      Considerations in changing and re-using node IDs

      • End users may have stored directives describing their changes to their experience of fragment layouts, referencing fragment layout nodes by ID.
      • If you re-use a node ID in a changed version of a fragment-layout, prior directives will try to apply to the changed node.
      • In practice this mostly means don't re-use node IDs.
      • To facilitate avoiding re-use, it's a good idea to note previously used node IDs in a comment in the particular *-fragment-layout.xml file when removing them

       

Step 2: Creating our own fragment-layout

You can create your own fragment-layout by copying an existing fragment-layout file, such as the welcome-lo.fragment-layout.xml above.

For demonstration purposes, I am going to create a new fragment called "Home" and copy the existing welcome-lo.fragment-layout.xml to a new xml file named home-lo.fragment-layout.xml

  1. First, I am going to replace the welcome-lo to my new layout owner, home-lo (Add Local User Accounts).

    <layout xmlns:dlm="http://www.uportal.org/layout/dlm" script="classpath://org/jasig/portal/io/import-layout_v3-2.crn" username="home-lo">
  2. Next, I want to replace the name of my tab from "Welcome" to "Home"

    <folder ID="s5" dlm:deleteAllowed="false" dlm:editAllowed="false" dlm:moveAllowed="false" hidden="false" immutable="false" name="Home" type="regular" unremovable="false">
  3. Change the externalId so it relates to your new fragment. In this example, I will change "welcome" to "home".

    <structure-attribute>
       <name>externalId</name>
       <value>home</value>
    </structure-attribute>
  4. Below I want to revise my first column with a width of 50% and replace the portlets 

    <folder ID="s6" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
       <structure-attribute>
         <name>width</name>
         <value>50%</value>
       </structure-attribute>
       <!-- The fname is the value that was set in the portlet's definition -->
       <channel fname="notifications" unremovable="false" hidden="false" immutable="false" ID="n7" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
       <channel fname="news" unremovable="false" hidden="false" immutable="false" ID="n9" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
    </folder>
  5. Finally, in the second column I want to add an additional portlet and adjust the width to 50%

    <folder ID="s10" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
      <structure-attribute>
         <name>width</name>
         <value>50%</value>
      </structure-attribute>
      <channel fname="calendar" unremovable="false" hidden="false" immutable="false" ID="n11"/>
      <!-- Remember: use a unique id for the node. -->
      <channel fname="events" unremovable="false" hidden="false" immutable="false" ID="n12"/>
    </folder>

Multiple Tabs Example: You can create more than one tab per fragment layout. Below is an example where I have 2 tabs labeled "Welcome" and "Home":

<layout xmlns:dlm="http://www.uportal.org/layout/dlm" script="classpath://org/jasig/portal/io/import-layout_v3-2.crn" username="home-lo">
  <folder ID="s1" hidden="false" immutable="false" name="Root folder" type="root" unremovable="true">
    <folder ID="s2" hidden="true" immutable="true" name="Header folder" type="header" unremovable="true">
      <channel fname="fragment-admin-exit" unremovable="false" hidden="false" immutable="false" ID="n3"/>
    </folder>
    <folder ID="s4" hidden="false" immutable="false" name="Footer folder" type="footer" unremovable="false"/>
 
     <!-- WELCOME TAB -->
    <folder ID="s5" dlm:deleteAllowed="false" dlm:editAllowed="false" dlm:moveAllowed="false" hidden="false" immutable="false" name="Welcome" type="regular" unremovable="false">
      <structure-attribute>
          <name>externalId</name>
          <value>welcome</value>
      </structure-attribute>
      <folder ID="s6" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
        <structure-attribute>
          <name>width</name>
          <value>60%</value>
        </structure-attribute>
        <channel fname="email-preview-demo" unremovable="false" hidden="false" immutable="false" ID="n7" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
        <channel fname="weather" unremovable="false" hidden="false" immutable="false" ID="n8"/>
        <channel fname="pbookmarks" unremovable="false" hidden="false" immutable="false" ID="n9" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
      </folder>
      <folder ID="s10" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
        <structure-attribute>
          <name>width</name>
          <value>40%</value>
        </structure-attribute>
        <channel fname="calendar" unremovable="false" hidden="false" immutable="false" ID="n11"/>
      </folder>
    </folder>
   </folder>
 
   <!-- HOME TAB -->
   <folder ID="s12" dlm:deleteAllowed="false" dlm:editAllowed="false" dlm:moveAllowed="false" hidden="false" immutable="false" name="Home" type="regular" unremovable="false">
      <structure-attribute>
          <name>externalId</name>
          <value>home</value>
      </structure-attribute>
      <folder ID="s13" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
        <structure-attribute>
          <name>width</name>
          <value>50%</value>
        </structure-attribute>
        <channel fname="notifications" unremovable="false" hidden="false" immutable="false" ID="n14" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
        <channel fname="news" unremovable="false" hidden="false" immutable="false" ID="n15" dlm:moveAllowed="false" dlm:deleteAllowed="false"/>
      </folder>
      <folder ID="s16" hidden="false" immutable="false" name="Column" type="regular" unremovable="false">
        <structure-attribute>
          <name>width</name>
          <value>50%</value>
        </structure-attribute>
        <channel fname="calendar" unremovable="false" hidden="false" immutable="false" ID="n17"/>
        <channel fname="events" unremovable="false" hidden="false" immutable="false" ID="n18"/>
      </folder>
    </folder>
  </folder>
 
</layout>

 

Step 3: Import your new fragment-layout

Before importing your new fragment layout:

  1. Make sure your fragment owner exists. (Add Local User Accounts).
  2. Make sure you have imported a corresponding fragment definition for your new layout  (Define fragments)
  3. Make sure all of your portlet's fname values in your fragment layout exist
  4. Make sure all your fragment layout's node ID's are unique  (ex., ID="s6" and ID="n6" are NOT unique. Numerical values need to be unique.)

If all the steps above have been completed try importing your fragment using this command. (Replace the -Dfile path to match where your new fragment layout file is located)

If you are using different filter properties per environment, remember to append the -Denv with the environment you wish to import to (ex., -Denv=test)

ant data-import -Dfile=/path/to/your.fragment-layout.xml

 

 

Additional References

Having problems with these instructions?

Please send us feedback at uportal-user@lists.ja-sig.org

Add Feedback content box here.....