Help customising Diagram.DiagramSheet

Dear XWiki community,

I’m trying to add a custom object to diagram pages which essentially consists of three drop down list fields linked to properties of a custom class. However, when I add an instance of my class to the Diagram.DiagramTemplate document this seems to prevent anything from displaying when creating a new Diagram.

This is what I’ve done:
First I added a reference to a new sheet called “Content Manager.Code.Content Manager Reduced Edit Sheet” to “Diagram.DiagramSheet”

{{velocity}}
#if ($doc.getObject('Diagram.DiagramClass'))
  #if ($xcontext.action == 'edit')
    {{include reference="Diagram.DiagramEditSheet" /}}
  #else
    {{include reference="Diagram.DiagramViewSheet" /}}
  #end
#end
{{include reference="Content Manager.Code.Content Manager Reduced Edit Sheet" /}}
{{/velocity}}

Where “Content Manager.Code.Content Manager Reduced Edit Sheet” contains the following:

{{velocity}}
#set($discard = $doc.use('Content Manager.Code.Content Manager Reduced Class'))
#set($class = $doc.getObject('Content Manager.Code.Content Manager Reduced Class').xWikiClass)
outside loop
#foreach($prop in $class.properties)
  inside loop
  ## Only display the content when editing
  #if ($xcontext.action == 'edit')
    ; $prop.prettyName
    : $doc.display($prop.getName())
  #end
#end
{{/velocity}}

Added XWiki.ClassSheetBinding = “Diagram.DiagramSheet” to “Content Manager.Code.Content Manager Reduced Class”

Added an instance of “Content Manager.Code.Content Manager Reduced Class” to “Diagram.DiagramTemplate”.

This last action seems to stop anything from displaying when creating a new Diagram. I just get the title of the document in view mode.
Picture1

What am I missing?

As a more general case, is there a way I can add this class to every new document no matter what template is used? I would also like to add it to documents imported from Office but I can’t find the template that is used. This is important to me because I use the values of each of the properties in this class to determine the page rights.

Thank you,
Ben

Yes, by writing an event listener for DocumentCreatingEvent that adds the object you need to the created document. See http://platform.xwiki.org/xwiki/bin/view/DevGuide/WritingEventListenerTutorial .

Thanks Marius,
For my learning benefit, was my approach to the Diagram Extension correct?

It’s not recommended to modify extension pages because you can have problems when upgrading to a new version (your changes need to be merged with the changes from the new version). If there’s no other way then you should keep the changes to a minimum. So your approach was not the best. A better solution would be to:

  • change the class sheet binding of Diagram.DiagramClass (from object editor) to point to your custom sheet. And that’s the only change you make to the Diagram Application.
  • include Diagram.DiagramSheet in your custom sheet (using the include macro)
  • for the rest of your custom sheet:
    • call $doc.getObject(’…’, true) with a second parameter that ensures the object is created if it doesn’t exist. This way you avoid modifying the diagram template. And if you need some default values just set them before displaying the fields

    • use a hidden input to set the object policy to “updateOrCreate” in order to save your custom data along with the diagram data

      <input type="hidden" name="objectPolicy" value="updateOrCreate" />

Hope this helps,
Marius

Marius,

Thanks a lot for that explanation, very helpful!

I have tried both methods, while the specific Diagram solution works nicely, I’ve got a small problem using the add objects from an event listener option. I think the new object’s sheet is overwriting the original sheet. For example, when importing a word document, I can only see the new object. If I edit the page in wiki mode I can however see that the content has been imported. Similarly, if I add the new object to a previous page with other objects, I can see the original objects only in Object Edit mode.

I’ve been reading the Sheet Module Documentation but I don’t really understand it. Am I barking up the wrong tree?

Thanks,
Ben

I didn’t understood exactly what the problem is but if you have a page with two or more objects of different types and each type (xclass) has a different sheet associated, then only one of the sheets will be used (the first one found) to display that page. So if the object you’re adding with the event listener on every page has a sheet associated then it will break the pages that already have a sheet (because they have already an object with a sheet associated). In this case you should remove the sheet associated from the object you add with the event listener and manage the display from the skin or from an UI extension point [1] (I assume you want to display something related to this object on each page).

Hope this helps,
Marius

[1] http://extensions.xwiki.org/xwiki/bin/view/Extension/UIExtension+Module

Thanks Marius,

Yes, that’s exactly what I want to do. I want to display a series of form fields associated with the object as well as the client and server side validation that goes with them. Currently this is all in the sheet associated with my new xclass.

I’ll see if I can figure out how to move it all into a UI extension point.

Regards,
Ben