Adding Fields to a Widget Content Type - Documentation topics on: widget content type,widgets,widget type,.

Adding Fields to a Widget Content Type

Widget Types are created by webmasters so that Content Publishers can create their own dynamic pulls of any type of content, even content that lives outside of dotCMS (YouTube, Vimeo, etc.), without any code.

In addition to the four System Fields that are automatically created by a Widget Type, additional fields can be created by a dotCMS webmaster that can act as parameter fields that will be used in the either the Widget Code or Widget Pre-execute fields. In the example of the News Listing Widget Type below, additional parameter fields have been added to allow users of the Widget Type to create their own customized, re-usable widgets (dynamic pulls of content).

System Fields on all Widget Content Types

  • Widget Title - Allows users to title their own dynamic listing for the widget content listing they are creating
  • Widget Usage - Tells the content publisher how to use the widget
  • Widget Code - Code that performs all the work, and takes the parameter settings from the fields to create the dynamic listing
  • Widget Pre-execute - Code field which executes before the Widget Code field for pre-loading purposes (optional)

Custom fields example on the News Listing widget (demo.dotcms.com)

In the example below from the News Listing widget, users can customize their pull by setting the following:

  • Headline - Allows users to create their own descriptive Headline that will appear above the dynamic listing
  • Headline font size - Allows users to adjust the font size of the headline above the listing
  • Number of Results - Sets the total number of new articles to pull dynamically
  • Fields to display - Checkbox for users to decide which fields to display in the dynamic pull (Title, Summary, Image, Publish Date, Comments)
  • Tags - Sets the tag(s) which will filter the widget listing of news content
  • Topic - Sets the category(ies) which will filter the widget listing of news content
  • Pagination - Checkbox to decide if the listing should be paginated
  • Items per page - If the user has selected pagination, this field sets the number to pull per page
  • Sort order - Determines the order in which the content should list


The widget code field does all the work in pulling the fields set by the content contributor using the widget. The widget code below can be found in the News Listing Widget Type that is packaged with the starter site included when downloading dotCMS (also on demo.dotcms.com).

The following is a code example from the /application/vtl/widgets/news/personalized-news-listing.vtl used by the News Listing Widget code field on demo.dotcms.com.

Note that the code below detects if the $numberOfResults, $sortResultsBy, topic (category field), tag (tag field), etc., have been set in the parameters of the News Listing widget content. This way the user who is setting the parameters of the widget, can create complex filtered and sorted listings of content, without writing a single line of code.

## --------------------------------------------------
## SETTING THE DEFAULT NUMBER OF RESULTS ------------
## --------------------------------------------------
#if (!$UtilMethods.isSet($numberOfResults))
  #set($numberOfResults = 5)
#end


## --------------------------------------------------
## SETTING THE SORT ORDER ---------------------------
## --------------------------------------------------
#set ($sortBy = "News.sysPublishDate")
#if ($sortResultsBy == "title")
  #set ($sortBy = "News.title")
#elseif ($sortResultsBy == "comments")
  #set ($sortBy = "News.commentscount")
#end
#set ($sortBy = "News.sysPublishDate $sortOrder1")


## --------------------------------------------------
## FILTER BY CATEGORIES -----------------------------
## --------------------------------------------------
#set($catsQuery = "")
#foreach ($catInode in $topic)
  #if ($velocityCount == 1)
    #set($catsQuery = "categories:$categories.getCategoryByInode($catInode).categoryVelocityVarName")
  #else
    #set($catsQuery = "$catsQuery categories:$categories.getCategoryByInode($catInode).categoryVelocityVarName")
  #end
#end
#if ($UtilMethods.isSet($catsQuery))
  #set($catsQuery = "+($catsQuery)")
#end


#set($ignoreQuery="")
#if($UtilMethods.isSet($URLMapContent.inode))

    #set($ignoreQuery="-inode:$URLMapContent.inode")
#end


## --------------------------------------------------
## FILTERS BY TAGS ----------------------------------
## --------------------------------------------------

#set($tagsQuery = "")
#if ($UtilMethods.isSet($tagsFilter))
  #foreach ($tag in $tagsFilter.split(','))
    #if ($velocityCount == 1)
      #set($tagsQuery = "News.tags:$tag")
    #else
      #set($tagsQuery = "$tag News.tags:$tag")
    #end
  #end
#end


## --------------------------------------------------
## SETTING PAGINATED RESULTS ------------------------
## --------------------------------------------------

