  
                    





          
          
  




<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh" xml:lang="zh">
  <head>
                    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
                                    <title>BROPEN - Macros for the Blog application (Blog.BlogCode)</title>
                        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                <link rel="shortcut icon" href="/xwiki/resources/favicon.ico" />
        <link rel="icon" href="/xwiki/resources/favicon16.png" type="image/png" />
                <link rel="apple-touch-icon" href="/xwiki/resources/favicon144.png" />
                <meta http-equiv="Content-Script-Type" content="text/javascript" />
                        <meta http-equiv="imagetoolbar" content="no"/>
                                <link rel="canonical" href="xwiki.Blog.BlogCode.html" />
                            <meta name="document" content="Blog.BlogCode"/>
    <meta name="wiki" content="xwiki"/>
    <meta name="space" content="Blog"/>
    <meta name="page" content="BlogCode"/>
    <meta name="version" content="2.1"/>
    <meta name="restURL" content="/xwiki/rest/wikis/xwiki/spaces/Blog/pages/BlogCode"/>
    <meta name="form_token" content="HaxWJBFR9QApx58YMhjexA"/>
                <meta name="gwt:property" content="locale=zh" />
                <meta name="revisit-after" content="7 days" />
<meta name="description" content="Macros for the Blog application" />
<meta name="keywords" content="wiki" />
<meta name="distribution" content="GLOBAL" />
<meta name="rating" content="General" />
<meta name="author" content="Administrator" />
<meta http-equiv="reply-to" content="" />
<meta name="language" content="zh" />
<link rel="alternate" type="application/rss+xml" title="Wiki Feed RSS" href="https://service.bropen.com.cn/xwiki/bin/view/Main/WebRss?xpage=rdf" />
<link rel="alternate" type="application/rss+xml" title="Blog RSS Feed" href="https://service.bropen.com.cn/xwiki/bin/view/Blog/GlobalBlogRss?xpage=plain" />

                <!-- com.xpn.xwiki.plugin.skinx.LinkExtensionPlugin -->
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
<link href="skins/colibri/style.css?colorTheme=ColorThemes.Dusk" rel="stylesheet" type="text/css" media="all" />
<link href="skins/colibri/print.css?colorTheme=ColorThemes.Dusk" rel="stylesheet" type="text/css" media="print" />
        <!--[if IE]>
  <link href="skins/colibri/ie-all.css?colorTheme=ColorThemes.Dusk" rel="stylesheet" type="text/css" />
<![endif]-->
    <!-- com.xpn.xwiki.plugin.skinx.CssResourceSkinExtensionPlugin -->
  <!-- com.xpn.xwiki.plugin.skinx.CssSkinExtensionPlugin -->
  <!-- com.xpn.xwiki.plugin.skinx.CssSkinFileExtensionPlugin -->

    



  
  
                                                                                                                                                                                                                      
    
      <!-- com.xpn.xwiki.plugin.skinx.JsResourceSkinExtensionPlugin -->
    <!-- com.xpn.xwiki.plugin.skinx.JsSkinFileExtensionPlugin -->
    <!-- com.xpn.xwiki.plugin.skinx.JsSkinExtensionPlugin -->

<script type="text/javascript" src="resources/js/xwiki/compatibility.js" defer="defer"></script>
<script type="text/javascript" src="resources/js/xwiki/markerScript.js" defer="defer"></script>
<script type="text/javascript">
// <![CDATA[
require.config({
  baseUrl: '/',
    paths: { 'jquery': "resources/js/amd/jquery" },
  map: {
    '*': { 'jquery': 'jQueryNoConflict' },
    'jQueryNoConflict': { 'jquery': 'jquery' }
  }
});
define('jQueryNoConflict', ['jquery'], function($) { $.noConflict(); return $; });
XWiki.webapppath = "xwiki/";
XWiki.servletpath = "bin/";
XWiki.contextPath = "/xwiki";
XWiki.mainWiki = "xwiki";
XWiki.currentWiki = "xwiki";
XWiki.currentSpace = "Blog";
XWiki.currentPage = "BlogCode";
XWiki.editor = "";
XWiki.viewer = "";
XWiki.contextaction = "export";
XWiki.docisnew = false;
XWiki.docsyntax = "xwiki/2.1";
XWiki.docvariant = "";
XWiki.blacklistedSpaces = [ "Import","Panels","Scheduler","Stats","XAppClasses","XAppSheets","XAppTemplates","XWiki","WatchCode","WatchSheets","XApp","WatchAdmin","Watch","ColorThemes","AnnotationCode" ];
XWiki.hasEdit = false;
XWiki.hasProgramming = false;
XWiki.hasBackupPackImportRights = false;
XWiki.hasRenderer = true;
window.docviewurl = "xwiki.Blog.BlogCode.html";
window.docediturl = "";
window.docsaveurl = "";
window.docgeturl = "";
// ]]>
</script>

		<script>var o = {
			name: 'XWikiGuest',
			username:'XWikiGuest',
			ip:'216.73.216.109, ::1',
															j:'B53B048D4109FDF8902C659C01FDD474'}</script>
  </head>
  <body id="body" class="wiki-xwiki space-Blog viewbody  doc-Blog_BlogCode admin_false">
<div id="xwikimaincontainer">
<div id="xwikimaincontainerinner">

  <div id="menuview">
    <div id="mainmenu" class="layoutsubsection actionmenu">
<div class="gradientfilterIE"></div>
<div class="componentcontainer">
<strong id="xwikimenutitle" class="hidden">一般动作</strong>
<div class="rightmenu">
      <div id="tmLogin" class="tmLogin topmenuentry ">
   <a class="tme" href=""><strong>登录</strong></a>
  </div>
  </div>
<div class="leftmenu">
            <div id="tmWiki" class="tmWiki topmenuentry dropdownmenuentry dropdownnolink hasIcon" onmouseover="showsubmenu(this);" onmouseout="hidesubmenu(this);">
<span class="tme-extensible">
              <span class="tmetype">Wiki: </span><a class="tme hastype" href=""><strong>BROPEN</strong></a>
         <span class="menuarrow">&#9660;</span><span class="hidden menucolon">: </span>
</span><span class="submenu hidden">
                        <span class="submenuitem "><a href="" id="tmWikiDocumentIndex" class="tmWikiDocumentIndex">Document Index</a></span>
            </span></div>
  <div class="topmenuentry"><span class="separator">&raquo;</span></div>
  <div id="tmSpace" class="tmSpace topmenuentry dropdownmenuentry dropdownnolink hasIcon" onmouseover="showsubmenu(this);" onmouseout="hidesubmenu(this);">
<span class="tme-extensible">
              <span class="tmetype">Space: </span><a class="tme hastype" href=""><strong>Blog</strong></a>
         <span class="menuarrow">&#9660;</span><span class="hidden menucolon">: </span>
</span><span class="submenu hidden">
              <span class="submenuitem "><a href="" id="tmSpaceDocumentIndex" class="tmSpaceDocumentIndex">Document Index</a></span>
      </span></div>
