New Alfresco tutorial on working with a custom content model

UPDATE (2012): I’ve recently published a second edition of this tutorial that updates the original with Alfresco Share and CMIS.

UPDATE (2014): I’ve moved the tutorial and the source code to GitHub. The HTML version of the tutorial is here. It has been updated for Maven and AMPs.

I’ve written a new article (with sample files) that talks about how to extend Alfresco with your own content model and how to work with content that leverages that model via the Web Services API. All of the examples are written in Java but I do include one in PHP just for grins.

Most of the code is based on the Alfresco SDK Web Services sample code, but I’ve tweaked it here and there and I break it down into smaller chunks with commentary. I also think it is good to have one example to follow that takes you from designing the content model to implementing it to writing code that might leverage it.

More about the Alfresco Developer Series.

114 comments

  1. ashwini says:

    Hello Jeff,

    Would like to know below mentioned points

    1.Can we add the property values while uploading the content in share Repository as it is possible in Alfresco Explorer. Or we have to add property values using Edit Metadata option ?

    2.If we use list constraint as a mandatory, while uploading content even if we will not change/touch this property , it will take first value as a input and update the metadata. So it looses mandatory feature.

    Thanks in Advance!!
    Regards,
    Ashwini

  2. jpotts says:

    Ashwini,

    Alfresco Share sits on top of the exact same repository as the Explorer client. Metadata extraction (grabbing data from the content file and setting it as a property value in the content object’s metadata) is a function of the underlying repository, not of the client, so that means it works in both Explorer and Share.

    Mandatory properties have to be completed, so it doesn’t surprise me that it is getting set with the first item in the constraint. The mandatory feature isn’t lost–the property is still mandatory. It’s just getting filled in by default, which is probably not what you want. I’d have to play with this to see if there is a workaround–I’m not sure off the top of my head.

    Jeff

  3. ashwini says:

    Thanks for your clarification !!!

    Let me explain scenario for 1st question:

    In explorer

    1. While uploading content we have to select Content type.
    2. Once we select the content type on next window, we see the properties belogning to that content type where we can not continue till we will fill mandatory properties.Same applies for aspect.

    Which is not in case of Share repository.
    my observation

    1.When I have applied some aspect to the folder via Rule and which containts some mandatory property , and later when I uploaded content in that folder it got uploaded successfule without asking value for mandatory property.

    2.Here I have to go again to edit metadata property view of that content and then I have to enter values to the properties.
    now after going to edit metadata view if I will not enter value to mandatory aspect then submit button is disable. It becomes enable only when I enter the value.

    In this situation there might be chances that end user forget to to edit metadata.

    So how I can force user to fill the mandatory metadata while uploading content as like in explorer.

    For my 2nd question:

    I have just tried to some work around as below.

    1.I just kept 1st value of list constraint empty like
    In this case when I editted metadata it doesnot allow me to submit it without selecting value from the list.

    So now its working fine.

    Thanks in advance!!

    Ashwini

  4. alfdhar says:

    Hi Jeff,

    I have doubt on alfresco wcm Workflow

    I need to initiate WCM workflow programatically using java backed/webscript.I have tried both using service API but i coulnt make it..

    The following ways i tried :

    when we run this below code workflow initiates successfully but no content file is attaching in the workflow even though we give node reference of space or content

    To create package we need to give container reference, could you please guide what we need to replace the (“????????????????”) below

    NodeRef noderefff= new NodeRef(“????????????????”);
    NodeRef workflowNodeRef = workflowService.createPackage(noderefff);

    parameters.put(WCMWorkflowModel.PROP_FROM_PATH, “SampleWebProj–admin:/www”);
    parameters.put(WCMWorkflowModel.ASSOC_WEBPROJECT, “SampleWebProj”);
    parameters.put(WCMWorkflowModel.PROP_WEBAPP, “ROOT”);
    parameters.put(WCMWorkflowModel.PROP_LABEL, “from prog”);
    parameters.put(WorkflowModel.ASSOC_PACKAGE, workflowNodeRef);
    parameters.put(WorkflowModel.ASSOC_GROUP_ASSIGNEES, “Group_prod”);
    parameters.put(WorkflowModel.PROP_DESCRIPTION, “From Prod Group”);

    WorkflowPath wfPath = workflowService.startWorkflow(wid, parameters);
    System.out.println(“initiated successfully”);

    the second way:

    script:{

    //var nodeId = args.nodeid;

    var store=”Simple–admin”;
    var contentPath =”/www/avm_webapps/ROOT/eee.xml”;

    node = avm.lookupNode(store + “:” + contentPath);

    if (node == undefined)
    {
    status.code = 404;
    status.message = “Store not found.”;
    status.redirect = true;
    break script;
    }

    if (node != null){
    var workflowDefinition = workflow.getDefinitionByName(“jbpm$expeditewf:submit”);

    var workflowPackage = workflow.createPackage();
    workflowPackage.addNode(node);

    var workflowParameters = [];
    workflowParameters[“bpm:workflowDescription”] = “Please edit: ” + node.name;
    workflowParameters[“bpm:assignees”] = [people.getPerson(“admin”), people.getPerson(“dharan”)];
    var futureDate = new Date();
    futureDate.setDate(futureDate.getDate() + 7);
    workflowParameters[“bpm:workflowDueDate”] = futureDate;
    workflowParameters[“bpm:dueDate”] = futureDate;
    workflowParameters[“bpm:workflowPriority”] = 1;

    var workflowPath = workflowDefinition.startWorkflow(workflowPackage, workflowParameters);

    // This does *not* work, I get “bpm_assignees is not defined”
    // workflowPath.signal(null);

    // End the start task
    var tasks = workflowPath.getTasks();
    for (task in tasks)
    {
    tasks[task].endTask(null);
    }
    }
    }

    but when i access the URL ,
    the error says :

    Message: 09270027 Wrapped Exception (with status template): 09270017 Failed to execute script ‘/org/alfresco/sample/helloworkflow.get.js (in repository store workspace://SpacesStore/Company Home/Data Dictionary/Web Scripts)’: Node does not exist: avm://Simple–admin/-1;www;avm_webapps;ROOT;eee.xml

    Exception: org.alfresco.service.cmr.repository.InvalidNodeRefException – Node does not exist: avm://Simple–admin/-1;www;avm_webapps;ROOT;eee.xml

    this node reference exists when i check through alfresco webclient node browser

    please help me on this

  5. Davide says:

    Hi jpotts,
    I have a question about custom behaviour.
    I have a beaviour that calls a javascript file when a node is deleted (beforeDeleteNode).
    How can I get the username of the person who made the event that trigger the javascript file connected to my custom behaviour?
    I need it into my javascript file.
    I tried person.properties.userName but it is undefined.

    I hope you can help me.
    Davide

  6. jpotts says:

    Vanessa,

    The best way is to use a CMIS client library available at Apache Chemistry. Sites live in the sites folder and each site has a folder called “documentLibrary” which is the root of that site’s document library. So any files placed in that folder structure will show up in the site.

    This is true whether you are talking about Alfresco in the Cloud or Alfresco on-premise. But, be aware that the CMIS URL for each is different as well as how authentication is handled.

    Jeff

  7. Drew Mills says:

    Thanks for the tutorial! You mentioned a ‘best practice’ of defining a root type for our organization. In my company I’m being asked to provide cm for Accounting, Marketing, et al. Would it help for them to have their own sub-types? Or would that be too much too soon. I’m all about refactoring to fit current knowledge, but if custom content models are stiff & hard to change, I’d be okay with trying a little harder to get it right the first time.

  8. jpotts says:

    Drew,

    It is very common for departments to have their own sub-types. But you might want to find out how they want to use those first to make sure they are justified before adding them. Otherwise you just end up with more config to maintain for no good reason. Remember that it is easier to add later than to take away.

    Jeff

  9. Drew Mills says:

    Thanks for the quick response. While I’m on a roll, let me ask about another best practice you mention. You mention being conservative and still be prepared to re-init the repository several times. That worries me because not everyone in my company knows about, much less understands, the promise of CM. So if Marketing & Accounting get it and start praising it to the roof, and then the independent contractors want theirs, and then corp agents, later ….. Are you suggesting everytime someone comes on board wanting CM that we have to have a re-do? Or is the ‘be conservative’ part supposed to mitigate that problem?

  10. jpotts says:

    I meant that in development mode you will re-init your repo many times. Once you are in production you should never have to do that unless something goes horribly wrong.

    Sometimes, people give their users early access to an application they are building. Without clear expectations set, those users may begin to enter data they expect to be there when the app goes into production. So this is a heads-up that while you are in development mode, blowing away the repo is often the quickest way to make a major change. Clearly, that’s not an option once you are in production.

    Jeff

Comments are closed.