#if($pagination.contains('true'))
  ## SETTING ITEMS PER PAGE
  #if ($UtilMethods.isSet($itemsPerPage))
    #set($itemsPerPage = $webapi.parseInt($itemsPerPage))
  #else
    #set($itemsPerPage = 5)
  #end

  ## GETTING PAGE NUMBER
  #if($UtilMethods.isSet($request.getParameter('page')))
    #set($page = $webapi.parseInt($request.getParameter('page')))
  #else
    #set($page = 1)
  #end
#end
#set($myHost = $webapi.resolveHostName($request.serverName))

#if($pagination.contains('true'))
  #set($newsListing = $dotcontent.pullPersonalized("+structureName:News +(conhost:$!{myHost.identifier} conhost:SYSTEM_HOST) $!{catsQuery} $!{tagsQuery} ${ignoreQuery}",$itemsPerPage,0,"$!{sortBy}"))
#else
  #set($newsListing = $dotcontent.pullPersonalized("+structureName:News +(conhost:$!{myHost.identifier} conhost:SYSTEM_HOST) $!{catsQuery} $!{tagsQuery} ${ignoreQuery}",$!{numberOfResults},"$!{sortBy}"))
#end

<!--
$newsListing.query
-->
#if($newsListing.size() > 0)
  #if ($UtilMethods.isSet($headline))
    #if (!$UtilMethods.isSet($headlineFontSize))
      #set ($headlineFontSize = '1')
    #end
    <h$!{headlineFontSize} class="news-listing-headline">$!{headline}</h$!{headlineFontSize}>
  #end
  <ul class="media-list media-list-extend news-listing">
  #foreach ($newsItem in $newsListing)
    <li class="media">
      <article>
        #editContentlet($newsItem.inode)
        #if ($fieldsToDisplay.contains('image') && $UtilMethods.isSet($newsItem.image.rawUri))
          <a href="/news/$!{newsItem.urlTitle}" class="pull-left media-object">
            <img src="/dA/$!{newsItem.identifier}/image/filter/Resize/resize_w/100" alt="$!{newsItem.title}" />
          </a>
        #end
        <div class="media-body">
          #if($fieldsToDisplay.contains('title') && $UtilMethods.isSet($newsItem.urlTitle))
            <h4 class="media-heading news-title"><a href="/news/$!{newsItem.urlTitle}">$!{newsItem.title}</a></h4>
          #end
          #if($fieldsToDisplay.contains('publishDate') && $UtilMethods.isSet($newsItem.sysPublishDate) || $fieldsToDisplay.contains('commentsCount') &&  $UtilMethods.isSet($newsItem.commentscount))
            <div class="post-info">
              #if($fieldsToDisplay.contains('publishDate') && $UtilMethods.isSet($newsItem.sysPublishDate))
                <time class="date" datetime="$!{newsItem.sysPublishDate}">$date.format('MMMM d, yyyy', $newsItem.sysPublishDate)</time>
              #end
              #if($fieldsToDisplay.contains('commentsCount') && $UtilMethods.isSet($newsItem.commentscount))
                #set ($comments = "Comment")
                #if ($newsItem.commentscount > 1)
                  #set ($comments = "Comments")
                #end
                <span class="comments"><a href="/news/$!{newsItem.urlTitle}#comments">$!{newsItem.commentscount} $!{comments}</a></span>
              #end
            </div>
          #end
          #if ($fieldsToDisplay.contains('summary') && $UtilMethods.isSet($newsItem.lead))
            <p class="summary">$!{newsItem.lead}</p>
          #end
        </div>
      </article>
    </li>
  #end
  </ul>
  #if($pagination.contains('true'))
    <div class="text-center">
      <ul class="pagination">
        #if($newsListing.previousPage)
          <li><a href="/news-events/news/?page=$!{math.sub($page, 1)}">«</a></li>
        #end
        #foreach($i in [1..$newsListing.totalPages])
          <li #if($page == $velocityCount)class="active"#end><a href="/news-events/news/?page=${velocityCount}">$velocityCount</a></li>
        #end
        #if($newsListing.nextPage)
          <li><a href="/news-events/news/?page=$!{math.add($page, 1)}">»</a></li>
        #end
      </ul>
    </div>
  #end
#else
  <div class="alert alert-info">
    No results for this query, try with another categories or tags.
  </div>
#end