- moved html encoding from REST API to ui layer webscripts and javascript

- proper header for discussions/blog list (aligned with documentlibrary)
- highlighting of selected filter in blog/discussions
- fix for broken invite users component if a user has null as first or last name
- removed obsolete webscripts
- various small fixes

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10241 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Michael Ru
2008-08-05 08:37:37 +00:00
parent e432646ca9
commit 720b70035f
20 changed files with 121 additions and 154 deletions

View File

@@ -2,16 +2,18 @@
This template renders the blog configuration json data.
-->
<#macro blogJSON item>
<#escape x as jsonUtils.encodeJSONString(x)>
{
"qnamePath" : "${item.qnamePath}",
"url" : "blog/node/${item.nodeRef?replace('://', '/')}",
"blogPostsUrl" : "blog/node/${item.nodeRef?replace('://', '/')}/posts",
"type" : "${item.properties["blg:blogImplementation"]!''}",
"id" : "${item.properties["blg:id"]!'0'}",
"name" : "${(item.properties["blg:name"]!'')?html?j_string}",
"description" : "${(item.properties["blg:description"]!'')?html?j_string}",
"name" : "${item.properties["blg:name"]!''}",
"description" : "${item.properties["blg:description"]!''}",
"url" : "${item.properties["blg:url"]!''}",
"username" : "${item.properties["blg:userName"]!''}",
"password" : "${item.properties["blg:password"]!''}"
}
</#escape>
</#macro>

View File

