cancel
Showing results for 
Search instead for 
Did you mean: 

'Add new comment' form retrieval

nicolabeghin
Champ in-the-making
Champ in-the-making
Hi everyone
I'm integrating Alfresco in a WebDynPro java in a SAP system.
I want to manage docs comments in alfresco (for many reasons not in the SAP system).
I've already developed a webscript to get HTML-formatted comments, starting from the existing org/alfresco/repository/comments/comments.get (JSON-based), but I'm unable to get a form to add new comments (I don't want to send SOAP/REST request from the WebDynPro because I want full-featured comments with HTML markup).

Any ideas if this is feasible? I need to understand if it's possible to get just the form markup OR a single page with the only possibility of adding new comments

[EDIT] I think org/alfresco/components/form/form.get is the way to go, I'm inspecting the issue to understand what .ftl needs to be included to make it work completely

Thanks, nicola
21 REPLIES 21

nicolabeghin
Champ in-the-making
Champ in-the-making
Even with an EMPTY AlfrescoUtil I get the same error. Seems like something is happening behing the scenes. Is a NodeRef always created??

var this_AlfrescoUtil = this;
var AlfrescoUtil =
{};

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
So if I understand you correctly, if you remove the import of alfresco-util.js the webscript can be called successfully (i.e. executes some test code), but as soon as you have the import, even if AlfrescoUtil does not contain code, you get that error?

I think you should try writing your import using classpath notation as in:
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/cmis/lib/read.lib.js">

nicolabeghin
Champ in-the-making
Champ in-the-making
That's right, when I import alfresco-util.js (even without any content in it) I get the aforementioned error.. (even if I remove the include of the doclib library).
Do you know if some other script/procedure is automatically called?

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
One thing in your previous posts that I overlooked: You are loading the webscript files as nodes in the datadictionary/webscripts dir, right?
I,ve never done that, but I could imagine that the imports should be reformulated to include the noderef of the file you are trying to import, rather than its filename. Then the error message would also make sense: it's simply expecting a noderef.

Once again, I'm just guessing. Maybe there's some useful info in the wiki on this, but you could also just give it a try.

nicolabeghin
Champ in-the-making
Champ in-the-making
Thanks Arnold
I got quite near the end, here's my code in case it can be useful for anyone else.

URL reference http://127.0.0.1:8080/alfresco/service/com/companyx/components/comments/list?nodeRef=workspace://Spa...

comments-list.get.js

<import resource="workspace://SpacesStore/434481d2-27d5-4966-98ff-59729b494168">

function getActivityParameters(nodeRef, defaultValue)
{
   var cm = "{http://www.alfresco.org/model/content/1.0}",
      metadata = AlfrescoUtil.getMetaData(nodeRef, {});
   if (metadata.properties)
   {
      if (model.activityType == "document")
      {
         return (
         {
            itemTitle: metadata.properties[cm + 'title'] || metadata.properties[cm + 'name'],
            page: 'document-details',
            pageParams:
            {
               nodeRef: metadata.nodeRef
            }
         });
      }
   }
   return defaultValue;
}

function main()
{
   AlfrescoUtil.param('nodeRef', null);
   AlfrescoUtil.param('site', null);
   AlfrescoUtil.param('maxItems', 10);
//   AlfrescoUtil.param('activityType', null);
   model.maxItems=10;
   model.locale='it';
   if (model.nodeRef && model.site) {
      // var documentDetails = AlfrescoUtil.getNodeDetails(model.nodeRef, model.site);
//      if (documentDetails) {
//         var activityParameters = getActivityParameters(model.nodeRef, null);
       //  if (activityParameters) model.activityParameterJSON = jsonUtils.toJSONString(activityParameters);
//      }
   }
   else {
      status.code=404;
      status.message='Unable to get nodeRef or site parameter';
      status.redirect=true;
   }
}

main();

alfresco-util.js

<import resource="workspace://SpacesStore/d4564463-8fba-4ca2-a761-d491bd9a4c08">

var this_AlfrescoUtil = this;

var AlfrescoUtil =
{

   error: function error(code, message, redirect)
   {
      status.code = arguments.length > 0 ? 500 : code;
      status.message = message || 'An error occured';
      status.redirect = arguments.length > 2 ? redirect : true;
      throw new Error(message);
   },

   /**
    * Looks for a parameter in a "safe" way that works in all "environments".
    * Meaning it will look in "page" and "template" if they do exist and not fail /crash if they don't.
    *
    * Looks for an argument in the following order/locations:
    * 1. args[name]
    * 2. page.url.args[name]       
    * 3. page.url.templateArgs[name]
    * 4. template.properties[name]
    * 5. a) if defaultValue has been passed in that is used
    *    b) otherwise the parameter is treated as required and an error is thrown
    *
    * @param name
    * @param defaultValue
    * @return the value for the parameter
    */
   param: function param(name, defaultValue)
   {
      if (args[name]!==undefined) model[name]=args[name];
      else if (defaultValue) model[name]=defaultValue;
      else AlfrescoUtil.error(400, 'Parameter "' + name+ '" is missing.', true);
      return model[name];
   },
  
   getRootNode: function getRootNode()
   {
      var rootNode = "alfresco://company/home",
         repoConfig = config.scoped["RepositoryLibrary"]["root-node"];

      if (repoConfig !== null)
      {
         rootNode = repoConfig.value;
      }
      return rootNode;
   },
   
   getNodeDetails: function getNodeDetails(nodeRef, site, options)
   {
      if (nodeRef)
      {
         // var url = '/slingshot/doclib2/node/' + nodeRef.replace('://', '/');
         // if (!site)
         // {
         //    // Repository mode
         //    url += "?libraryRoot=" + encodeURIComponent(AlfrescoUtil.getRootNode());
         // }
         // var result = remote.connect("alfresco").get(url);
      details = search.findNode(nodeRef);

         if (details != null)
         {
            if (details && (details.item || details.items))
            {
               DocList.processResult(details, options);
               return details;
            } else AlfrescoUtil.error(500, 'details not ok'+jsonUtils.toJSONString(details), true);
         } else AlfrescoUtil.error(500, 'details empty', true);
      }
   return null;
   },
   
   getMetaData: function getMetaData(nodeRef, defaultValue)
   {
//   var result=search.findNode(nodeRef);
     var result = remote.connect("alfresco").get('/api/metadata?nodeRef=' + nodeRef);
      if (result.status != 200)
      {
         if (defaultValue !== undefined)
         {
            return defaultValue;
         }
         AlfrescoUtil.error(result.status, 'Could not load meta data ' + nodeRef);
      }
      result = eval('(' + result + ')');
      return result;
   },

};

HTML i get from this webscript


   <script type="text/javascript">//<![CDATA[
      new Alfresco.CommentsList("prova").setOptions(
      {
         nodeRef: "workspace://SpacesStore/4b7198b9-5356-446d-a1a2-747b2896a9ff",
         siteId: "SpacesStore",
         maxItems: 10,
         activity: null,
         editorConfig:
         {
            inline_styles: false,
            convert_fonts_to_spans: false,
            theme: "advanced",
            theme_advanced_buttons1: "bold,italic,underline,|,bullist,numlist,|,forecolor,|,undo,redo,removeformat",
            theme_advanced_toolbar_location: "top",
            theme_advanced_toolbar_align: "left",
            theme_advanced_resizing: true,
            theme_advanced_buttons2: null,
            theme_advanced_buttons3: null,
            theme_advanced_path: false,
            language: "it"
         }
      }).setMessages(
         {"message.confirm.delete": "Eliminare questo commento?", "message.delete.success": "Commento eliminato", "message.wait": "Attendere…", "message.delete.failure": "Impossibile eliminare il commento", "header.edit": "Modifica commento…", "header.comments": "Commenti", "message.noComments": "Nessun commento", "message.loadeditform.failure": "Impossibile caricare il modulo di modifica del commento", "message.savecomment": "Salvataggio del commento in corso…", "message.confirm.delete.title": "Elimina commento", "header.add": "Aggiungi commento…", "button.addComment": "Aggiungi commento", "link.deleteComment": "Elimina commento", "button.save": "Salva", "label.avatar": "Avatar", "button.cancel": "Annulla", "message.savecomment.failure": "Impossibile salvare il commento", "link.editComment": "Modifica commento"}
      );
   //]]></script>
   <div id="prova-body" class="comments-list">

      <h2 class="thin dark">Commenti</h2>

      <div id="prova-add-comment">
         <div id="prova-add-form-container" class="theme-bg-color-4 hidden"></div>
      </div>

      <div class="comments-list-actions">
         <div class="left">
            <div id="prova-actions" class="hidden">
               <button class="alfresco-button" name=".onAddCommentClick">Aggiungi commento</button>
            </div>
         </div>
         <div class="right">
            <div id="prova-paginator-top"></div>
         </div>
         <div class="clear"></div>
      </div>

      <hr class="hidden"/>

      <div id="prova-comments-list"></div>

      <hr class="hidden"/>

      <div class="comments-list-actions">
         <div class="left">
         </div>
         <div class="right">
            <div id="prova-paginator-bottom"></div>
         </div>
         <div class="clear"></div>
      </div>

   </div>

I think now it's sufficient to reference alfresco.js (and CSS) with normal javascript <link> and that's it, am I right?

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
That is really cool, Nicola! I googled a bit on it, but couldn't find good reference on specifying imports in data dictionary webscript. I was about to advice you to include all code in the webscript js as an alternative, but it is great that this now works.

It looks indeed that including comments-list.js and alfresco.js script references will get it working.

nicolabeghin
Champ in-the-making
Champ in-the-making
Thanks again for the support Alfred.
I'm stuck again cause the template can't find some user-defined functions like <@markup>, <@link>, <@script>… Do you have any suggestion? It seems like an endless job. any way to turn off freemarker error at least while trying to get something up and running?

The error is quite self-explanatory and I get it's because no predefined (and required) variables are set before the output of the freemarker template, but shouldn't these function be available to any alfresco template? not event context is defined..

'Expression theme is undefined on line 14, column 9

comments-list.get.html.ftl

<#–
   RESOURCES
–>

   <!– Icons –>
   <link rel="shortcut icon" href="/share/res/favicon.ico" type="image/vnd.microsoft.icon" />
   <link rel="icon" href="/share/res/favicon.ico" type="image/vnd.microsoft.icon" />


   <!– YUI –>
   <link rel="stylesheet" type="text/css" href="/share/res/css/yui-fonts-grids.css" />
   <link rel="stylesheet" type="text/css" href="/share/res/yui/columnbrowser/assets/columnbrowser.css" />
   <link rel="stylesheet" type="text/css" href="/share/res/yui/columnbrowser/assets/skins/default/columnbrowser-skin.css" />
   <#if theme = 'default'>
   <link rel="stylesheet" type="text/css" href="/share/res/yui/assets/skins/default/skin.css" />
   <#else>
   <link rel="stylesheet" type="text/css" href="/share/res/themes/${theme}/yui/assets/skin.css" />
   </#if>
   <#if DEBUG>
   <script type="text/javascript" src="/share/res/js/log4javascript.v1.4.1.js"></script>
   <script type="text/javascript" src="/share/res/yui/yahoo/yahoo-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/event/event-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/dom/dom-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/dragdrop/dragdrop-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/animation/animation-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/logger/logger-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/connection/connection-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/element/element-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/get/get-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/yuiloader/yuiloader-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/button/button-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/container/container-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/menu/menu-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/json/json-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/selector/selector-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/datasource/datasource-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/autocomplete/autocomplete-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/paginator/paginator-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/datatable/datatable-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/history/history-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/treeview/treeview-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/autocomplete/autocomplete-debug.js"></script>
   <script type="text/javascript" src="/share/res/yui/yui-patch.js"></script>
   <script type="text/javascript">//<![CDATA[
      YAHOO.util.Event.throwErrors = true;
   //]]></script>
   <#else>
   <script type="text/javascript" src="/share/res/js/yui-common.js"></script>
   </#if>
   <script type="text/javascript" src="/share/res/js/bubbling.v2.1.js"></script>
   <script type="text/javascript">//<![CDATA[
      YAHOO.Bubbling.unsubscribe = function(layer, handler, scope)
      {
         this.bubble[layer].unsubscribe(handler, scope);
      };
   //]]></script>


   <!– Common i18n msg properties –>
   <script type="text/javascript" src="/share/service/messages.js?locale=${locale}"></script>

   <!– Alfresco web framework constants –>
   <script type="text/javascript">//<![CDATA[
      Alfresco.constants = Alfresco.constants || {};
      Alfresco.constants.DEBUG = ${DEBUG?string};
      Alfresco.constants.AUTOLOGGING = ${AUTOLOGGING?string};
      Alfresco.constants.PROXY_URI = window.location.protocol + "//" + window.location.host + "/share/proxy/alfresco/";
      Alfresco.constants.PROXY_URI_RELATIVE = "/share/proxy/alfresco/";
      Alfresco.constants.PROXY_FEED_URI = window.location.protocol + "//" + window.location.host + "/share/proxy/alfresco-feed/";
      Alfresco.constants.THEME = "${theme}";
      Alfresco.constants.URL_CONTEXT = "/share/";
      Alfresco.constants.URL_RESCONTEXT = "/share/res/";
      Alfresco.constants.URL_PAGECONTEXT = "/share/page/";
      Alfresco.constants.URL_SERVICECONTEXT = "/share/service/";
      Alfresco.constants.URL_FEEDSERVICECONTEXT = "/share/feedservice/";
      Alfresco.constants.USERNAME = "${(user.name!"")?js_string}";
      Alfresco.constants.SITE = "<#if page??>${(page.url.templateArgs.site!"")?js_string}</#if>";
      Alfresco.constants.PAGEID = "<#if page??>${(page.url.templateArgs.pageid!"")?js_string}</#if>";
      Alfresco.constants.PORTLET = ${PORTLET?string};
      Alfresco.constants.PORTLET_URL = unescape("${(context.attributes.portletUrl!"")?js_string}");
      Alfresco.constants.JS_LOCALE = "${locale}";
   <#if PORTLET>
      document.cookie = "JSESSIONID=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/share";
   </#if>
   //]]></script>


   <!– Alfresco web framework common resources –>
<#if PORTLET>
   <link rel="stylesheet" type="text/css" href="/share/res/css/portlet.css" />
</#if>
   <link rel="stylesheet" type="text/css" href="/share/res/css/base.css" />
   <link rel="stylesheet" type="text/css" href="/share/res/css/yui-layout.css" />
   <script type="text/javascript" src="/share/res/js/flash/AC_OETags.js"></script>
   <script type="text/javascript" src="/share/res/js/alfresco.js"></script>
   <script type="text/javascript" src="/share/res/modules/editors/tiny_mce/tiny_mce${DEBUG?string("_src", "")}.js"></script>
   <script type="text/javascript" src="/share/res/modules/editors/tiny_mce.js"></script>
   <script type="text/javascript" src="/share/res/modules/editors/yui_editor.js"></script>
   <script type="text/javascript" src="/share/res/js/forms-runtime.js"></script>


   <!– Share Constants –>
   <script type="text/javascript">//<![CDATA[
      Alfresco.service.Preferences.FAVOURITE_DOCUMENTS = "org.alfresco.share.documents.favourites";
      Alfresco.service.Preferences.FAVOURITE_FOLDERS = "org.alfresco.share.folders.favourites";
      Alfresco.service.Preferences.FAVOURITE_SITES = "org.alfresco.share.sites.favourites";
      Alfresco.service.Preferences.IMAP_FAVOURITE_SITES = "org.alfresco.share.sites.imapFavourites";
      Alfresco.service.Preferences.COLLAPSED_TWISTERS = "org.alfresco.share.twisters.collapsed";
      Alfresco.service.Preferences.RULE_PROPERTY_SETTINGS = "org.alfresco.share.rule.properties";
      Alfresco.constants.URI_TEMPLATES =
      {
         <#list config.scoped["UriTemplate"]["uri-templates"].childrenMap["uri-template"] as c>
         "${c.attributes["id"]}": "${c.value}"<#if c_has_next>,</#if>
         </#list>
      };
      Alfresco.constants.HELP_PAGES =
      {
         <#list config.scoped["HelpPages"]["help-pages"].children as c>
         "${c.name}": "${c.value}"<#if c_has_next>,</#if>
         </#list>
      };
      Alfresco.constants.HTML_EDITOR = 'tinyMCE';
   //]]></script>


   <!– Share resources –>
   <script type="text/javascript" src="/share/res/js/share.js"></script>
   <script type="text/javascript" src="/share/res/js/lightbox.js"></script>
   <link rel="stylesheet" type="text/css" href="/share/res/themes/${theme}/presentation.css" />


   <#if (templateStylesheets?size > 0)>
   <!– Common stylesheets gathered to workaround IEBug KB262161 –>
   <style type="text/css" media="screen">
      <#list templateStylesheets as href>
      @import "${href}";
      </#list>
   </style>
   </#if>

   <#– Use this "markup id" to add in a extension's resources –>


<!– Comments List –>
<link rel="stylesheet" type="text/css" href="/share/res/components/comments/comments-list.css" />
<script type="text/javascript" src="/share/res/components/comments/comments-list.js"></script>

<#if nodeRef??>
   <#assign el=args.htmlid?js_string>
   <script type="text/javascript">//<![CDATA[
      new Alfresco.CommentsList("${el}").setOptions(
      {
         nodeRef: "${nodeRef?js_string}",
         siteId: <#if site??>"${site?js_string}"<#else>null</#if>,
         maxItems: ${maxItems?js_string},
         activity: <#if activityParameterJSON??>${activityParameterJSON}<#else>null</#if>,
         editorConfig:
         {
            inline_styles: false,
            convert_fonts_to_spans: false,
            theme: "advanced",
            theme_advanced_buttons1: "bold,italic,underline,|,bullist,numlist,|,forecolor,|,undo,redo,removeformat",
            theme_advanced_toolbar_location: "top",
            theme_advanced_toolbar_align: "left",
            theme_advanced_resizing: true,
            theme_advanced_buttons2: null,
            theme_advanced_buttons3: null,
            theme_advanced_path: false,
            language: "${locale?substring(0, 2)?js_string}"
         }
      }).setMessages(
         ${messages}
      );
   //]]></script>
   <div id="${el}-body" class="comments-list">

      <h2 class="thin dark">${msg("header.comments")}</h2>

      <div id="${el}-add-comment">
         <div id="${el}-add-form-container" class="theme-bg-color-4 hidden"></div>
      </div>

      <div class="comments-list-actions">
         <div class="left">
            <div id="${el}-actions" class="hidden">
               <button class="alfresco-button" name=".onAddCommentClick">${msg("button.addComment")}</button>
            </div>
         </div>
         <div class="right">
            <div id="${el}-paginator-top"></div>
         </div>
         <div class="clear"></div>
      </div>

      <hr class="hidden"/>

      <div id="${el}-comments-list"></div>

      <hr class="hidden"/>

      <div class="comments-list-actions">
         <div class="left">
         </div>
         <div class="right">
            <div id="${el}-paginator-bottom"></div>
         </div>
         <div class="clear"></div>
      </div>

   </div>
</#if>

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
Am I assuming correctly that you were having trouble with the @ directives in the freemarker template, so you've created the provided template that has all code inline, but it still gives errors because of undefined global variables such as 'theme'?

You'll have to look whether you really need these variables, and if so, add them to the model in the webscript js.
Looking further at the template I think it has too much share plumbing still in it. I think you'll should have a careful look at the code and remove anything share-related that is not needed by your comments-list. Then finally make sure all remaining script and stylesheet references point to the alfresco tier, not to share.

(Edit: Nicola, I was somehow editing to a previous version of your current post when I wrote message above)

arnoldschrijve1
Champ on-the-rise
Champ on-the-rise
The alfresco repo tier has no full configuration for Spring Surf. In share you can find some @ declarations in share/WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/component.head.inc

nicolabeghin
Champ in-the-making
Champ in-the-making
Hi Arnold,
sorry for this huge lag in replying.. I had to focus on some more recently-due Alfresco tasks and let this issue delay.
At the moment I'm trying to add new comments via SOAP (via the alfresco-webservice.jar of the Alfresco SDK but seems like it's not supported), I'll keep you updated as soon as I'll work in this issue again.

Thanks again for your invaluable support, hope I'll be able to close the issue and get something useful for you too!
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.