XWiki Data Model

XWiki exposes a flexible data model that can be leveraged at the presentation level. Combined with its powerful presentation level scripting capabilities, XWiki Enterprise data model can be used for building simple to complex Web applications with little or no need to access the XWiki core. In other words, it is possible to build custom applications through the XWiki web interface, without having to compile, package and deploy software components.

XWiki Classes

An XWiki class defines a unique type of object, i.e. the properties an object can have. When defining a custom class, the application may need to create one or many objects, or instances of that class. A class is attached to a page and there can be at most one class per page. The class name is the name of the page containing that class.

Create a Class

The Class Editor Wizard has been developed for creating classes and is available by navigating to "XWiki.XWikiClasses". To create a class, enter the title of the page storing it and the location, then click on "Create this Class".

CreateClass.png

The location is the place in the page hierarchy where the new class page will be created. By default, the parent is set to "XWiki" but you can easily change it by clicking the blue editing pen icon, which will load 2 more fields:

  • Parent - the parent of the new page; right after starting to type the name, the suggest feature will display the list of all the occurrences, so that you can select from them. To collapse the suggestion results, just click on "hide suggestions". As soon as you select a parent, the breadcrumb is updated in order to reflect the location of the page in the reference hierarchy.
By leaving this field empty, you will create a top-level page which is the equivalent of an old space home page. 
  • Name - the name of the page i.e. the string appearing in the URL.

    ClassLocationForm.png

Another way of selecting a location is to click on the blue hierarchy icon

ClassLocationIcon.png

and select a space from the document tree or to search it using the integrated finder.

DocumentTree.png

After clicking on "Create this Class", you will be redirected to the class page in "Wiki" edit mode which will contain the following code:

{{velocity}}
## Replace the default space with the space where you want your pages to be created.
## Replace the default parent with the one of your choice and save the page.
##
#set($defaultSpace = $doc.space)
#set($defaultParent = $doc.fullName)
{{/velocity}}

Change the default space which is the current space with the name of the space where you want your pages to be created in, as the commented instructions in the page code suggest.

#set($defaultSpace = 'XWiki')

You can also change the default parent of the new pages by replacing the value of the $defaultParent parameter with the full name of your chosen page. Thus, the corresponding code should look like this:

#set($defaultParent = 'XWiki.WebHome')

Click on the "Save & View" button to finalize the creation of the "Employee" class.

ClassCreated.png

Add Properties to the Class

Below the page title, you should see the words "The class does not have any properties yet. You can use the class editor to define them".

Properties are characteristics that an object can have. In a class definition, the properties define the data fields that each unique instance of the class can have values for. XWiki currently supports the following kinds of properties (or data types):

 Property type Description
NumberAllows to store and display Numbers of type Integer, Long, Float or Double.
StringAllows to store and display one-line text.
Text AreaAllows to store and display large text fields, both text and Wysiwyg.
PasswordAllows to store password fields which can be encrypted or hashed. 
Boolean Allows to store and display Boolean values which can be displayed as select or check-box fields. The possible values cans be either "yes/no" or "1/0". 
EmailAllows to store email fields that can be obfuscated at display time, provided you make this setting in the wiki administration page.
Static ListAllows to store and display single-select or multi-select fields that can be displayed as select, check-box, radio or suggest fields. The possible values of static list fields are configured in the field definition.
Database List Allows to store and display single-select or multi-select fields that can be displayed as select, check-box, radio or suggest fields. The possible values of static list fields are taken other XWiki data using a Hibernate query.
Database Tree ListBehaves the same as the Database List property, with the addition that the data can be displayed as a tree, using the Yahoo Javascript Tree library. 
Date Allows to store and display Date or Datetime values using a Date Picker.
List of UsersAllows to store and display single-select or multi-select users with an User Picker.
List of GroupsAllows to store and display single-select or multi-select groups using a Group Picker.
TimezoneAllows to display and edit Time Zones.
Page (the equivalent of "List of Pages")Behaves just like a String field but it stores XWiki page names. 
Access Right LevelsAllows to store and display the access rights levels as select, check-box, radio or suggest fields.
Computed pseudo-fieldAllows to create a pseudo field for which the display can be configured using a script and it allows to combine other fields together.

Click on the "class editor" link to edit the "Employee" class in "Class" mode. Note that the breadcrumb is "Home » XWiki » EmployeeClass".

EditNewClass.png

Now you need to add 2 "String" properties corresponding to the first name and last name of each employee and one "Text Area" property for the address. To do so, enter the name of the property in the "Add new property" text box, choose its type from the "Type" drop-down box then click on the "ADD" button.

AddProperty.png

Once you are done adding and configuring the properties, click on "Save & View". Your class page should look like this:

AddProperty2.png

Objects

Objects are unique instances of a class with unique values defined for each of the properties that make up the class. An object is attached to a specific page and each page can have multiple objects. By using objects, structured information is inserted into the wiki, while in a traditional wiki it is only possible to enter unstructured information (plain text).

Sheets

A sheet is an XWiki page determining how to display the objects, the title and the content of other XWiki pages. The title and the content are rendered in the context of the displayed page. Note that a sheet is not responsible for the page layout.

Create the Class Sheet

The class sheet displays the data stored in an object attached to an XWiki page. To control the display, you need

  • to bind the XWiki class defining the object type to a sheet by adding a "XWiki.ClassSheetBinding" object to the class page 
  • to set the sheet reference as the value of the "Sheet" property.

Click on "Create the sheet",

CreateDocumentSheet.png

then click on "Bind the sheet to the class" to add an "XWiki.ClassSheetBinding" object to the sheet page. 

ClassSheet.png