@@ -1,36 +1,33 @@
<#-- Renders a person object. -->
<#macro renderPerson person fieldName>
<#escape x as jsonUtils.encodeJSONString(x)>
"${fieldName}" : {
<#if person.assocs["cm:avatar"]??>
"avatarRef" : "${person.assocs["cm:avatar"][0].nodeRef?string}",
</#if>
"username" : "${person.properties["cm:userName"]}",
"firstName" : "${person.properties["cm:firstName"]?html}",
"lastName" : "${person.properties["cm:lastName"]?html}"
"firstName" : "${person.properties["cm:firstName"]}",
"lastName" : "${person.properties["cm:lastName"]}"
},
</#escape>
</#macro>
<#macro renderTags tags>
[<#list tags as x>"${x?html?j_string}"<#if x_has_next>, </#if></#list>]
</#macro>
<#macro addContent item>
<#assign maxTextLength=512>
<#if (! contentFormat??) || contentFormat == "" || contentFormat == "full">
"content" : "${item.node.content?j_string}",
<#elseif contentFormat == "htmlDigest">
<#if (item.node.content?length > maxTextLength)>
"content" : "${item.node.content?substring(0, maxTextLength)?j_string}",
<#else>
"content" : "${item.node.content?j_string}",
</#if>
<#elseif contentFormat == "textDigest">
<#assign croppedTextContent=cropContent(item.node.properties.content, maxTextLength)>
"content" : "${croppedTextContent?j_string}",
<#escape x as jsonUtils.encodeJSONString(x)>
<#if (contentLength?? && contentLength > -1)>
"content" : "${cropContent(item.node.properties.content, contentLength)}",
<#else>
<#-- no content returned -->
"content" : "${item.node.content}",
</#if>
<#--
<#if (contentLength?? && contentLength > -1)>
"content" : "${stringUtils.stripUnsafeHTML(cropContent(item.node.properties.content, contentLength))}",
<#else>
"content" : "${stringUtils.stripUnsafeHTML(item.node.content)}",
</#if>
-->
</#escape>
</#macro>
<#--
@@ -39,23 +36,24 @@
-->
<#macro blogpostJSON item>
<#escape x as jsonUtils.encodeJSONString(x)>
{
"url" : "blog/post/node/${item.node.nodeRef?replace('://','/')}",
"commentsUrl" : "/node/${item.node.nodeRef?replace('://','/')}/comments",
"nodeRef" : "${item.node.nodeRef}",
"name" : "${(item.node.properties.name!'')?html?j_string}",
"title" : "${(item.node.properties.title!'')?html?j_string}",
"name" : "${item.node.properties.name!''}",
"title" : "${item.node.properties.title!''}",
<@addContent item=item />
<#if item.author??>
<@renderPerson person=item.author fieldName="author" />
<#else>
"author" : { "username" : "${item.node.properties.creator?j_string}" },
"author" : { "username" : "${item.node.properties.creator}" },
</#if>
"createdOn" : "${item.createdDate?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
"modifiedOn" : "${item.modifiedDate?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
"permissions" : {"edit" : true, "publishExt" : true, "delete" : true},
"commentCount" : ${item.commentCount?c},
"tags" : <@renderTags tags=item.tags />,
"tags" : [<#list item.tags as x>"${x}"<#if x_has_next>, </#if></#list>],
<#-- draft vs internal published -->
"isDraft" : ${item.isDraft?string},
@@ -80,4 +78,5 @@
<#-- external publishing - last to make sure that we correctly end the response without a comma -->
"isPublished" : ${(item.node.properties["blg:published"]!'false')?string}
}
</#escape>
</#macro>

View File

@@ -12,7 +12,10 @@ function main()
// assign data
model.item = getBlogPostData(node);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -37,7 +37,10 @@ function main()
// fetch and assign the data
model.data = getBlogPostList(node, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -38,7 +38,10 @@ function main()
// fetch and assign the data
model.data = getBlogPostList(node, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -40,7 +40,10 @@ function main()
// fetch and assign the data
model.data = getBlogPostList(node, numdays, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -36,7 +36,10 @@ function main()
// fetch and assign the data
model.data = getBlogPostList(node, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -76,7 +76,10 @@ function main()
// fetch and assign the data
model.data = getBlogPostList(node, fromDate, toDate, tag, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -1,13 +1,15 @@
<#-- Renders a person object. -->
<#macro renderPerson person fieldName>
<#escape x as jsonUtils.encodeJSONString(x)>
"${fieldName}" : {
<#if person.assocs["cm:avatar"]??>
"avatarRef" : "${person.assocs["cm:avatar"][0].nodeRef?string}",
</#if>
"username" : "${person.properties["cm:userName"]}",
"firstName" : "${(person.properties["cm:firstName"])?html}",
"lastName" : "${(person.properties["cm:lastName"])?html}"
"firstName" : "${person.properties["cm:firstName"]}",
"lastName" : "${person.properties["cm:lastName"]}"
},
</#escape>
</#macro>
<#--
@@ -16,21 +18,23 @@
-->
<#macro commentJSON item>
<#escape x as jsonUtils.encodeJSONString(x)>
{
"url" : "api/comment/node/${item.node.nodeRef?replace('://','/')}",
"nodeRef" : "${item.node.nodeRef}",
"name" : "${(item.node.properties.name!'')?html?j_string}",
"title" : "${(item.node.properties.title!'')?html?j_string}",
"content" : "${item.node.content?j_string}",
"name" : "${item.node.properties.name!''}",
"title" : "${item.node.properties.title!''}",
"content" : "${item.node.content}",
<#if item.author??>
<@renderPerson person=item.author fieldName="author" />
<#else>
"author" : { "username" : "${item.node.properties.creator?j_string}" },
"author" : { "username" : "${item.node.properties.creator}" },
</#if>
"createdOn" : "${item.node.properties.created?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
"modifiedOn" : "${item.node.properties.modified?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
"isUpdated" : ${item.isUpdated?string},
"permissions" : {"edit" : true, "delete" : true}
}
</#escape>
</#macro>

View File

@@ -96,7 +96,9 @@ function main()
// fetch the data and assign it to the model
model.data = getHotTopicPostList(node, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -1,10 +0,0 @@
<webscript>
<shortname>Forum latest posts and replies</shortname>
<description>Get the latest posts and replies added to the forum</description>
<url>/forum/site/{site}/{container}/{path}/latestposts</url>
<url>/forum/site/{site}/{container}/latestposts</url>
<url>/forum/node/{store_type}/{store_id}/{id}/latestposts</url>
<format default="json"/>
<authentication>user</authentication>
<transaction>required</transaction>
</webscript>

View File

@@ -1,49 +0,0 @@
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/requestutils.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/generic-paged-results.lib.js">
<import resource="classpath:alfresco/templates/webscripts/org/alfresco/repository/discussions/topicpost.lib.js">
function getLatestAddedPostData(node)
{
// fetch the topic post data and then add the node as reply.
// in case of a new topic post, the reply and the post will be the
// same, otherwise they differ. The topic post will be used to fetch
// the topic title, while the reply will be used to show the text
var data = getTopicPostData(node.parent);
data.reply = node;
data.isRootPost = data.post.nodeRef.equals(data.reply.nodeRef);
return data;
}
/**
* Fetches all posts in reverse order.
*/
function getLatestAddedPosts(node, index, count)
{
var luceneQuery = " +TYPE:\"{http://www.alfresco.org/model/forum/1.0}post\"" +
" +PATH:\"" + node.qnamePath + "/*/*\"";
var sortAttribute = "@{http://www.alfresco.org/model/content/1.0}created";
// get the data
return getPagedResultsDataByLuceneQuery(node, luceneQuery, sortAttribute, false, index, count, getLatestAddedPostData);
}
function main()
{
// get requested node
var node = getRequestNode();
if (status.getCode() != status.STATUS_OK)
{
return;
}
// process additional parameters
var index = args["startIndex"] != undefined ? parseInt(args["startIndex"]) : 0;
var count = args["pageSize"] != undefined ? parseInt(args["pageSize"]) : 10;
// fetch the data and assign it to the model
model.data = getLatestAddedPosts(node, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
}
main();

View File

@@ -1,15 +0,0 @@
<#import "../post.lib.ftl" as postLib/>
<#import "../../generic-paged-results.lib.ftl" as gen/>
<#macro latestPostJSON item>
{
"topicTitle" : "${item.post.properties.title?js_string}",
"topicName" : "${item.topic.name}",
"isRootPost" : ${item.isRootPost?string},
<@postLib.postDataJSON refNode=item.topic post=item.reply />
}
</#macro>
<@gen.pagedResults data=data ; item>
<@latestPostJSON item=item />
</@gen.pagedResults>

View File

@@ -33,7 +33,9 @@ function main()
// fetch the data and assign it to the model
model.data = getTopicPostList(node, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -39,7 +39,9 @@ function main()
// fetch the data and assign it to the model
model.data = getTopicPostList(node, numdays, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -40,7 +40,9 @@ function main()
model.data = getTopicPostList(node, tag, index, count);
model.contentFormat = (args["contentFormat"] != undefined) ? args["contentFormat"] : "full";
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -1,37 +1,36 @@
<#-- Renders a person object. -->
<#macro renderPerson person fieldName>
<#escape x as jsonUtils.encodeJSONString(x)>
"${fieldName}" : {
<#if person.assocs["cm:avatar"]??>
"avatarRef" : "${person.assocs["cm:avatar"][0].nodeRef?string}",
</#if>
"username" : "${person.properties["cm:userName"]}",
"firstName" : "${person.properties["cm:firstName"]?html}",
"lastName" : "${person.properties["cm:lastName"]?html}"
"firstName" : "${person.properties["cm:firstName"]}",
"lastName" : "${person.properties["cm:lastName"]}"
},
</#escape>
</#macro>
<#macro renderTags tags>
[<#list tags as x>"${x?j_string}"<#if x_has_next>, </#if></#list>]
</#macro>
<#macro addContent post>
<#assign maxTextLength=512>
<#if (! contentFormat??) || contentFormat == "" || contentFormat == "full">
"content" : "${post.content?j_string}",
<#elseif contentFormat == "htmlDigest">
<#if (post.content?length > maxTextLength)>
"content" : "${post.content?substring(0, maxTextLength)?j_string}",
<#else>
"content" : "${post.content?j_string}",
</#if>
<#elseif contentFormat == "textDigest">
<#assign croppedTextContent=cropContent(post.properties.content, maxTextLength)>
"content" : "${croppedTextContent?j_string}",
<#escape x as jsonUtils.encodeJSONString(x)>
<#if (contentLength?? && contentLength > -1)>
"content" : "${cropContent(post.properties.content, contentLength)}",
<#else>
<#-- no content returned -->
"content" : "${post.content}",
</#if>
<#--
<#if (contentLength?? && contentLength > -1)>
"content" : "${stringUtils.stripUnsafeHTML(cropContent(post.properties.content, contentLength))}",
<#else>
"content" : "${stringUtils.stripUnsafeHTML(post.content)}",
</#if>
-->
</#escape>
</#macro>
<#macro postJSON postData>
{
<@postDataJSON postData=postData />
@@ -39,6 +38,7 @@
</#macro>
<#macro postDataJSON postData>
<#escape x as jsonUtils.encodeJSONString(x)>
<#-- which node should be used for urls? which for the post data? -->
<#if postData.isTopicPost>
<#assign refNode=postData.topic />
@@ -50,22 +50,22 @@
<#-- render topic post only data first -->
<#if postData.isTopicPost>
"name" : "${postData.topic.name?html?js_string}",
"name" : "${postData.topic.name}",
"totalReplyCount" : ${postData.totalReplyCount?c},
<#if postData.lastReply??>
"lastReplyOn" : "${postData.lastReply.properties.created?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
<@renderPerson person=postData.lastReplyBy fieldName="lastReplyBy" />
</#if>
"tags" : <@renderTags tags=postData.tags />,
"tags" : [<#list postData.tags as x>"${x}"<#if x_has_next>, </#if></#list>],
</#if>
<#-- data using refNode which might be the topic or the post node -->
"url" : "/forum/post/node/${refNode.nodeRef.storeRef.protocol}/${refNode.nodeRef.storeRef.identifier}/${refNode.nodeRef.id}",
"repliesUrl" : "/forum/post/node/${refNode.nodeRef.storeRef.protocol}/${refNode.nodeRef.storeRef.identifier}/${refNode.nodeRef.id}/replies",
"nodeRef" : "${refNode.nodeRef?j_string}",
"nodeRef" : "${refNode.nodeRef}",
<#-- normal data, the post node will used to fetch it -->
"title" : "${(post.properties.title!"")?html?j_string}",
"title" : "${(post.properties.title!"")}",
"createdOn" : "${post.properties.created?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
"modifiedOn" : "${post.properties.modified?string("MMM dd yyyy HH:mm:ss 'GMT'Z '('zzz')'")}",
"isUpdated" : ${post.hasAspect("cm:contentupdated")?string},
@@ -82,6 +82,7 @@
<@addContent post=post />
"replyCount" : <#if post.sourceAssocs["cm:references"]??>${post.sourceAssocs["cm:references"]?size?c}<#else>0</#if>,
"permissions" : { "edit": true, "delete" : true, "reply" : true }
</#escape>
</#macro>

View File

@@ -90,6 +90,10 @@ function main()
var levels = args["levels"] != undefined ? parseInt(args["levels"]) : 1;
model.data = getReplies(node, levels);
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentFormat"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -32,6 +32,10 @@ function main()
}
fetchPostData(node);
// fetch the contentLength param
var contentLength = args["contentLength"] != undefined ? parseInt(args["contentLength"]) : -1;
model.contentLength = isNaN(contentLength) ? -1 : contentLength;
}
main();

View File

@@ -1,29 +1,30 @@
<#assign workingCopyLabel = " " + message("coci_service.working_copy_label")>
{
<#escape x as jsonUtils.encodeJSONString(x)>
{
"items":
[
<#list data.items as item>
[
<#list data.items as item>
{
"index": ${item_index},
"nodeRef" : "${item.nodeRef?j_string}",
"qnamePath" : "${item.qnamePath?j_string}",
"nodeRef" : "${item.nodeRef}",
"qnamePath" : "${item.qnamePath}",
"type": "${item.type}",
"icon32": "${item.icon32}",
"name" : "${(item.name!'')?html?j_string}",
"displayName": "${(item.displayName!'')?html?j_string}",
"tags" : [<#list item.tags as tag>"${tag?html?j_string}"<#if tag_has_next>,</#if></#list>],
"name" : "${item.name!''}",
"displayName": "${item.displayName!''}",
"tags" : [<#list item.tags as tag>"${tag}"<#if tag_has_next>,</#if></#list>],
<#if item.downloadUrl??>
"downloadUrl" : "${item.downloadUrl?j_string}",
"downloadUrl" : "${item.downloadUrl}",
</#if>
<#if item.browseUrl??>
"browseUrl" : "${item.browseUrl?j_string}",
"browseUrl" : "${item.browseUrl}",
</#if>
"site" : {
"shortName" : "${item.site.shortName?html?j_string}",
"title" : "${item.site.title?html?j_string}"
"shortName" : "${item.site.shortName}",
"title" : "${item.site.title}"
},
"container" : "${item.container?html?j_string}"
}<#if item_has_next>,</#if>
</#list>
]
"container" : "${item.container}"
}<#if item_has_next>,</#if>
</#list>
]
}
</#escape>