What is the Char Limit on a Quick Post and how to change it?

is there any way we can limit number of characters on quick post.

  • Hi . I see you're posting in the Archive forum. What version of Community are you using? And is the Quick Post the factory default version for that version? It's changed significantly across releases.

  • In recent versions, there is not a straightforward way to do this. Additionally, limiting characters is not necessarily meaningful as status messages support rich text/HTML and embedded items.

    In previous versions, the status message form only accepted plain text, and so max length was more meaningful. For example, in this similar thread https://community.telligent.com/community/archive/f/telligent-community-forum/1141192/what-is-the-char-limit-on-a-quick-post-and-how-to-change-it. Of course, the legacy widgets will still run in 10, which is why I was curious about whether or not you're using the default 10.x widgets or legacy/upgraded widgets from an upgraded UI. 

  • Hi We are not using legacy widget we are using the standard 10.x widget.

    Problem here is users are writing stories on quick post, i know they need to use blog post not quick post.

    But they are using quick post to write long stories, so we thought of limiting user  with long stories on quick post. 

  • We have people posting from Word documents or emails directly into a quickpost. I'm sure that is not a preferred behavior. It claims the full real estate of a home page and also turns off the visitors since they do not want to enter seeing content they didn't ask for. I'm sure the designer of the QuickPost had a thought on what an acceptable length should be.

    Now it seems that the quickpost is nothing but a TinyMCE rendering with no limits. I understand that from systems commonality but it is an undesired side effect

  • I understand your concerns, . A few points:

    By design, Community supports quickly converting content between types, such as status message-to-blog post via the "more" menu. In fact, the content conversion service was originally added specifically to address the scenario of some community members "living" in the stream versus others using focused applications.

    While the Quick Post widget doesn't support max length, it can be modified in Administration > Widgets to limit or disable the auto-expanding nature of the form input. To change this, in Administration > Widgets navigate to the Quick Post widget and inspect line 55 of its content, changing AutoResize = 'True' to AutoResize = 'False'. Of course, such a change could be added as a configurable option on the widget as well.

    In addition, I'm logging an issue to review making sure status message activity stories render truncated with the ability to expand their content, similar to stories for other long content like blog posts.

    TE-8255: Status message story widget should truncate long messages and support user expansion

    Completed for 10.3.0.5640

    It turns out such a change would just be an update to the status message activity story widget in Administration > Widgets, and it's small enough that I've attached an edited version of that widget to this post below as it's a good example of various types of widget edits. The relevant changes would be to change

    <div class="activity-content user-defined-markup">
    	$context.StatusMessage.Message('web')
    </div>

    ...to the following, explained inline:

    <div class="activity-content user-defined-markup">
    	## Truncate the status message, maintaining formatting
    	#set ($renderedMessage = $context.StatusMessage.Message('web'))
    	#set ($truncatedRenderedMessage = $core_v2_language.Truncate($renderedMessage, 750, "%{ Ellipsis = '...', MaintainHtmlFormatting = 'true' }"))
    	## If the truncated version differs from original, add a "view more" link
    	#if ($renderedMessage != $truncatedRenderedMessage)
    		#set($statusMessageWrapperId = $core_v2_widget.UniqueId("status-content-${context.StatusMessage.Id}"))
    		<span id="$core_v2_encoding.HtmlAttributeEncode($statusMessageWrapperId)">
    			$truncatedRenderedMessage
    		</span>
    		## Use a message link with embedded data about the status message and wrapper element
    		<a href="#" data-messagename="expand-status-message"
    			data-userid="$context.StatusMessage.Author.Id"
    			data-messageid="$context.StatusMessage.Id"
    			data-wrapper="$core_v2_encoding.HtmlAttributeEncode($statusMessageWrapperId)">
    			View More
    		</a>
    		## Register a global script for all status stories that handles expansions
    		#registerEndOfPageHtml('status-message-story')
    			<script>
    				jQuery(function(j){
    					j.telligent.evolution.messaging.subscribe('expand-status-message', function(e) {
    						var link = j(e.target);
    						var wrapper = j('#' + link.data('wrapper'));
    						var messageId = link.data('messageid');
    						var userId = link.data('userid');
    
    						// Load the full status message via REST
    						j.telligent.evolution.get({
    							url: j.telligent.evolution.site.getBaseUrl() + 'api.ashx/v2/users/{userid}/statuses/{messageid}.json',
    							data: {
    								userid: userId,
    								messageid: messageId
    							}
    						}).done(function(r){
    							// Render the full status body and hide the view link
    							wrapper.html(r.StatusMessage.Body);
    							link.hide();
    						});
    					})
    				});
    			</script>
    		#end
    	#else
    		$renderedMessage
    	#end
    </div>

    Hope this helps.

    Full widget export:

    <scriptedContentFragments>
    	<scriptedContentFragment name="${resource:StatusMessageActivityStory_Name}" version="10.0.0.0" description="${resource:StatusMessageActivityStory_Description}" instanceIdentifier="93a5307312ef453a9f8927ccc0cb2049" theme="" isCacheable="false" varyCacheByUser="true" showHeaderByDefault="false" cssClass="">
    		<contentScript><![CDATA[#set($content = $core_v2_content.Get($context.Story.ContentId, $context.Story.ContentTypeId))
    #set($statusMessage = $context.StatusMessage)
    
    #if(!$content || !$statusMessage)
    	$core_v2_widget.Hide()
    #else
    	#set($actor = $context.Story.PrimaryUser)
    	#if ($actor.Url)
            #set($profile0Html = $core_v2_language.FormatString($core_v2_language.GetResource('UserProfile_Html'), $actor.DisplayName, $actor.Url))
    	#else
    		#set($profile0Html = $actor.DisplayName)
    	#end
    	#if ($context.IsPreview)
    		#if ($content.Application.Container.ParentContainer)
    			#format($core_v2_language.GetResource('StatusMessage_Preview_InGroup'))
    				#token('user')
    					$profile0Html
    			#token('message')
    				$core_v2_language.Truncate($context.StatusMessage.Message('web'), 100, '...')
    			#token('group')
    				<a href="$core_v2_encoding.HtmlAttributeEncode($content.Application.Container.Url)">$content.Application.Container.HtmlName('Web')</a>
    			#end
    		#else
    			#format($core_v2_language.GetResource('StatusMessage_Preview'))
    				#token('user')
    					$profile0Html
    			#token('message')
    				$core_v2_language.Truncate($context.StatusMessage.Message('web'), 100, '...')
    			#token('group')
    				<a href="$core_v2_encoding.HtmlAttributeEncode($content.Application.Container.Url)">$content.Application.Container.HtmlName('Web')</a>
    			#end
    		#end
    	#else
    		<div class="activity-summary">
    			#if ($content.Application.Container.ParentContainer)
    				#format($core_v2_language.GetResource('in_group'))
    					#token('user')
    						$profile0Html
    					#token('group')
    						<a href="$core_v2_encoding.HtmlAttributeEncode($content.Application.Container.Url)">$content.Application.Container.HtmlName('Web')</a>
    				#end
    			#elseif ($core_v2_urls.Current != 'ActivityMessage')
    				#format($core_v2_language.GetResource('in'))
    					#token('user')
    						$profile0Html
    				#end
    			#end
    		</div>
    
    		<div class="activity-content user-defined-markup">
    		    ## Truncate the status message, maintaining formatting
    		    #set ($renderedMessage = $context.StatusMessage.Message('web'))
    		    #set ($truncatedRenderedMessage = $core_v2_language.Truncate($renderedMessage, 750, "%{ Ellipsis = '...', MaintainHtmlFormatting = 'true' }"))
    		    ## If the truncated version differs from original, add a "view more" link 
    		    #if ($renderedMessage != $truncatedRenderedMessage) 
                    #set($statusMessageWrapperId = $core_v2_widget.UniqueId("status-content-${context.StatusMessage.Id}"))
    		        <span id="$core_v2_encoding.HtmlAttributeEncode($statusMessageWrapperId)">
    		            $truncatedRenderedMessage
    		        </span>
    		        ## Use a message link with embedded data about the status message and wrapper element
    		        <a href="#" data-messagename="expand-status-message" 
    		            data-userid="$context.StatusMessage.Author.Id" 
    		            data-messageid="$context.StatusMessage.Id"
    		            data-wrapper="$core_v2_encoding.HtmlAttributeEncode($statusMessageWrapperId)">
    		            $core_v2_language.GetResource('ViewMore')
    		        </a>
    		        ## Register a global script for all status stories that handles expansions
    		        #registerEndOfPageHtml('status-message-story')
    		            <script>
    		                jQuery(function(j){
    		                    j.telligent.evolution.messaging.subscribe('expand-status-message', function(e) {
    		                        var link = j(e.target);
    		                        var wrapper = j('#' + link.data('wrapper'));
    		                        var messageId = link.data('messageid');
    		                        var userId = link.data('userid');
    		                        
    		                        // Load the full status message via REST
                                    j.telligent.evolution.get({
                                    	url: j.telligent.evolution.site.getBaseUrl() + 'api.ashx/v2/users/{userid}/statuses/{messageid}.json',
                                    	data: { 
                                    		userid: userId,
                                    		messageid: messageId
                                    	}
                                    }).done(function(r){
                                        // Render the full status body and hide the view link
                                    	wrapper.html(r.StatusMessage.Body);
                                    	link.hide();
                                    });		                        
    		                    })
    		                });
    		            </script>
    		        #end
    		    #else 
    		        $renderedMessage
    		    #end
    		</div>
    
    		#set($attachmentUrl = $context.AttachmentUrl)
    		#set($referencedUrl = $context.ReferencedUrl)
    		#set($attachmentIsExplicit = true)
    		#if (!$attachmentUrl || $attachmentUrl == '')
    			#set($attachmentUrl = $referencedUrl)
    		    #set($attachmentIsExplicit = false)
    		#end
    		#if ($attachmentUrl && $attachmentUrl != '')
    			#set($hasAccess = $context.HasAccessToUrl($attachmentUrl))
    
    			#if ($attachmentIsExplicit && !$hasAccess)
    				<div class="post-attachment-viewer access-denied">$core_v2_language.GetResource('attachment_access_denied')</div>
    			#elseif($hasAccess)
    				#set ($mediaType = $core_v2_ui.GetMediaType($attachmentUrl, "%{ ViewType = 'View', OutputIsPersisted='False' }"))
    				#if($mediaType == 'Audio' || $mediaType == 'Video')
    					<div class="post-attachment-viewer">
    						$core_v2_ui.GetViewHtml($attachmentUrl, "%{ Width=320, Height=240, OutputIsPersisted = 'false' }")
    					</div>
    				#elseif ($mediaType == 'Image')
    					<div class="post-attachment-viewer">
    						<a href="$core_v2_encoding.HtmlAttributeEncode($attachmentUrl)" class="internal-link" data-imagepreviewurl="$core_v2_encoding.HtmlAttributeEncode($attachmentUrl)">
    							$!core_v2_ui.GetPreviewHtml($attachmentUrl, "%{Width=320, Height=240, OutputIsPersisted='False'}")
    						</a>
    					</div>
    				#elseif ($mediaType != 'Empty')
    					#set ($theaterUrl = $context.TheaterUrl())
    					<div class="post-attachment-viewer">
    						<a href="$core_v2_encoding.HtmlAttributeEncode($attachmentUrl)" class="internal-link ui-theater" data-theaterurl="$core_v2_encoding.HtmlAttributeEncode($core_v2_widget.GetExecutedFileUrl('theater-view.vm'))">
    							$!core_v2_ui.GetPreviewHtml($attachmentUrl, "%{Width=56, Height=56, OutputIsPersisted='False'}")
    						</a>
    					</div>
    				#else
    					<div class="post-attachment-viewer">
    						<a href="$core_v2_encoding.HtmlAttributeEncode($attachmentUrl)" class="internal-link">
    							$!core_v2_ui.GetPreviewHtml($attachmentUrl, "%{Width=56, Height=56, OutputIsPersisted='False'}")
    						</a>
    					</div>
    				#end
    		    #end
    	    #end
        #end
    #end
    ]]></contentScript>
    		<languageResources><language key="en-us">
      <resource name="attachment_access_denied">You do not have permission to view the attachment.</resource>
      <resource name="Delete">Delete</resource>
      <resource name="discussed_by">Discussed by</resource>
      <resource name="download">Download</resource>
      <resource name="in">{user}:</resource>
      <resource name="in_group">{user} in {group}:</resource>
      <resource name="serp_type">status</resource>
      <resource name="StatusMessage_Preview">{user}: {message}</resource>
      <resource name="StatusMessage_Preview_InGroup">{user} in {group}: {message}</resource>
      <resource name="StatusMessageActivityStory_Description">Story for status messages.</resource>
      <resource name="StatusMessageActivityStory_Name">StatusMessage Activity Story</resource>
      <resource name="UserProfile_Html">&lt;span class="user-name"&gt;&lt;a href="{1}" class="internal-link view-user-profile activity-summary-user"&gt;{0}&lt;/a&gt;&lt;/span&gt;</resource>
      <resource name="view">View</resource>
      <resource name="ViewMore">View More</resource>
      <resource name="WriteComment">Write a comment...</resource>
    </language></languageResources>
    		<files>
    			<file name="theater-view.vm">I3NldCgkYXR0YWNobWVudFVybCA9ICRjb250ZXh0LkF0dGFjaG1lbnRVcmwpDQojaWYgKCEkYXR0YWNobWVudFVybCB8fCAkYXR0YWNobWVudFVybCA9PSAnJykNCiAgICAjc2V0KCRhdHRhY2htZW50VXJsID0gJGNvbnRleHQuUmVmZXJlbmNlZFVybCkNCiNlbmQNCiNpZiAoJGF0dGFjaG1lbnRVcmwgJiYgJGF0dGFjaG1lbnRVcmwgIT0gJycgJiYgJGNvbnRleHQuSGFzQWNjZXNzVG9VcmwoJGF0dGFjaG1lbnRVcmwpKQ0KICAgICRjb3JlX3YyX3VpLkdldFZpZXdIdG1sKCRhdHRhY2htZW50VXJsLCAiJXsgT3V0cHV0SXNQZXJzaXN0ZWQgPSAnZmFsc2UnLCBBZGp1c3RUb0NvbnRhaW5lciA9ICd0cnVlJyB9IikNCiNlbmQ=</file>
    		</files>
    	</scriptedContentFragment>
    </scriptedContentFragments>

  • We'll check it out.. I did not make the mental mind map that More-->MOVE will lead to a content conversion dialog. I like your solution. We'll be back and report

  • We checked it out

    1. The code works, only half way. So it expands but there is no menu to toggle back to collapsed state
    2. The "MOVE Status Message to..." works for Forum and Media (if media is posted) but not for Blog which is of course strange because the prime candidate for a long Status Message is a Blog.
  • The code works, only half way. So it expands but there is no menu to toggle back to collapsed state

    The code provided is just a sample to show how this kind of stream behavior can be modified in a supported manner on the platform with a minimal widget editing. If you want a "show less" toggle, you can add that too.

    The "MOVE Status Message to..." works for Forum and Media (if media is posted) but not for Blog which is of course strange because the prime candidate for a long Status Message is a Blog.

    Unfortunately, that is the case OOTB. However, there's platform support for customizing content conversion (for both platform content types or any custom content types) through the use of content converter plugins.