If you then click on "View the sheet page (XWiki / Employees Sheet)" and edit the page in "Wiki" mode, you will see the following code:

{{velocity}}
## You can modify this page to customize the presentation of your object.
## At first you should keep the default presentation and just save the page.

#set($class = $doc.getObject('XWiki.EmployeesClass').xWikiClass)
#foreach($prop in $class.properties)
  ; $prop.prettyName
  : $doc.display($prop.getName())
#end
{{/velocity}}

If you navigate back to the class page and edit it in "Objects" mode, you will see the attached "XWiki.ClassSheetBinding" object for which the value of the "Sheet" property is "EmployeesSheet". So "XWiki.EmployeesSheet" will be applied each time a wiki page contains an "XWiki.EmployeesClass" object.

ClassSheetBindingObject.png

Document Sheets

As you may have already noticed, the "XWiki.EmployeesClass" page contains a second object, "XWiki.DocumentSheetBinding". A document sheet is useful when you wish to display a page differently than the rest of its type. In previous versions of XWiki you would have overridden the class sheet. Now you can bind your page to a custom sheet, by adding an "XWiki.DocumentSheetBinding" object and by setting the custom sheet reference as value of the "Sheet" property.

DocumentSheetBindingObject.png

You may leave the "Sheet" property blank, which means that the page will be bind to itself, thus will control its own display.

Create the Class Template

Navigate back to the class page and click on the "Create the template" button. The Authoring Template will be automatically created but it won't have  an "XWiki.EmployeeClass" object attached. To attach an object, click on "Add a Employees object to the template".

ClassTemplate.png

If you then click on "View the template page (XWiki / Employees Template)" and edit the page in "Objects" mode, you will see the "XWiki.EmployeeClass" object attached:

ClassObjectInTemplate.png

To create Employees instances, navigate back to the class page and search for the "Create a new page" section. Next, fill in the title, choose a parent and a page name, then click on "Create this page".

CreateDocument.png

The new form will open in "Inline" mode so that you can fill in the first name, last name and address. Click on "Save & View" to create your first Employee form.

EmployeeForm.png

Create New XClass Property Types

The first step is to create a class which extends the PropertyClass. The code below creates the "External Image" property type used for storing URLs to external images:

public class ExternalImageClass extends PropertyClass
{
  /**
     * Default constructor.
     */

  public ExternalImageClass()
  {
      // Specify the default name and pretty name of this XClass property. They can be overwritten from the class
      // editor when adding a property of this type to an XClass.
      super("externalImage", "External Image", null);
  }

  @Override
  public BaseProperty fromString(String value)
  {
        BaseProperty property = newProperty();
      // The stored value can be different than the value set by the user. You can do the needed transformations here.
      // In our case the value is an image URL so we keep it as it is. The reverse transformation, from the stored
      // value to the user friendly value, can be done in the property displayer.
      property.setValue(value);
      return property;
  }

  @Override
  public BaseProperty newProperty()
  {
      // The value of this XClass property is stored as a String. You have to use raw types here like StringProperty
      // because they are mapped to the database. Adding a new raw type implies modifying the Hibernate mapping and is
      // not the subject of this tutorial.
      BaseProperty property = new StringProperty();
        property.setName(getName());
      return property;
  }
}

The raw property type used for storing our new property type in the database is StringProperty. The other available raw property types are:

The corresponding Hibernate mappings are detailed in the XWiki Database Schema overview.

The second step is to create a provider class which implements PropertyClassProvider. A provider can also define the list of meta properties that control the way the property value is parsed or how it is displayed. Most importantly, the values of the meta properties are shared by all the class instances. 

@Component
// Note that the component hint matches the name of the property class without the "Class" suffix. The reason is that
// the component hint must match the value returned by the #getClassType() method of your property class, which by
// default strips the "Class" suffix from the Java class name of your property class. If you want to use a different
// hint that doesn't follow this naming convention you need to override #getClassType().
@Named("ExternalImage")
@Singleton
public class ExternalImageClassProvider implements PropertyClassProvider
{
  @Override
  public PropertyClassInterface getInstance()
  {
      return new ExternalImageClass();
  }

  @Override
  public PropertyMetaClassInterface getDefinition()
  {
        PropertyMetaClass definition = new PropertyMetaClass();
      // This text will appear in the drop down list of property types to choose from in the class editor.
      definition.setPrettyName("External Image");
        definition.setName(getClass().getAnnotation(Named.class).value());

      // Add a meta property that will allows us to specify a CSS class name for the image HTML element.
      // NOTE: We define meta properties using XClass property types. This means for instance that you can define meta
      // properties of External Image type or whatever XClass property type you create.
      StringClass styleName = new StringClass();
        styleName.setName("styleName");
        styleName.setPrettyName("Style Name");
        definition.safeput(styleName.getName(), styleName);

      // The alternative text is required for a valid image HTML element so we add a meta property for it.
      StringClass placeholder = new StringClass();
        placeholder.setName("placeholder");
        placeholder.setPrettyName("Alternative Text");
        definition.safeput(placeholder.getName(), placeholder);

      // Add more meta properties here.

      return definition;
  }
}

Finally, you need to register the new component by declaring the Component implementation in a META-INF/components.txt file:

org.xwiki.example.internal.ExternalImageClassProvider

For more details regarding how to register, initialize or log components, go to the Component Module documentation page.

To use the new property type, build you Maven project, copy the Jar file in the "WEB-INF/lib" folder and restart the server. Next, create an XWiki class that has the property type "ExternalImage" and a class sheet which will display the property value. Finally, attach an "ExternalImage" object to a new wiki page and save it.

To improve the display of the new property type, you can create a custom displayer as explained here.

           

Search this space