<div class="topmenuentry"><span class="separator">&raquo;</span></div>
  <div id="tmPage" class="tmPage topmenuentry hasIcon">
              <span class="tmetype">Page: </span><a class="tme hastype" href="xwiki.Blog.BlogCode.html"><strong>BlogCode</strong></a>
       </div>
</div>
</div>
</div>

  </div>
 <div id="headerglobal" class="layoutsection">
<div class="minwidthd"></div>
  <div id="company">
  <div id="companylogo">
    <a href="" title="Home" rel="home">
    <img src="/xwiki/resources/logo_bropen.png" alt="Wiki Logo"/>
    </a>
  </div>   </div>   <div id="globallinks">
        <form action="">
      <div class="globalsearch">
        <label class="hidden" for="headerglobalsearchinput">搜索</label><input class="globalsearchinput withTip" id="headerglobalsearchinput" type="text" name="text" value="查找中......" size="15"/><input class="button" type="image" value="查找" alt="查找" src="resources/icons/xwiki/search.png"/>
      </div>
    </form>
      <span class="glink" id="headerlanguages">
            <a href="xwiki.Blog.BlogCode.html" class="language-default language-current">default</a>
      </span>
  </div>   <div class="clearfloats"></div>
  </div> 

<div class="content" id="contentcontainer">
<div id="contentcontainerinner">
<div class="leftsidecolumns">
  <div id="contentcolumn"> 
        <div class="main layoutsubsection">
      <div id="contentmenu" class="actionmenu">
    <div class="gradientfilterIE"></div>
<div class="componentcontainer">
<strong id="xwikicontentmenutitle" class="hidden">页面动作</strong>
<div class="rightmenu">
</div>
<div class="leftmenu">
  <div id="tmExport" class="tmExport topmenuentry dropdownmenuentry dropdownnolink " onmouseover="showsubmenu(this);" onmouseout="hidesubmenu(this);">
<span class="tme-extensible">
   <a class="tme"><strong>导出</strong></a>
    <span class="menuarrow">&#9660;</span><span class="hidden menucolon">: </span>
</span><span class="submenu hidden">
    <span class="submenuitem "><a href="xwiki.Blog.BlogCode.html" id="tmExportPdf" class="tmExportPdf">以PDF格式导出</a></span>
    <span class="submenuitem "><a href="" id="tmExportRtf" class="tmExportRtf">以RTF格式导出</a></span>
  <span class="submenuitem "><a href="" id="tmExportHtml" class="tmExportHtml">以HTML格式导出</a></span>
    </span></div>
  <div id="tmMoreActions" class="tmMoreActions topmenuentry dropdownmenuentry dropdownnolink " onmouseover="showsubmenu(this);" onmouseout="hidesubmenu(this);">
<span class="tme-extensible">
   <a class="tme"><strong>更多动作</strong></a>
    <span class="menuarrow">&#9660;</span><span class="hidden menucolon">: </span>
</span><span class="submenu hidden">
  <span class="submenuitem "><a href="xwiki.Blog.BlogCode.html" id="tmPrintPreview" class="tmPrintPreview">打印预览</a></span>
  <span class="submenuitem "><a href="xwiki.Blog.BlogCode.html" id="tmViewSource" class="tmViewSource">察看源码</a></span>
  </span></div>
  </div>
</div>
    </div>
    <div id="mainContentArea">
  
   <div id="hierarchy">
                                          <a href=''>欢迎进入Wiki</a> <span class='separator'>&#187;</span> <a href=''>The Wiki Blog</a> <span class='separator'>&#187;</span> <span class='current'>Macros for the Blog application</span>
                      </div>

      <div id="document-title"><h1>Wiki源代码<a href="xwiki.Blog.BlogCode.html">Macros for the Blog application</a></h1></div>
                        <div id="document-info">
    <div class="xdocLastModification">       在2013-10-09 15:03上被<span class="wikilink"><a href="">Administrator</a></span>修改
    </div>
    <div>
                      <span id="commentsshortcut"><a href="xwiki.Blog.BlogCode.html">评论</a> <span class="itemCount">(0)</span></span>
               <span class="separator">&#183;</span>         <span id="attachmentsshortcut"><a href="xwiki.Blog.BlogCode.html">附件</a> <span class="itemCount">(0)</span></span>
               <span class="separator">&#183;</span>         <span id="historyshortcut"><a href="xwiki.Blog.BlogCode.html">记录</a></span>
               <span class="separator">&#183;</span>         <span id="informationshortcut"><a href="xwiki.Blog.BlogCode.html">信息</a></span>
          </div>
    <div class="clearfloats"></div>
  </div>

<div>
  <a href="xwiki.Blog.BlogCode.html" id="toggleLineNumbers">隐藏行号</a>
                                  <textarea readonly="readonly" class="wiki-code" rows="25" cols="80">
  1: {{include document=&quot;Blog.BlogParameters&quot;/}}
  2: 
  3: {{velocity output=&quot;false&quot;}}
  4: ##
  5: ##
  6: ##
  7: ## Import the blog skin and javascripts.
  8: $!xwiki.ssx.use($blogStyleDocumentName)##
  9: $!xwiki.jsx.use($blogScriptsDocumentName)##
 10: ##
 11: ##
 12: ##
 13: #**
 14:  * Prints a blog. This is the main macro used in the BlogSheet.
 15:  * 
 16:  * @param blogDoc the XDocument holding the blog definition object.
 17:  *###
 18: #macro(printBlog $blogDoc)
 19:   {{include document='Blog.CreatePost'/}}
 20:   #getBlogEntries($blogDoc $entries)
 21:   #displayBlog($entries 'index' true true)
 22:   #displayNavigationLinks($blogDoc)
 23: #end
 24: ##
 25: ##
 26: ##
 27: #**
 28:  * Shows blog information. In view mode, the description is printed. In edit mode, allows changing blog settings: title,
 29:  * description, blog type (global or in-space), index display type (fixed size pagination, weekly index, monthly index,
 30:  * all entries).
 31:  * 
 32:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
 33:  *###
 34: #macro(showBlogInfo $blogDoc)
 35:   #if($blogDoc.getObject($blogClassname))
 36:     ## Keep testing for inline action for backward compatibility with older blogs.
 37:     #if($xcontext.action == 'edit' || $xcontext.action == 'inline')
 38:       #macro(displayProperty $blogDoc $propname)
 39:         ; #displayPropName($xwiki.getClass($blogClassname).get($propname)):
 40:         : $blogDoc.display($propname)
 41:       #end
 42:       #displayProperty($blogDoc 'title')
 43:       #displayProperty($blogDoc 'description')
 44:       #displayProperty($blogDoc 'blogType')
 45:       #displayProperty($blogDoc 'displayType')
 46:       #displayProperty($blogDoc 'itemsPerPage')
 47:     #else
 48:       $blogDoc.display('description')
 49:     #end
 50:   #elseif($doc.fullName == $blogSheet)
 51: = $services.localization.render('xe.blog.code.blogsheet') =
 52:     {{translation key='xe.blog.code.sheetexplanation'/}}
 53:   #else
 54:     {{warning}}{{translation key='xe.blog.code.notblog'/}}{{/warning}}
 55:   #end
 56: #end
 57: ##
 58: ##
 59: ##
 60: #**
 61:  * Retrieve the blog document, which usually is either &lt;tt&gt;&amp;lt;Space&amp;gt;.WebHome&lt;/tt&gt; for whole-spaces blogs, or
 62:  * &lt;tt&gt;&amp;lt;Space&amp;gt;.Blog&lt;/tt&gt; for in-space blogs. If none of these documents contains a blog object, then the first
 63:  * (alphabetically) document in the target space that contains one is returned. Finally, if no document in the current
 64:  * space contains a blog object, then &lt;tt&gt;Blog.WebHome&lt;/tt&gt; is returned as the default blog.
 65:  * 
 66:  * @param space A &lt;tt&gt;String&lt;/tt&gt;, the name of the space where to search.
 67:  * @param blogDoc The resulting XDocument.
 68:  *###
 69: #macro(getBlogDocument $space $blogDoc)
 70:   ## First, try the Space.WebHome, for a whole-space blog
 71:   #set($result = $xwiki.getDocument(&quot;${space}.WebHome&quot;))
 72:   #if(!$result.getObject($blogClassname))
 73:     ## Second, try the Space.Blog document
 74:     #set($result = $xwiki.getDocument(&quot;${space}.Blog&quot;))
 75:     #if(!$result.getObject($blogClassname))
 76:       ## Third, try searching for a blog document in the current space
 77:       #set($blogDocs = $services.query.hql(&quot;, BaseObject obj where doc.space = ? and obj.name = doc.fullName and obj.className = '$blogClassname' order by doc.name&quot;).setLimit(1).setOffset(0).bindValues([${space}]).execute())
 78:       #if($blogDocs.size() &gt; 0)
 79:         #set($result = $xwiki.getDocument($blogDocs.get(0)))
 80:       #else
 81:         ## Last, fallback to Blog.WebHome, the default blog
 82:         #set($result = $xwiki.getDocument('Blog.WebHome'))
 83:       #end
 84:     #end
 85:   #end
 86:   #set ($blogDoc = $NULL)
 87:   #setVariable (&quot;$blogDoc&quot; $result)
 88: #end
 89: ##
 90: ##
 91: ##
 92: #**
 93:  * Retrieve the blog title.
 94:  * 
 95:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;tt&gt; object with the &lt;tt&gt;title&lt;/tt&gt; property set.
 96:  * @param title The resulting title.
 97:  *###
 98: #macro(getBlogTitle $blogDoc $title)
 99:   #getBlogProperty($blogDoc 'title' $!blogDoc.displayTitle $result)
