Creating New XClass Property Types

Version 11.1 by Marius Dumitru Florea on 2012/11/27

Contents

This tutorial guides you through the creation of a new XClass property type, which is a way to extend the class editor.

This tutorial applies to XWiki version 4.3M2 and above. Don't try on older versions.

You should start by reading the XWiki Data Model to understand XWiki Classes, Objects and Properties, and then the Writing XWiki components tutorial because new property types are implemented as components.

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;
   }
}
@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;
   }
}
org.xwiki.example.internal.ExternalImageClassProvider
{{velocity}}
; $doc.displayPrettyName('screenshot', false, false)
: $doc.display('screenshot')
{{/velocity}}
#if ($type == 'edit')
  #set($id = $escapetool.xml("${prefix}${name}"))
  <input type="text" id="$!id" name="$!id" value="$!escapetool.xml($value)" />
#elseif ($type == 'view')
  <img src="$escapetool.xml($value)" alt="$escapetool.xml($field.getProperty('placeholder').value)"
    class="$escapetool.xml($field.getProperty('styleName').value)" />
#else
  ## In order for the custom displayer to be taken into account, the result of its evaluation with an unknown display
  ## mode must not be empty. Let's output something.
  Unknown display mode.
#end
Tags:
   

Get Connected