Learn how to create a custom content model using theAlfresco SDK.Defining and implementing a custom content model for a specific domain is one of the first thing you need to do in mostdigital transformation projects.
See alsoContent Model extension point.
You can create new content model using the Alfresco SDK.
Use the Alfresco SDK to build and deploy a new content model. In this tutorial you will see how to implement a bootstrap deployment.
Create a newAll-In-One SDK Project.
The new project already contains a sample model that you can change to suit your needs.
In your IDE, examine the fileaio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/context/bootstrap-context.xml.
This is the Spring Bean configuration file for your new content model:
<bean parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap"> <property name="models"> <list> <value>alfresco/module/${project.artifactId}/model/content-model.xml</value> <value>alfresco/module/${project.artifactId}/model/workflow-model.xml</value> </list> </property> <property name="labels"> <list> <!-- Bootstrap Resource Bundles for the content model types, aspects, properties etc --> <value>alfresco/module/${project.artifactId}/messages/content-model</value> </list> </property></bean>This Spring bean links to your model file. It causes the model to extend the existing model, rather than replace it. The bean definition indicates that this model is to use a bootstrap deployment, which will require a server restart in order to take effect.
In your IDE, open the fileaio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/model/content-model.xml.
This is your new custom model. Replace the contents with the following text:
<?xml version="1.0" encoding="UTF-8"?> <!-- Definition of new Model --> <!-- The important part here is the name - Note: the use of the my: namespace which is defined further on in the document --><model name="my:contentModel" xmlns="http://www.alfresco.org/model/dictionary/1.0"> <!-- Optional meta-data about the model --> <description>Example Custom Model</description> <author>Alfresco Documentation Team</author> <version>1.0</version> <!-- Imports are required to allow references to definitions in other models --> <imports> <!-- Import Alfresco Dictionary Definitions --> <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/> <!-- Import Alfresco Content Domain Model Definitions --> <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/> </imports> <!-- Introduction of new namespaces defined by this model --> <!-- NOTE: The following namespace my.new.model should be changed to reflect your own namespace --> <namespaces> <namespace uri="http://www.mycompany.com/model/content/1.0" prefix="my"/> </namespaces> <types> <!-- Enterprise-wide generic document type --> <type name="my:doc"> <title>MyCompany Generic Document</title> <parent>cm:content</parent> </type> <type name="my:marketingDoc"> <title>MyCompany Marketing Document</title> <parent>my:doc</parent> </type> <type name="my:whitepaper"> <title>MyCompany Whitepaper</title> <parent>my:marketingDoc</parent> </type> </types></model>This is the custom model that will extend the existing core model framework. The model adds three new types of document, a generic company document, a marketing document, and a whitepaper.
To build and run the project seeworking with an AIO project.
Check for any errors in the log file.
Log into Share as admin. Check that login works as expected.
You have seen how to create a Maven archetype for your content model and deploy it in bootstrap mode.
In this tutorial you create some content of one of the custom types defined in your custom model. This is done using a simple web script so that the type can be conveniently specified.
It is assumed that you are familiar with web scripts. If not, you might want to look at theRepo Web Script Extension Point.
Using the model defined in theprevious section, you run a simple web script to create content of typemy:whitepaper.
In your IDE, navigate to theaio/aio-platform-jar/src/main/resources/alfresco/extension/templates/webscripts folder.
In the next part of this tutorial, you create three files for the test web script,modeltest.get.desc.xml,modeltest.get.html.ftl, andmodeltest.get.js in thewebscripts folder.
In thewebscripts folder, create the web script description file,modeltest.get.desc.xml, with the following content:
<webscript> <shortname>Model test</shortname> <family>Tutorials</family> <description>Creates content of a custom type</description> <url>/modeltest/{documentName}</url> <format default="html">extension</format> <authentication>user</authentication></webscript>You can specify the name of the document to create - it is passed as a parameter via the URL. To keep things simple the type of the content is hardcoded in the JavaScript code to be of typemy:whitepaper.
In thewebscripts folder, create a new JavaScript file,modeltest.get.js, with the following content:
var contentType = "my:whitepaper";var documentName = url.templateArgs.documentName; var document = companyhome.createNode(documentName, contentType); if (document != null){model.document = document;model.msg = "Created OK!";}else {model.msg = "Failed to create document!";}The web script simply creates a new document of type whitepaper. If the operation fails an error message is recorded and this will be displayed by the corresponding template file. If the operation is successful, the reference to the created document itself is stored in the model for use by the template.
In thewebscripts folder, create a new FreeMarker template file,modeltest.get.html.ftl, with the following contents:
<p>Creating the following document:</p><ul><li>${document.name}</li><li>${document.type}</li></ul><b>${msg}</b>The template file simply extracts the name and type from the document object and displays it, along with the message passed from the JavaScript code.
Point your web browser at the web scripts index athttp://localhost:8080/alfresco/service/index.
You can clickBrowse ‘Tutorials’ Web Scripts to view your web script and confirm that it is indeed present.
Run the web script by specifying a URL such as the following (you can change the name of the document if you wish):
http://localhost:8080/alfresco/service/modeltest/MyWhitepaperYou will see a page displayed such as the following:
Creating the following document: MyWhitepaper {http://www.mycompany.com/model/content/1.0}whitepaper Created OK!Note that the fully qualified type name is as specified in your custom model file. If you try to create a content of a type that does not exist you will get an error.
Run the web script a few times to create several documents.
Log into Share. You can use the Node Browser to search for nodes of the custom type.
On the main Share menu selectAdmin Tools and then from the left-handTools Menu selectNode Browser.
The Node Browser interface will be displayed.
In the search box type the following query:
TYPE:"{http://www.mycompany.com/model/content/1.0}whitepaper"Click theSearch button.
A list of nodes with the specified type,my:whitepaper, will be returned.
You have created some content of custom typemy:whitepaper in the repository. You then used the Node Browser to find content only of this custom type.
In this tutorial you add a custom property to your model.
Complete the previous tutorials in this series before attempting this one.
Using the model defined in anearlier section you will extend it to use a custom property. Any piece of content has a number of properties inherited from its parent, such ascm:content. These include properties such as name, title, and description. It is possible to add custom properties, effectively extending the parent types property list. In this tutorial you add aproduct property to a piece of content. This property will also have a constraint. This constraint will mean that the product type has to be selected from a list of pre-defined products. This allows the content to be more accurately catalogued and searched for. You will also run a query to find content using a type and property.
In your IDE, open the fileaio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/model/content-model.xml and load it into the editor.
Replace the content of the file with the following:
<?xml version="1.0" encoding="UTF-8"?> <!-- Definition of new Model --> <!-- The important part here is the name - Note: the use of the my: namespace which is defined further on in the document --><model name="my:contentModel" xmlns="http://www.alfresco.org/model/dictionary/1.0"> <!-- Optional meta-data about the model --><description>Example Custom Model</description><author>Alfresco Documentation Team</author><version>1.0</version> <!-- Imports are required to allow references to definitions in other models --><imports><!-- Import Alfresco Dictionary Definitions --><import uri="http://www.alfresco.org/model/dictionary/1.0"prefix="d" /><!-- Import Alfresco Content Domain Model Definitions --><import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" /></imports> <!-- Introduction of new namespaces defined by this model --><!-- NOTE: The following namespace my.new.model should be changed to reflect your own namespace --><namespaces><namespace uri="http://www.mycompany.com/model/content/1.0"prefix="my" /></namespaces> <constraints><constraint name="my:productListConstraint" type="LIST"><parameter name="allowedValues"><list><value>Foobar Widget</value><value>Flux Capacitor</value><value>Big Bold App</value></list></parameter></constraint></constraints> <types><!-- Enterprise-wide generic document type --><type name="my:doc"><title>MyCompany Generic Document</title><parent>cm:content</parent></type><type name="my:marketingDoc"><title>MyCompany Marketing Document</title><parent>my:doc</parent><properties><property name="my:product"><type>d:text</type><multiple>true</multiple><constraints><constraint ref="my:productListConstraint" /></constraints></property></properties></type><type name="my:whitepaper"><title>MyCompany Whitepaper</title><parent>my:marketingDoc</parent></type></types></model>This model is an extended version of the previously used model. It adds a new property to the MyCompany Marketing Document type. A constraint is also defined for this property to restrict its value to one of three possible product names. The new property itself is calledmy:product. Note that although the property is added to the typemy:marketingDoc, the property will also apply to content of the typemy:whitepaper as whitepaper has the marketing document as its parent type. In other words properties are inherited from the parent content type.
To build and restart the project seeworking with an AIO project.
Check that Content Services has restarted without errors (either through checking the logs or logging into Share).
If you check a piece of content you created previously in Share, you can see that the custom property is automatically displayed. In the next tutorial you customize this information.
For a whitepaper created earlier apply the valueFlux Capacitor to itsproduct property.
As before locate the Node Browser.
Set the Node Browser’s query language tolucene.
In the Node Browser’s search box type the following query:
@my\:product:"Flux Capacitor"ClickSearch.
Any documents with themy:product property set toFlux Capacitor will be returned in the search results.
You have created and deployed a custom model with a custom property and constraint. You have applied a custom property and seen how to search for content with a particular property value.
Alfresco Share needs to be configured to display custom types. It is also possible to configure Share to display properties in a customized way (the default is to display all properties).
This tutorial assumes you have completed the preceding tutorials in the series.
Although you have deployed a custom model, created content of the custom type, search for it, and applied a custom property, it is necessary to carry out some configuration in order to allow Share to take advantage of these new types and properties. The custom configuration will be done in the usual file for custom Share configurations,share-config-custom.xml.
Your SDK project has a sample ataio/aio-share-jar/src/main/resources/META-INF/share-config-custom.xml.
Replace everything inside the<alfresco-config> tag with the following configuration:
<!-- Form customization for whitepaper --><config evaluator="model-type" condition="my:whitepaper"><forms><form><field-visibility><show /><show /><show force="true" /><show force="true" /></field-visibility></form></forms></config> <config evaluator="node-type" condition="my:whitepaper"><forms><form><field-visibility><show /><show /><show force="true" /><show force="true" /></field-visibility></form></forms></config><!-- End of Form customization for whitepaper -->This piece of configuration indicates that Share should display four properties for the typemy:whitepaper:
cm:namemy:productcm:titlecm:descriptionOf course any property supported by the type could be chosen to be displayed here.
Now define the custom types. After the config element you just created, add the following configuration:
<config evaluator="string-compare" condition="DocumentLibrary"> <!-- Used by "Manage Rules" -> "Specialise type" action. If a type has been specified without a title element in the content model, or you need to support multiple languages, then an i18n file is needed on the Repo AMP/JAR extension side for the type to be visible when creating rules: custom_customModel.type.custom_mytype.title=My SubType Used by the "Change Type" action. For the type to have a localised label add relevant i18n string(s) in a Share AMP/JAR extension: type.custom_mytype=My SubType Define valid subtypes using the following example: <type name="cm:content"> <subtype name="custom:mytype" /> </type> --> <types> <type name="cm:content"> <!-- Custom sub-type added for whitepapers --> <subtype name="my:whitepaper" /> </type> <type name="cm:folder"> </type> <type name="trx:transferTarget"> <subtype name="trx:fileTransferTarget" /> </type> </types></config>You will notice you have just added a new sub-type ofcm:content,my:whitepaper. You could also have added the other custom types you created in here. When you create new content you will be able to use theChange Type action in Share to specify the custom typemy:whitepaper.
Now add the string to display in Share for the whitepaper type. Open the fileaio/aio-share-jar/src/main/resources/alfresco/web-extension/messages/aio-share-jar.properties in your editor.
Add a line for your custom type (or types) at the end of the file:
type.my_whitepaper=WhitepaperTo build and restart the project seeworking with an AIO project.
Log into Share.
Create a new piece of content using the Share user interface.
Select the piece of content.
Notice that there will be numerous properties displayed for the content.
UnderDocument Actions selectChange Type. From this list selectWhitepaper.
Note that only four properties will be displayed for this content type.
Now underDocument Actions selectEdit Properties.
For themy:product property selectFlux Capacitor.
ClickSave.
You have seen how to configure Share to support custom types and properties.
In this tutorial you add an association to your model. An association is a logical link between content types, it is a way of connecting related content.
Complete the previous tutorials in this series before attempting this one.
In your IDE, open the fileaio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/model/content-model.xml and load it into the editor.
Change the MyCompany generic document type to the following code:
<!-- Enterprise-wide generic document type --><type name="my:doc"> <title>MyCompany Generic Document</title> <parent>cm:content</parent> <associations> <association name="my:relatedDocuments"> <title>Related Documents</title> <source> <mandatory>false</mandatory> <many>true</many> </source> <target> <class>my:doc</class> <mandatory>false</mandatory> <many>true</many> </target> </association> </associations></type>To build and restart the project seeworking with an AIO project.
The association has been created and deployed.
In this tutorial you add an aspect to your model. An aspect provides an additional way to classify content.
Complete the previous tutorials in this series before attempting this one.
In your IDE, open the fileaio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/model/content-model.xml and load it into the editor.
Add the following after thetypes section:
<aspects> <aspect name="my:publishToWeb"> <title>MyCompany Website</title> <properties> <property name="my:publishedDate"> <type>d:date</type> </property> <property name="my:isActive"> <type>d:boolean</type> <default>false</default> </property> </properties> </aspect> <aspect name="my:clientRelated"> <title>MyCompany Client Metadata</title> <properties> <property name="my:clientName"> <type>d:text</type> <mandatory>true</mandatory> </property> <property name="my:projectName"> <type>d:text</type> <mandatory>false</mandatory> </property> </properties> </aspect></aspects>In the next section of this tutorial you add some configuration to Share to ensure that the aspect appears in the Share user interface.
Open the fileaio/aio-share-jar/src/main/resources/META-INF/share-config-custom.xml in your editor.
Find the following line in the file:
<config evaluator="string-compare" condition="DocumentLibrary">Add a list of aspects add any you wish to be able to apply to a document using the ShareManage Aspects action. In this case, add the following text:
<!-- Used by "Manage Rules" -> "Add aspect" action. If an aspect has been specified without a title element in the content model, or you need to support multiple languages, then an i18n file is needed on the Repo AMP/JAR extension side for the aspect to be visible when creating rules: custom_customModel.aspect.custom_myaspect.title=My Aspect Used by the "Manage Aspects" action. For the aspect to have a localised label add relevant i18n string(s) in a Share AMP/JAR extension: aspect.custom_myaspect=My Aspect --> <aspects> <!-- Aspects that a user can see --> <visible> <!-- custom aspects --> <aspect name="my:publishToWeb" /> <aspect name="my:clientRelated" /> </visible> <!-- Aspects that a user can add. Same as "visible" if left empty --> <addable> </addable> <!-- Aspects that a user can remove. Same as "visible" if left empty --> <removeable> </removeable></aspects>Edit the fileaio/aio-share-jar/src/main/resources/alfresco/web-extension/messages/aio-share-jar.properties to add suitable strings for the aspects. For example, in the aspects section you can add:
aspect.my_publishToWeb=Web Publishableaspect.my_clientRelated=Client RelatedLog back into Share and create a new piece of content. Add the typeWhitepaper to the content.
Once the type has been changed clickManage Aspects. You can now apply the aspectsWeb Publishable andClient Related to the content.
The aspect has been created and deployed, along with suitable Share configurations.
In this tutorial you add a mandatory aspect to your model.
Complete the previous tutorials in this series before attempting this one.
You create a mandatory aspect and add it to your model. All content of the specified type (and child types) will have the mandatory aspect automatically applied when the content is created and added to the repository. The mandatory aspect you add is calledcm:generalClassifiable.
In your IDE, open the fileaio/aio-platform-jar/src/main/resources/alfresco/module/aio-platform-jar/model/content-model.xml and load it into the editor.
Find the typemy:doc (the parent custom type). After the type’s associations add the following mandatory aspect:
<mandatory-aspects> <aspect>cm:generalclassifiable</aspect> </mandatory-aspects>To build and restart the project so the modified model is picked up seeworking with an AIO project.
Log back into Share and create a new piece of content. Add the typeWhitepaper to the content.
Once the type has been changed clickManage Aspects.
You can see that the mandatory aspect,Classifiable has been applied by default.
You have seen how to add a mandatory aspect to your model.