100:   #set ($title = $NULL)
101:   #setVariable (&quot;$title&quot; $result)
102: #end
103: ##
104: ##
105: ##
106: #**
107:  * Retrieve the blog description.
108:  * 
109:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object with the &lt;tt&gt;description&lt;/tt&gt;
110:  *        property set.
111:  * @param description The resulting description.
112:  *###
113: #macro(getBlogDescription $blogDoc $description)
114:   #getBlogProperty($blogDoc 'description' '' $result)
115:   #set ($description = $NULL)
116:   #setVariable (&quot;$description&quot; $result)
117: #end
118: ##
119: ##
120: ##
121: #**
122:  * Retrieves a list of entries to be displayed. The entries are either part of the blog's space, or have the blog
123:  * document set as a parent. The number and range of entries returned (from all those belonging to this blog) depends on
124:  * the blog display type: paginated (fixed number of entries), weekly (all entries in a week), monthly (all entries in a
125:  * month), or all.
126:  * 
127:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
128:  * @param entries The resulting list of entries to display, a list of XDocument names.
129:  *###
130: #macro(getBlogEntries $blogDoc $entries)
131:   #if (!$entries)
132:     #setVariable (&quot;$entries&quot; [])
133:   #end
134:   #getBlogEntriesBaseQuery($query)
135:   #isBlogGlobal($blogDoc $isGlobal)
136:   #if(!$isGlobal)
137:     #set($query = &quot;${query} and (doc.space = '${blogDoc.space}' or doc.parent = '${blogDoc.fullName}')&quot;)
138:   #end
139:   #getBlogDisplayType($blogDoc $displayType)
140:   #if($displayType == 'weekly')
141:     #getWeeklyBlogEntries($blogDoc $query $entries)
142:   #elseif($displayType == 'monthly')
143:     #getMonthlyBlogEntries($blogDoc $query $entries)
144:   #elseif($displayType == 'all')
145:     #getAllBlogEntries($blogDoc $query $entries)
146:   #else
147:     #getPagedBlogEntries($blogDoc $query $entries)
148:   #end
149: #end
150: ##
151: ##
152: ##
153: #**
154:  * Retrieves a list of entries to be displayed. The entries are taken from a &quot;page&quot; of the blog, a sequence of documents
155:  * defined by the request parameters &lt;tt&gt;ipp&lt;/tt&gt; (items per page) and &lt;tt&gt;page&lt;/tt&gt; (the current page). Initially the
156:  * first page is displayed, with the number of entries defined in the blog object in the &lt;tt&gt;itemsPerPage&lt;/tt&gt; property 
157:  * (10 if not defined).
158:  * 
159:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
160:  * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
161:  *        refined to restrict to a given space, or to a given search criteria, etc.
162:  * @param entries The resulting list of entries to display, a list of XDocument names.
163:  *###
164: #macro(getPagedBlogEntries $blogDoc $query $entries)
165:   #if (!$entries)
166:     #setVariable (&quot;$entries&quot; [])
167:   #end
168:   #set($totalEntries = $services.query.hql($query).count())
169:   #getBlogProperty($blogDoc 'itemsPerPage' '10' $defaultItemsPerPage)
170:   #set($defaultItemsPerPage = $mathtool.toInteger($defaultItemsPerPage))
171:   ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
172:   #preparePagedViewParams($totalEntries $defaultItemsPerPage)
173:   #set($discard = $entries.addAll($services.query.hql(&quot;${query} order by publishDate.value desc&quot;).setLimit($itemsPerPage).setOffset($startAt).execute()))
174: #end
175: ##
176: ##
177: ##
178: #**
179:  * Retrieves a list of entries to be displayed. The entries are taken from a week of the blog. The target week is
180:  * defined by the request parameters &lt;tt&gt;week&lt;/tt&gt; (the week number in the year, from 1 to 52) and &lt;tt&gt;year&lt;/tt&gt; (4 
181:  * digit year). Initially the current week is displayed.
182:  * 
183:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
184:  * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
185:  *        refined to restrict to a given space, or to a given search criteria, etc.
186:  * @param entries The resulting list of entries to display, a list of XDocument names.
187:  *###
188: #macro(getWeeklyBlogEntries $blogDoc $query $entries)
189:   #if (!$entries)
190:     #setVariable (&quot;$entries&quot; [])
191:   #end
192:   #getRequestedWeek($weekDate)
193:   #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
194:   #set($minDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundFloor()))
195:   #set($maxDay = $dateFormatter.print($weekDate.toMutableDateTime().weekOfWeekyear().roundCeiling()))
196:   #set($query = &quot;${query} and publishDate.value &gt;= '$minDay' and publishDate.value &lt; '$maxDay'&quot;)
197:   #set($totalEntries = $services.query.hql($query).count())
198:   #set($discard = $entries.addAll($services.query.hql(&quot;${query} order by publishDate.value desc&quot;).execute()))
199: #end
200: ##
201: ##
202: ##
203: #**
204:  * Retrieves a list of entries to be displayed. The entries are taken from a month of the blog. The target month is
205:  * defined by the request parameters &lt;tt&gt;month&lt;/tt&gt; (the month number, from 1 to 12) and &lt;tt&gt;year&lt;/tt&gt; (4 
206:  * digit year). Initially the current month is displayed.
207:  * 
208:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
209:  * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
210:  *        refined to restrict to a given space, or to a given search criteria, etc.
211:  * @param entries The resulting list of entries to display, a list of XDocument names.
212:  *###
213: #macro(getMonthlyBlogEntries $blogDoc $query $entries)
214:   #if (!$entries)
215:     #setVariable (&quot;$entries&quot; [])
216:   #end
217:   #getRequestedMonth($monthDate)
218:   #set($dateFormatter = $xwiki.jodatime.getDateTimeFormatterForPattern('yyyy-MM-dd'))
219:   #set($minDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundFloor()))
220:   #set($maxDay = $dateFormatter.print($monthDate.toMutableDateTime().monthOfYear().roundCeiling()))
221:   #set($query = &quot;${query} and publishDate.value &gt;= '$minDay' and publishDate.value &lt; '$maxDay'&quot;)
222:   #set($totalEntries = $services.query.hql($query).count())
223:   #set($discard = $entries.addAll($services.query.hql(&quot;${query} order by publishDate.value desc&quot;).execute()))
224: #end
225: ##
226: ##
227: ##
228: #**
229:  * Retrieves a list of entries to be displayed. All entries belonging to the current blog are returned.
230:  * 
231:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
232:  * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
233:  *        refined to restrict to a given space, or to a given search criteria, etc.
234:  * @param entries The resulting list of entries to display, a list of XDocument names.
235:  *###
236: #macro(getAllBlogEntries $blogDoc $query $entries)
237:   #if (!$entries)
238:     #setVariable (&quot;$entries&quot; [])
239:   #end
240:   #set($totalEntries = $services.query.hql($query).count())
241:   #set($discard = $entries.addAll($services.query.hql(&quot;${query} order by publishDate.value desc&quot;).execute()))
242: #end
243: ##
244: ##
245: ##
246: #**
247:  * Retrieves a list of entries to be displayed. Only (and all) unpublished entries are returned.
248:  * 
249:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
250:  * @param query The base query for selecting entries. Apart from the base query that selects entries, it can further be
251:  *        refined to restrict to a given space, or to a given search criteria, etc.
252:  * @param entries The resulting list of entries to display, a list of XDocument names.
253:  *###
254: #macro(getUnpublishedBlogEntries $blogDoc $query $entries)
255:   #if (!$entries)
256:     #setVariable (&quot;$entries&quot; [])
257:   #end
258:   #set($query = &quot;${query} and isPublished.value = 0&quot;)
259:   #set($totalEntries = $services.query.hql($query).count())
260:   #set($discard = $entries.addAll($services.query.hql(&quot;${query} order by publishDate.value desc&quot;).execute()))
261: #end
262: ##
263: ##
264: ##
265: #**
266:  * Retrieves a list of entries to be displayed. The entries are taken from all the wiki, and not from a specific blog.
267:  * 
268:  * @param entries The resulting list of entries to display, a list of XDocument names.
269:  *###
270: #macro(getGlobalBlogEntries $entries)
271:   #if (!$entries)
272:     #setVariable (&quot;$entries&quot; [])
273:   #end
274:   #getBlogEntriesBaseQuery($query)
275:   #set($totalEntries = $services.query.hql($query).count())
276:   #set($defaultItemsPerPage = 20)
277:   ## This macro is defined in the default macros.vm library. It also sets $itemsPerPage and $startAt.
278:   #preparePagedViewParams($totalEntries $defaultItemsPerPage)
279:   #set($discard = $entries.addAll($services.query.hql(&quot;${query} order by publishDate.value desc&quot;).setLimit($itemsPerPage).setOffset($startAt).execute()))
280: #end
281: ##
282: ##
283: ##
284: #**
285:  * Return the base query for selecting blog entries. It filters only visible entries, but does not bind to a specific
286:  * blog, nor specify a range or an ordering criteria.
287:  * 
288:  * @param query The basic query for selecting blog entries.
289:  *###
290: #macro(getBlogEntriesBaseQuery $query)
291:   #set ($query = $NULL)
292:   #setVariable (&quot;$query&quot; &quot;, BaseObject obj, IntegerProperty isPublished, IntegerProperty hidden, DateProperty publishDate 
293:     where doc.fullName &lt;&gt; '${blogPostTemplate}' and
294:       obj.name = doc.fullName and obj.className = '${blogPostClassname}' and
295:       publishDate.id.id = obj.id and publishDate.id.name = 'publishDate' and
296:       isPublished.id.id = obj.id and isPublished.id.name = 'published' and
297:       hidden.id.id = obj.id and hidden.id.name = 'hidden' and
298:       (doc.creator = '$xcontext.user' or (isPublished.value = 1 and hidden.value = 0))&quot;)
299: #end
300: ##
301: ##
302: ##
303: #**
304:  * Checks if the provided blog is global or in-space.
305:  * 
306:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object with the &lt;tt&gt;blogType&lt;/tt&gt; property set.
307:  * @param isGlobal The resulting boolean. If the blog object does not define anything, it is considered in-space.
308:  *###
309: #macro(isBlogGlobal $blogDoc $isGlobal)
310:   #getBlogProperty($blogDoc 'blogType' '' $discard)
311:   #set ($result = false)
312:   #if($discard == 'global')
313:     #set($result = true)
314:   #end
315:   #set ($isGlobal = $NULL)
316:   #setVariable (&quot;$isGlobal&quot; $result)
317: #end
318: ##
319: ##
320: ##
321: #**
322:  * Determines how is the blog index split into pages: paginated (fixed number of entries), weekly (all entries in a
323:  * week), monthly (all entries in a month), or all.
324:  * 
325:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object with the &lt;tt&gt;displayType&lt;/tt&gt;
326:  *        property set.
327:  * @param displayType The resulting string. If the blog object does not define anything, it is considered paginated.
328:  *###
329: #macro(getBlogDisplayType $blogDoc $displayType)
330:   #getBlogProperty($blogDoc 'displayType' 'paginated' $result)
331:   #set ($displayType = $NULL)
332:   #setVariable (&quot;$displayType&quot; $result)
333: #end
334: ##
335: ##
336: ##
337: #**
338:  * Displays a list of entries.
339:  * 
340:  * @param entries The entries to display, a list of XDocument names.
341:  * @param displaying What exactly is displayed: blog index, a single blog entry, a blog category, search results,
342:  *        unpublished entries, etc. This will be used as the classname(s) for the container div (hfeed). Currently
343:  *        used values: index, single, category, search, unpublished, hidden.
344:  * @param onlyExtract If &lt;tt&gt;true&lt;/tt&gt;, only display the extract of articles where available, otherwise display the full content.
345:  * @param shouldDisplayTitles If &lt;tt&gt;true&lt;/tt&gt;, display the blog title (blog posts shouldn't display the title when they're
346:  *        displayed alone on their page since it's the page title which is used in this case)
347:  *###
348: #macro(displayBlog $entries $displaying $onlyExtract $shouldDisplayTitles)
349:   #set($blogDay = '')
350:   (% class=&quot;hfeed $!{displaying}&quot; %)(((
351:   (% class=&quot;blogDay&quot; %)(((
352:   #foreach ($entryDoc in $xwiki.wrapDocs($entries))
353:     #getEntryObject($entryDoc $entryObj)
354:     ## Although all entries should have one of the two objects, better check to be sure.
355:     #if(&quot;$!{entryObj}&quot; != '')
356:       #getEntryDate($entryDoc $entryObj $entryDate)
357:       ## Display a &quot;calendar sheet&quot; for each day. All entries posted on the same day share one such sheet.
358:       #set($entryDateStr = $xwiki.formatDate($entryDate, 'yyyyMMMMdd'))
359:       #if($blogDay != $entryDateStr)
360:         #if($blogDay != '')
361:           )))
362:           (% class=&quot;blogDay&quot; %)(((
363:         #end
364:         #displayBlogDate($entryDate)
365:         #set ($blogDay = $entryDateStr)
366:       #end
367:       ## Finally, display the entry.
368:       #displayEntry($entryDoc $entryObj $onlyExtract $shouldDisplayTitles)
369:     #end
370:   #end
371:   )))## blogDay
372:   )))## hfeed
373: #end
374: ##
375: ##
376: ##
377: #**
378:  * Get the entry object, either a new BlogPost or an old Article.
379:  * 
380:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
381:  * @param entryObj The resulting xobject of the blog post.
382:  *###
383: #macro(getEntryObject $entryDoc $entryObj)
384:   #set($result = $entryDoc.getObject(&quot;${blogPostClassname}&quot;))
385:   #if(!$result)
386:     #set($result = $entryDoc.getObject(&quot;${oldArticleClassname}&quot;))
387:   #end
388:   #set ($entryObj = $NULL)
389:   #setVariable (&quot;$entryObj&quot; $result)
390: #end
391: ##
392: ##
393: ##
394: #**
395:  * Gets the date associated with a blog entry. This is the publication date. For unpublished entries, initially this is
396:  * the document creation date, but can be edited by the user.
397:  * 
398:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
399:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
400:  * @param result The resulting date, an instance of &lt;tt&gt;java.util.Date&lt;/tt&gt;.
401:  *###
402: #macro(getEntryDate $entryDoc $entryObj $result)
403:   #set ($result = $NULL)
404:   #setVariable (&quot;$result&quot; $entryObj.getProperty('publishDate').value)
405: #end
406: ##
407: ##
408: ##
409: #**
410:  * Displays a date, nicely formatted as a calendar page.
411:  * 
412:  * @param date The date to display, an instance of &lt;tt&gt;java.util.Date&lt;/tt&gt;.
413:  *###
414: #macro(displayBlogDate $date)
415:   #set($year = $xwiki.formatDate($date, 'yyyy'))
416:   ## 3 letter month name, like Jan, Dec.
417:   #set($month = $xwiki.formatDate($date, 'MMM'))
418:   ## Uncomment to get a full length month name, like January, December.
419:   ## TODO: this could be defined somewhere in the blog style.
420:   ## #set($month = $xwiki.formatDate($date, 'MMMM'))
421:   #set($day = $xwiki.formatDate($date, 'dd'))
422:   (% class=&quot;blogdate&quot; %)
423:   == (% class=&quot;month&quot; %)$month(%%) (% class=&quot;day&quot; %)$day(%%) (% class=&quot;year&quot; %)$year(%%) ==
424: #end
425: ##
426: ##
427: ##
428: #**
429:  * Displays a blog article: management tools, header, content, footer.
430:  * 
431:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
432:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
433:  * @param onlyExtract If &lt;tt&gt;true&lt;/tt&gt;, try to display only a summary of the entry, instead of the full content.
434:  * @param shouldDisplayTitle If &lt;tt&gt;true&lt;/tt&gt;, display the blog title (blog posts shouldn't display the title 
435:  *        when they're displayed alone on their page since it's the page title which is used in this case)
436:  *###
437: #macro(displayEntry $entryDoc $entryObj $onlyExtract $shouldDisplayTitle)
438:   ## Only articles with an explicit hidden setting or an explicit unpublished setting are hidden
439:   #isPublished($entryObj $isPublished)
440:   #isHidden($entryObj $isHidden)
441:   #if($doc.fullName == $entryDoc.fullName)
442:     (% class=&quot;hentry single-article&quot; %)(((
443:   #else
444:     (% class=&quot;hentry#if(!$isPublished) unpublished-article#elseif($isHidden) hidden-article#end&quot; %)(((
445:   #end
446:   #displayEntryTools($entryDoc $entryObj)
447:   #if($shouldDisplayTitle)
448:     #displayEntryTitle($entryDoc $entryObj)
449:   #end
450:   #if($doc.fullName == $entryDoc.fullName)
451:     #if(!$isPublished)
452:       {{warning}}{{translation key='xe.blog.code.published'/}}{{/warning}}
453:     #elseif($isHidden)
454:       {{warning}}{{translation key='xe.blog.code.hidden'/}}{{/warning}}
455:     #end
456:   #end
457:   #displayEntryContent($entryDoc $entryObj $onlyExtract)
458:   #displayEntryFooter($entryDoc $entryObj)
459:   )))## hentry
460: #end
461: ##
462: ##
463: ##
464: #**
465:  * Checks if the provided blog is published or not.
466:  * 
467:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
468:  * @param isPublished The resulting boolean, true if the entry is considered published.
469:  *###
470: #macro(isPublished $entryObj $isPublished)
471:   #set ($isPublished = $NULL)
472:   ## This should work for both old articles, which don't have the 'published' property at all, and
473:   ## are considered published by default, and new entries, that should have 1 if published.
474:   #if (&quot;$!{entryObj.getProperty('published').value}&quot; != '0')
475:     #setVariable (&quot;$isPublished&quot; true)
476:   #else
477:     #setVariable (&quot;$isPublished&quot; false)
478:   #end
479: #end
480: ##
481: ##
482: ##
483: #**
484:  * Checks if the provided blog is hidden or not.
485:  * 
486:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;tt&gt; xclass.
487:  * @param isHiddel The resulting boolean, true if the entry is considered hidden.
488:  *###
489: #macro(isHidden $entryObj $isHidden)
490:   #set ($isHidden = $NULL)
491:   ## This should work for both old articles, which don't have the 'hidden' property at all, and
492:   ## are considered visible by default, and new entries, that should have 1 if hidden.
493:   #if (&quot;$!{entryObj.getProperty('hidden').value}&quot; == '1')
494:     #setVariable (&quot;$isHidden&quot; true)
495:   #else
496:     #setVariable (&quot;$isHidden&quot; false)
497:   #end
498: #end
499: ##
500: ##
501: ##
502: #**
503:  * Displays several &quot;tools&quot; for manipulating blog posts: hide/show, publish, edit.
504:  * 
505:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
506:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
507:  *###
508: #macro(displayEntryTools $entryDoc $entryObj)
509:   #if($xcontext.action == 'view')
510:     (% class=&quot;blog-entry-toolbox&quot; %)(((
511:     #displayPublishButton($entryDoc $entryObj)
512:     #displayHideShowButton($entryDoc $entryObj)
513:     #displayEditButton($entryDoc $entryObj)
514:     #displayDeleteButton($entryDoc $entryObj)
515:     )))
516:   #end
517: #end
518: ##
519: ##
520: ##
521: #**
522:  * Displays the publish button to the entry &lt;strong&gt;creator&lt;/strong&gt;, if the article is not published yet.
523:  * 
524:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
525:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
526:  * @todo AJAX calls.
527:  *###
528: #macro(displayPublishButton $entryDoc $entryObj)
529:   #isPublished($entryObj $isPublished)
530:   #if(!$isPublished &amp;&amp; $entryDoc.creator == $xcontext.user &amp;&amp; $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
531:     [[{{html clean=&quot;false&quot;}}#toolImage('page_white_world' 'publish '){{/html}}&gt;&gt;path:$blogPublisher.getURL('view', &quot;entryName=${escapetool.url($entryDoc.fullName)}&amp;xredirect=${escapetool.url($thisURL)}&amp;form_token=$!{services.csrf.getToken()}&quot;)||title=&quot;${escapetool.xml($services.localization.render('xe.blog.code.notpublished'))}&quot;]]##
532:   #end
533: #end
534: ##
535: ##
536: ##
537: #**
538:  * Displays the hide or show button to the entry &lt;strong&gt;creator&lt;/strong&gt;, if the article is already published.
539:  * 
540:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
541:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
542:  *###
543: #macro(displayHideShowButton $entryDoc $entryObj)
544:   #isPublished($entryObj $isPublished)
545:   #isHidden($entryObj $isHidden)
546:   ## Only published articles can be hidden. Unpublished articles are considered already hidden.
547:   #if($isPublished &amp;&amp; $entryDoc.creator == $xcontext.user &amp;&amp; $xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
548:     #if ($isHidden)
549:       [[{{html clean=&quot;false&quot;}}#toolImage('lock_open', 'show '){{/html}}&gt;&gt;path:$entryDoc.getURL('save', &quot;${entryObj.getxWikiClass().getName()}_${entryObj.number}_hidden=0&amp;comment=${escapetool.url($services.localization.render('xe.blog.code.madevisible'))}&amp;xredirect=${escapetool.url($thisURL)}&amp;form_token=$!{services.csrf.getToken()}&quot;)||class=&quot;blog-tool-show&quot; title=&quot;${escapetool.xml($services.localization.render('xe.blog.code.makevisible'))}&quot;]]##
550:     #else
551:       [[{{html clean=&quot;false&quot;}}#toolImage('lock', 'hide '){{/html}}&gt;&gt;path:$entryDoc.getURL('save', &quot;${entryObj.getxWikiClass().getName()}_${entryObj.number}_hidden=1&amp;comment=${escapetool.url($services.localization.render('xe.blog.code.hid'))}&amp;xredirect=${escapetool.url($thisURL)}&amp;form_token=$!{services.csrf.getToken()}&quot;)||class=&quot;blog-tool-hide&quot; title=&quot;${escapetool.xml($services.localization.render('xe.blog.code.hide'))}&quot;]]##
552:     #end
553:   #end
554: #end
555: ##
556: ##
557: ##
558: #**
559:  * Displays the edit button to those that can edit the article.
560:  * 
561:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
562:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
563:  *###
564: #macro(displayEditButton $entryDoc $entryObj)
565:   #if($xwiki.hasAccessLevel('edit', $xcontext.user, $entryDoc.fullName))
566:     ## Call getDefaultEditMode() for backward compatibility with older blog posts.
567:     [[{{html clean=&quot;false&quot;}}#toolImage('pencil' 'edit '){{/html}}&gt;&gt;path:$entryDoc.getURL('edit')||title=&quot;${escapetool.xml($services.localization.render('xe.blog.code.editpost'))}&quot;]]##
568:   #end
569: #end
570: ##
571: ##
572: ##
573: #**
574:  * Displays the delete button to those that can edit the article.
575:  * 
576:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
577:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
578:  * @todo AJAX calls.
579:  *###
580: #macro(displayDeleteButton $entryDoc $entryObj)
581:   #if($xwiki.hasAccessLevel('delete', $xcontext.user, $entryDoc.fullName))
582:     [[{{html clean=&quot;false&quot;}}#toolImage('cross' 'delete '){{/html}}&gt;&gt;path:$entryDoc.getURL('delete')||title=&quot;${escapetool.xml($services.localization.render('xe.blog.code.deletepost'))}&quot;]]##
583:   #end
584: #end
585: ##
586: ##
587: ##
588: #**
589:  * Displays the title of the entry.
590:  * 
591:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
592:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
593:  *###
594: #macro(displayEntryTitle $entryDoc $entryObj)
595:   #if($doc.fullName == $entryDoc.fullName)
596:     (% class=&quot;entry-title&quot; %)
597:     = $entryDoc.display('title', 'view', $entryObj) =
598:   #else
599:     (% class=&quot;entry-title&quot; %)
600:     === [[$entryDoc.display('title', 'view', $entryObj)&gt;&gt;doc:$entryDoc]] ===
601:   #end
602: #end
603: ##
604: ##
605: ##
606: #**
607:  * Displays the body of the entry.
608:  * 
609:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
610:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
611:  * @param onlyExtract If &lt;tt&gt;true&lt;/tt&gt;, try to display only a summary of the entry, instead of the full content.
612:  *###
613: #macro(displayEntryContent $entryDoc $entryObj $onlyExtract)
614:   (% class=&quot;#if($onlyExtract)entry-summary#{else}entry-content#end&quot; %)(((
615:   #getEntryContent($entryDoc $entryObj $onlyExtract $entryContent)
616:   {{html wiki=&quot;false&quot;}}$entryDoc.getRenderedContent($entryContent, $entryDoc.syntax.toIdString()){{/html}}
617:   ))) ## entry-content
618: #end
619: ##
620: ##
621: ##
622: #**
623:  * Extracts the body of the entry that should be displayed. If &lt;tt&gt;onlyExtract&lt;/tt&gt; is &lt;tt&gt;true&lt;/tt&gt;, display the content
624:  * of the &lt;tt&gt;extract&lt;/tt&gt; field (if not empty).
625:  * 
626:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
627:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
628:  * @param onlyExtract If &lt;tt&gt;true&lt;/tt&gt;, try to display only a summary of the entry, instead of the full content.
629:  * @param entryContent The resulting content.
630:  *###
631: #macro(getEntryContent $entryDoc $entryObj $onlyExtract $entryContent)
632:   #if ($onlyExtract)
633:     #set ($result = $entryObj.getProperty('extract').value)
634:   #end
635:   #if(&quot;$!result&quot; == '')
636:     #set($result = $entryObj.getProperty('content').value)
637: #* Disabled until the content can be cleanly cut.
638: *    #if($onlyExtract &amp;&amp; $result.length()&gt;$maxchars)
639: *      #set($i = $result.lastIndexOf(&quot; &quot;, $maxchars))
640: *      #set($i = $i + 1)
641: *      #set($result = &quot;${result.substring(0,$i)} *[...&gt;${entryDoc.fullName}]*&quot;)
642: *    #end
643: ## *###
644:   #else
645:     #if($entryDoc.syntax.toIdString() == 'xwiki/1.0')
646:       #set($result = &quot;${result} &lt;a href='${entryDoc.getURL()}' title='$services.localization.render('xe.blog.code.readpost')'&gt;...&lt;/a&gt;&quot;)
647:     #else
648:       #set($result = &quot;${result} [[...&gt;&gt;${entryDoc}||title='$services.localization.render('xe.blog.code.readpost')']]&quot;)
649:     #end
650:   #end
651:   #set ($entryContent = $NULL)
652:   #setVariable (&quot;$entryContent&quot; $result)
653: #end
654: ##
655: ##
656: ##
657: #**
658:  * Displays the footer of the entry.
659:  * 
660:  * @param entryDoc The xdocument of the blog post. Each post resides in its own document.
661:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
662:  *###
663: #macro(displayEntryFooter $entryDoc $entryObj)
664:   (% class=&quot;entry-footer&quot; %)(((
665:   #isPublished($entryObj $isPublished)
666:   #if($isPublished)
667:     {{translation key='xe.blog.code.postedby'/}} ##
668:   #else
669:     {{translation key='xe.blog.code.createdby'/}} ##
670:   #end
671:   {{html wiki=&quot;false&quot;}}
672:   &lt;address class=&quot;author vcard&quot;&gt;#userfn($entryDoc.creator)&lt;/address&gt; ##
673:   #getEntryDate($entryDoc $entryObj $entryDate)
674:   #listCategories($entryObj) ##
675:   ## Since the publish date and update date are not set at the exact same time, there could be a small difference that
676:   ## we assume cannot be more than 3 seconds.
677:   {{/html}}
678:   (% class=&quot;separator&quot; %)&middot;(%%) [[{{translation key='xe.blog.code.permalink'/}}&gt;&gt;$entryDoc||rel=&quot;bookmark&quot;]] ##
679:   (% class=&quot;separator&quot; %)&middot;(%%) [[{{translation key='xe.blog.code.comments'/}}&gt;&gt;$entryDoc||anchor=&quot;Comments&quot;]] (% class=&quot;itemCount&quot; %)($entryDoc.comments.size())(%%) ##
680:   )))## entry-footer
681: #end
682: ##
683: ##
684: ##
685: #**
686:  * List the categories an entry belongs to. Used in the footer. The categories are instances of &lt;tt&gt;Blog.CategoryClass&lt;/tt&gt;.
687:  * 
688:  * @param entryObj The xobject of the blog post, an instance of the &lt;tt&gt;Blog.BlogPostClass&lt;/tt&gt; xclass.
689:  *###
690: #macro(listCategories $entryObj)
691:   #if($entryObj.getxWikiClass().getName() == $blogPostClassname)
692:     #set($categories = $entryObj.getProperty('category').value)
693:     #set($first = true)
694:     #if($categories.size() &gt; 0)
695:       #foreach($category in $categories)
696: ## Do not indent
697: #set($categoryDoc = $!xwiki.getDocument($category))
698: #if(!$categoryDoc.isNew() &amp;&amp; $categoryDoc.getObject(${blogCategoryClassname}))
699: #if($first)
700:  &lt;span class=&quot;separator&quot;&gt;&amp;#183;&lt;/span&gt; $services.localization.render('xe.blog.code.categories')
701: #set($first = false)
702: #else, #end## if first
703: &lt;a rel=&quot;tag&quot; href=&quot;$xwiki.getURL(${category})&quot;&gt;$!{escapetool.xml($!xwiki.getDocument($category).getObject($blogCategoryClassname).getProperty('name').value)}&lt;/a&gt;##
704: #end## if isNew
705: #end## foreach
706:     #end
707:   #end
708: #end
709: ##
710: ##
711: ##
712: #**
713:  * Displays blog pagination links (older and newer entries).
714:  * 
715:  * @param blogDoc the XDocument holding the blog definition object.
716:  *###
717: #macro(displayNavigationLinks $blogDoc)
718:   (% class=&quot;clearfloats&quot; %)((()))
719:   #getBlogDisplayType($blogDoc $displayType)
720:   #if($displayType == 'weekly')
721:     (% class=&quot;pagingLinks&quot; %)(((
722:     #getRequestedWeek($weekDate)
723:     $weekDate.addWeeks(-1)##
724:     (% class=&quot;prevPage&quot; %)**[[&laquo; {{translation key='xe.blog.code.previousweek'/}}&gt;&gt;$doc.name||queryString=&quot;year=$weekDate.weekyear&amp;week=$weekDate.weekOfWeekyear&quot;]]**(%%)
725:     #sep()
726:     $weekDate.addWeeks(2)## 2 because we already subtracted 1 above
727:     (% class=&quot;nextPage&quot; %)**[[{{translation key='xe.blog.code.nextweek'/}} &raquo;&gt;&gt;$doc.name||queryString=&quot;year=$weekDate.weekyear&amp;week=$weekDate.weekOfWeekyear&quot;]]**(%%)
728:     )))
729:   #elseif($displayType == 'monthly')
730:     (% class=&quot;pagingLinks&quot; %)(((
731:     #getRequestedMonth($monthDate)
732:     $monthDate.addMonths(-1)##
733:     (% class=&quot;prevPage&quot; %)**[[&laquo; {{translation key='xe.blog.code.previousmonth'/}}&gt;&gt;$doc.name||queryString=&quot;year=$monthDate.year&amp;month=$monthDate.monthOfYear&quot;]]**(%%)
734:     #sep()
735:     $monthDate.addMonths(2)## 2 because we already subtracted 1 above
736:     (% class=&quot;nextPage&quot; %)**[[{{translation key='xe.blog.code.nextmonth'/}} &raquo;&gt;&gt;$doc.name||queryString=&quot;year=$monthDate.year&amp;month=$monthDate.monthOfYear&quot;]]**(%%)
737:     )))
738:   #elseif($displayType == 'all')
739:   #else
740:     ## Paginated
741:     #if(($totalPages &gt; 1))
742:       #set($queryString = '')
743:       #foreach($p in $request.getParameterNames())
744:         #if($p != 'page' &amp;&amp; $p != 'ipp')
745:           #foreach($v in $request.getParameterValues($p))
746:             #set($queryString = &quot;${queryString}&amp;${p}=${v}&quot;)
747:           #end
748:         #end
749:       #end
750:       (% class=&quot;pagingLinks&quot; %)(((
751:       #if ($currentPageNumber &lt; $totalPages)
752:         #set($currentPageNumber = $currentPageNumber + 1)
753:         (% class=&quot;prevPage&quot; %)**[[&laquo; {{translation key='xe.blog.code.olderposts'/}}&gt;&gt;$doc.name||queryString=&quot;page=${currentPageNumber}&amp;ipp=${itemsPerPage}$queryString&quot;]]**(%%)
754:         #set($currentPageNumber = $currentPageNumber - 1)
755:       #end
756:       #if ($currentPageNumber &gt; 1)
757:         #if ($currentPageNumber &lt; $totalPages)
758:           #sep()
759:         #end
760:         #set($currentPageNumber = $currentPageNumber - 1)
761:         (% class=&quot;nextPage&quot; %)**[[{{translation key='xe.blog.code.newerposts'/}} &raquo;&gt;&gt;$doc.name||queryString=&quot;page=${currentPageNumber}&amp;ipp=${itemsPerPage}$queryString&quot;]]**(%%)
762:         #set($currentPageNumber = $currentPageNumber + 1)
763:       #end
764:       (% class=&quot;clear&quot; %)(%%)
765:       )))## pagingLinks
766:     #end
767:   #end
768: #end
769: ##
770: ##
771: ##
772: #**
773:  * Displays a message box with &quot;publish&quot; icon.
774:  * 
775:  * @param message A text message concerning blog article publishing
776:  *###
777: #macro(publishMessageBox $message)
778: (% class=&quot;plainmessage publish-message&quot; %)((($message)))
779: #end
780: #**
781:  * Displays a message box with &quot;show/hide&quot; icon.
782:  * 
783:  * @param message A text message concerning blog article hiding
784:  *###
785: #macro(hideMessageBox $message)
786: (% class=&quot;plainmessage hide-message&quot; %)((($message)))
787: #end
788: ##
789: ##
790: ##
791: #**
792:  * Determine the requested week, for using in a weekly-indexed blog. The relevant request parameters are
793:  * &lt;tt&gt;year&lt;/tt&gt; and &lt;tt&gt;week&lt;/tt&gt;. By default, the current week is used.
794:  * 
795:  * @param monthDate The resulting week, a JODATime MutableDateTime.
796:  *###
797: #macro(getRequestedWeek $weekDate)
798:   #set ($weekDate = $NULL)
799:   #setVariable (&quot;$weekDate&quot; $xwiki.jodatime.mutableDateTime)
800:   #if(&quot;$!{request.year}&quot; != '')
801:     $weekDate.setYear($mathtool.toInteger($request.year))
802:   #end
803:   #if(&quot;$!{request.week}&quot; != '')
804:     $weekDate.setWeekOfWeekyear($mathtool.toInteger($request.week))
805:   #end
806: #end
807: ##
808: ##
809: ##
810: #**
811:  * Determine the requested month, for using in a monthly-indexed blog. The relevant request parameters are
812:  * &lt;tt&gt;year&lt;/tt&gt; and &lt;tt&gt;month&lt;/tt&gt;. By default, the current month is used.
813:  * 
814:  * @param monthDate The resulting month, a JODATime MutableDateTime.
815:  *###
816: #macro(getRequestedMonth $monthDate)
817:   #set ($monthDate = $NULL)
818:   #setVariable (&quot;$monthDate&quot; $xwiki.jodatime.mutableDateTime)
819:   #if(&quot;$!{request.year}&quot; != '')
820:     $monthDate.setYear($mathtool.toInteger($request.year))
821:   #end
822:   #if(&quot;$!{request.month}&quot; != '')
823:     $monthDate.setMonthOfYear($mathtool.toInteger($request.month))
824:   #end
825: #end
826: ##
827: ##
828: ##
829: #**
830:  * Retrieve a blog property (title, display type, etc).
831:  * 
832:  * @param blogDoc The blog document. It should contain a &lt;tt&gt;Blog.BlogClass&lt;/tt&gt; object.
833:  * @param propertyName The name of the property to be retrieved. One of the &lt;tt&gt;Blog.BlogClass&lt;/tt&gt;'s properties.
834:  * @param defaultValue The default value to use in case the blog object does not define one.
835:  * @param propertyValue The resulting value.
836:  *###
837: #macro(getBlogProperty $blogDoc $propertyName $defaultValue $propertyValue)
838:   #set($result = &quot;$!{blogDoc.getObject(${blogClassname}).getProperty($propertyName).value}&quot;)
839:   #if($result == '')
840:     #set($result = $defaultValue)
841:   #end
842:   #set ($propertyValue = $NULL)
843:   #setVariable (&quot;$propertyValue&quot; $result)
844: #end
845: 
846: #**
847:  * If an error occurs when executing an action, set a specific response status and display an error message.
848:  * 
849:  * @param status The response status.
850:  * @param text The user readable error to be displayed. Can be a translation key.
851:  * @param parameters The parameters to use when decoding the translation key.
852:  *###
853: #macro(blog__actionResponseError $status $text $parameters)
854:   $response.setStatus($status)
855:   #if($request.ajax)
856:     $services.localization.render($text, $!parameters)
857:   #else
858:     {{error}}$services.localization.render($text, $!parameters){{/error}}
859:   #end
860: #end
861: {{/velocity}}
</textarea>
</div>

    <div class="clearfloats"></div>
  </div>    </div>      </div><div id="leftPanels" class="panels left">
      <div class="panel expanded RecentPostsPanel"><h1 class="xwikipaneltitle">Recent Blog Posts</h1><div class="xwikipanelcontents"></div></div>
        
        <div class="panel expanded CategoriesPanel"><h1 class="xwikipaneltitle">Blog Categories</h1><div class="xwikipanelcontents"><ul><li><span class="blog-category-level"><a href="" title="RSS"><img alt="[RSS]" class="icon-manage" src="resources/icons/silk/bullet_feed.png"></img></a> <a href="">News</a> <span class="itemCount"> (16)</span></span></li><li><span class="blog-category-level"><a href="" title="RSS"><img alt="[RSS]" class="icon-manage" src="resources/icons/silk/bullet_feed.png"></img></a> <a href="">Other</a> <span class="itemCount"> (0)</span></span></li><li><span class="blog-category-level"><a href="" title="RSS"><img alt="[RSS]" class="icon-manage" src="resources/icons/silk/bullet_feed.png"></img></a> <a href="">Personal</a> <span class="itemCount"> (0)</span></span></li></ul></div></div>
        <div class="panel expanded ArchivePanel"><h1 class="xwikipaneltitle">Blog Archive</h1><div class="xwikipanelcontents"><div class="box infomessage">当前没有文章......</div></div></div>
  </div>

  </div><div id="rightPanels" class="panels right">
      <div class="panel expanded QuickLinks"><h1 class="xwikipaneltitle">快速链接</h1><div class="xwikipanelcontents"><ul><li><span class="wikilink"><a href="">首页</a></span></li><li><span class="wikilink"><a href="">新闻动态</a></span></li><li><span class="wikilink"><a href="">FAQ</a></span></li></ul></div></div>
                
  </div>

<div class="clearfloats"></div>
  </div></div><div id="footerglobal" class="layoutsection">
<div class="minwidth"></div>
<hr/>
  <div id="xwikilicence">Copyright © 2013 北京博瑞开源软件有限公司</div>
          <div id="xwikiplatformversion">京ICP备12048974号</div>
<hr/>
</div>

</div></div></body>
</html>


