今天想在给Java客二级版面加入栏目文章统计效果,如下图,

查看JEECMS的源代码发现开发者版本还没有类似现成的统计标签,一种解决的办法是使用现有的JEECMS标签,像这样Struts( [@cms_content_list channel=id]${tag_list?size}[/@cms_content_list]) ,但是这样的做法非常地低效,原因是[@cms_content_list]标签会把所有当前栏目的文章内容对象查询出来,做全表查询!

没办法啊!!!为了网站访问效率,只好自己写一个统计标签吧。那下面就以[@cms_channel_statistic]为例说下如何在JEECMS加入自定义标签。

第一步:编写装载统计信息的Entity。

/**
* 频道统计实体类
* @author www.javake.net
*/
public class ChannelStatistics {
/**
* 文章总数
*/
private long contentAllCount;
/**
* 待审核文章总数
*/
private long contentCheckingCount;
/**
* 评论总数
*/
private long commentCount;
/**
* 阅读总数
*/
private long viewCount;
public long getContentAllCount() {
return contentAllCount;
}
public void setContentAllCount(long contentAllCount) {
this.contentAllCount = contentAllCount;
}
public long getContentCheckingCount() {
return contentCheckingCount;
}
public void setContentCheckingCount(long contentCheckingCount) {
this.contentCheckingCount = contentCheckingCount;
}
public long getCommentCount() {
return commentCount;
}
public void setCommentCount(long commentCount) {
this.commentCount = commentCount;
}
public long getViewCount() {
return viewCount;
}
public void setViewCount(long viewCount) {
this.viewCount = viewCount;
}
}

第二步:编写栏目信息统计的Dao接口。暂时只实现文章总数统计,待审核文章统计,评论总数。

/**
* 栏目信息统计Dao接口
* @author www.javake.net
*/
public interface CmsChannelStatisticDao {
/**
* 当前栏目文章统计
* @param restrictions
* @return
*/
public long contentStatistic(Map<String, Object> restrictions);
/**
* 当前栏目待审核文章统计
* @param restrictions
* @return
*/
public long contentCheckingStatistic(Map<String, Object> restrictions);
/**
* 当前栏目评论统计
* @param restrictions
* @return
*/
public long commentStatistic(Map<String, Object> restrictions);
}

第三步:编写Dao接口的实现。

/**
* 栏目信息统计Dao实现类
* @author www.javake.net
*/
import static com.jeecms.cms.entity.main.Content.ContentStatus.passed;
import static com.jeecms.cms.entity.main.Content.ContentStatus.prepared;
import static com.jeecms.cms.entity.main.Content.ContentStatus.rejected;
import static com.jeecms.cms.statistic.CmsStatistic.CHANNELID;
import static com.jeecms.cms.statistic.CmsStatistic.ISREPLYED;
import static com.jeecms.cms.statistic.CmsStatistic.SITEID;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.jeecms.cms.entity.main.Content.ContentStatus;
import com.jeecms.common.hibernate3.Finder;
import com.jeecms.common.hibernate3.HibernateSimpleDao;
@Repository
public class CmsChannelStatisticDaoImpl extends HibernateSimpleDao
implements CmsChannelStatisticDao{
/**
* 获取文章总数
*/
public long contentStatistic(Map<String, Object> restrictions) {
Finder f = createCacheableFinder("select count(*) from Content bean");
Integer channelId = (Integer) restrictions.get(CHANNELID);
if (channelId != null) {
f.append(" join bean.channel channel,Channel parent");
f.append(" where channel.lft between parent.lft and parent.rgt");
f.append(" and channel.site.id=parent.site.id");
f.append(" and parent.id=:parentId");
f.setParam("parentId", channelId);
} else {
f.append(" where bean.site.id=:siteId").setParam("siteId",
restrictions.get(SITEID));
}
return (Long) find(f).iterator().next();
}

private long contentStatistic(Map<String, Object> restrictions,ContentStatus status) {
Finder f = createCacheableFinder("select count(*) from Content bean");
if (prepared == status || passed == status || rejected == status) {
f.append(" join bean.contentCheckSet check");
}
Integer channelId = (Integer) restrictions.get(CHANNELID);
if (channelId != null) {
f.append(" join bean.channel channel,Channel parent");
f.append(" where channel.lft between parent.lft and parent.rgt");
f.append(" and channel.site.id=parent.site.id");
f.append(" and parent.id=:parentId");
f.setParam("parentId", channelId);
} else {
f.append(" where bean.site.id=:siteId").setParam("siteId",
restrictions.get(SITEID));
}
if (prepared == status || passed == status) {
f.append(" and check.rejected=false");
} else if (rejected == status) {
f.append(" and check.rejected=true");
}
return (Long) find(f).iterator().next();
}

/**
* 待审核文章总数
* @param restrictions
* @param status
* @return
*/
public long contentCheckingStatistic(Map<String, Object> restrictions) {
return contentStatistic(restrictions,ContentStatus.prepared);
}
public long commentStatistic(Map<String, Object> restrictions) {
Finder f = createCacheableFinder("select count(*) from CmsComment bean ");
Integer channelId = (Integer) restrictions.get(CHANNELID);
if (channelId != null) {
f.append(" join bean.channel channel,Channel parent");
f.append(" where channel.lft between parent.lft and parent.rgt");
f.append(" and channel.site.id=parent.site.id");
f.append(" and parent.id=:parentId");
f.setParam("parentId", channelId);
} else {
f.append(" where bean.site.id=:siteId").setParam("siteId",
restrictions.get(SITEID));
}
Boolean isReplyed = (Boolean) restrictions.get(ISREPLYED);
if (isReplyed != null) {
if (isReplyed) {
f.append(" and bean.replayTime is not null");
} else {
f.append(" and bean.replayTime is null");
}
}
return (Long) find(f).iterator().next();
}

private Finder createCacheableFinder(String hql) {
Finder finder = Finder.create(hql);
finder.setCacheable(true);
return finder;
}
}

第四步:编写栏目统计的FreeMarker标签类。这里可以输入两个参数,一个是id(栏目id),一个是siteId(站点id)。这两个参数可在使用标签的时候输入。

/**
* 栏目统计
* @author www.javake.net
*/
import static com.jeecms.common.web.freemarker.DirectiveUtils.OUT_BEAN;
import static freemarker.template.ObjectWrapper.DEFAULT_WRAPPER;
import static com.jeecms.cms.statistic.CmsStatistic.SITEID;
import static com.jeecms.cms.statistic.CmsStatistic.ISREPLYED;
import static com.jeecms.cms.statistic.CmsStatistic.USERID;
import static com.jeecms.cms.statistic.CmsStatistic.CHANNELID;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.jeecms.cms.entity.main.ChannelStatistics;
import com.jeecms.cms.entity.main.CmsSite;
import com.jeecms.cms.statistic.CmsChannelStatisticDao;
import com.jeecms.cms.web.FrontUtils;
import com.jeecms.common.web.freemarker.DirectiveUtils;
import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
public class CmsChannelStatisticsDirective implements TemplateDirectiveModel{
/**
* 输入参数,站点ID。存在时,获取该站点栏目,不存在时获取当前站点栏目。
*/
public static final String PARAM_SITE_ID = "siteId";
/**
* 输入参数,栏目ID。
*/
public static final String PARAM_ID = "id";
@SuppressWarnings("unchecked")
public void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException {
CmsSite site = FrontUtils.getSite(env);
Integer id = DirectiveUtils.getInt(PARAM_ID, params);
ChannelStatistics statistics = null;
Map<String,Object> restrictions = new HashMap<String,Object>();
Integer siteId = DirectiveUtils.getInt(PARAM_SITE_ID, params);
if (siteId == null) {
siteId = site.getId();
}
if (id != null ) {
restrictions.put(CHANNELID, id);
} else {
restrictions.put(SITEID, siteId);
}
long contentCount = channelSatistic.contentStatistic(restrictions);
long contentCheckingCount = channelSatistic.contentCheckingStatistic(restrictions);
long commentCount = channelSatistic.commentStatistic(restrictions);

statistics = new ChannelStatistics();
statistics.setCommentCount(commentCount);
statistics.setContentAllCount(contentCount);
statistics.setContentCheckingCount(contentCheckingCount);

Map<String, TemplateModel> paramWrap = new HashMap<String, TemplateModel>(
params);
paramWrap.put(OUT_BEAN, DEFAULT_WRAPPER.wrap(statistics));
Map<String, TemplateModel> origMap = DirectiveUtils
.addParamsToVariable(env, paramWrap);
body.render(env.getOut());
DirectiveUtils.removeParamsFromVariable(env, paramWrap, origMap);
}

@Autowired
private CmsChannelStatisticDao channelSatistic;

public void setChannelSatistic(CmsChannelStatisticDao channelSatistic) {
this.channelSatistic = channelSatistic;
}
}

第五步:在jeecms-context.xml文件中加入CmsChannelStatisticsDirective标签类的bean注入代码。

<!— Author:www.javake.net -->

<bean id="cms_lucene_page"class="com.jeecms.cms.lucene.LuceneDirectivePage"/>

<bean id="cms_advertising"class="com.jeecms.cms.action.directive.CmsAdvertisingDirective"/>

<bean id="cms_channel_statistic" class="com.jeecms.cms.action.directive.CmsChannelStatisticsDirective"/>

<!— Author:www.javake.net -->

<property name="freemarkerVariables">

<map>

<entry key="uuid"value-ref="uuid"/>

<entry key="process_time"value-ref="process_time"/>

<entry key="text_cut"value-ref="text_cut"/>

<entry key="html_cut"value-ref="html_cut"/>

<entry key="cms_pagination"value-ref="cms_pagination"/>

<entry key="cms_channel_list"value-ref="cms_channel_list"/>

<entry key="cms_channel_page"value-ref="cms_channel_page"/>

<entry key="cms_channel"value-ref="cms_channel"/>

<entry key="cms_content"value-ref="cms_content"/>

<entry key="cms_content_list"value-ref="cms_content_list"/>

<entry key="cms_content_page"value-ref="cms_content_page"/>

<entry key="cms_tag_list"value-ref="cms_tag_list"/>

<entry key="cms_tag_page"value-ref="cms_tag_page"/>

<entry key="cms_topic_list"value-ref="cms_topic_list"/>

<entry key="cms_topic_page"value-ref="cms_topic_page"/>

<entry key="cms_comment_list"value-ref="cms_comment_list"/>

<entry key="cms_comment_page"value-ref="cms_comment_page"/>

<entry key="cms_guestbook_ctg_list"value-ref="cms_guestbook_ctg_list"/>

<entry key="cms_guestbook_list"value-ref="cms_guestbook_list"/>

<entry key="cms_guestbook_page"value-ref="cms_guestbook_page"/>

<entry key="cms_vote"value-ref="cms_vote"/>

<entry key="cms_friendlink_ctg_list"value-ref="cms_friendlink_ctg_list"/>

<entry key="cms_friendlink_list"value-ref="cms_friendlink_list"/>

<entry key="cms_lucene_list"value-ref="cms_lucene_list"/>

<entry key="cms_lucene_page"value-ref="cms_lucene_page"/>

<entry key="cms_advertising"value-ref="cms_advertising"/>

<entry key="cms_channel_statistic" value-ref="cms_channel_statistic"/>

</map>

</property>

第六步:在jeecms-servlet-front.xml文件中配置

<!— Author:www.javake.net -->

<bean id="freemarkerConfig"class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">

<property name="freemarkerVariables">

<map>

<entry key="uuid"value-ref="uuid"/>

<entry key="process_time"value-ref="process_time"/>

<entry key="text_cut"value-ref="text_cut"/>

<entry key="html_cut"value-ref="html_cut"/>

<entry key="cms_pagination"value-ref="cms_pagination"/>

<entry key="cms_channel_list"value-ref="cms_channel_list"/>

<entry key="cms_channel_page"value-ref="cms_channel_page"/>

<entry key="cms_channel"value-ref="cms_channel"/>

<entry key="cms_content"value-ref="cms_content"/>

<entry key="cms_content_list"value-ref="cms_content_list"/>

<entry key="cms_content_page"value-ref="cms_content_page"/>

<entry key="cms_tag_list"value-ref="cms_tag_list"/>

<entry key="cms_tag_page"value-ref="cms_tag_page"/>

<entry key="cms_topic_list"value-ref="cms_topic_list"/>

<entry key="cms_topic_page"value-ref="cms_topic_page"/>

<entry key="cms_comment_list"value-ref="cms_comment_list"/>

<entry key="cms_comment_page"value-ref="cms_comment_page"/>

<entry key="cms_guestbook_ctg_list"value-ref="cms_guestbook_ctg_list"/>

<entry key="cms_guestbook_list"value-ref="cms_guestbook_list"/>

<entry key="cms_guestbook_page"value-ref="cms_guestbook_page"/>

<entry key="cms_vote"value-ref="cms_vote"/>

<entry key="cms_lucene_list"value-ref="cms_lucene_list"/>

<entry key="cms_lucene_page"value-ref="cms_lucene_page"/>

<entry key="cms_friendlink_ctg_list"value-ref="cms_friendlink_ctg_list"/>

<entry key="cms_friendlink_list"value-ref="cms_friendlink_list"/>

<entry key="cms_advertising"value-ref="cms_advertising"/>

<entry key="cms_channel_statistic" value-ref="cms_channel_statistic"/>

</map>

</property>

第七步:到目前为止,核心代码和配置编写完毕啦!!!可以在栏目模板中使用标签了!

<!—Author:www.javake.net-->

( [@cms_channel_statisticid=a.id]${tag_bean.contentAllCount}[/@cms_channel_statistic] )
---------------------
作者:Java客
来源:CSDN
原文:https://blog.csdn.net/javafamily/article/details/8544400
版权声明:本文为博主原创文章,转载请附上博文链接!

自己动手编写JEECMS自定义栏目统计标签的更多相关文章

  1. JEECMS自定义标签

    查看JEECMS的源代码发现开发者版本还没有类似现成的统计标签,一种解决的办法是使用现有的JEECMS标签,像这样Struts( [@cms_content_list channel=id]${tag ...

  2. [原创]JEECMS 自定义标签调用广告版位下的所有广告(利用广告管理管理首页幻灯片)

    JEECMS自带的只有[@cms_advertising]标签,并且官方没有给文档,用法: [@cms_advertising id='3']             <img src=&quo ...

  3. JEECMS自定义标签开发步骤2

    JEECMS自带的只有[@cms_advertising]标签,并且官方没有给文档,用法: [@cms_advertising id='3']             <img src=&quo ...

  4. JEECMS自定义标签开发步骤

    JEECMS自带的只有[@cms_advertising]标签,并且官方没有给文档,用法: [@cms_advertising id='3']             <img src=&quo ...

  5. JEECMS站群管理系统-- 标签使用和模板的制作

    1模板规划 1.1资源文件 资源文件就是网页中用到的图片.CSS.JS等元素,在CMS系统中所有的资源文件在网站的根目录中的 /res_base/所属网站定义资源目录/TEMPLEATE/WEB /r ...

  6. JEECMS二次开发 -------标签使用说明

    转载:https://blog.csdn.net/u012176984/article/details/45501771 一:标签套用结构说明 登录后台管理页面,这些嵌套在html中的标签 以[@标签 ...

  7. OWIN系列之自己动手编写中间件

    一.前言 1.基于OWIN的项目摆脱System.Web束缚脱颖而出,轻量级+跨平台,使得ASP.NET应用程序只需依赖这个抽象接口,不用关心所运行的Web服务器. 2.OWIN.dll介绍 使用反编 ...

  8. Django入门--自定义过滤器与标签

    ---恢复内容开始--- 为了让Django找到自定义的模板过滤器和模板标签,需要进行文件路径配置,配置方式分为APP目录下配置和项目路径下配置两种方式: 1.在APP目录下配置:针对某个应用特定的自 ...

  9. 如何在CSDN博客自定义栏目中添加“给我写信”

    在"自定义栏目"中添加"连接"(将自己的微博,QQ空间和CSDN博客关联起来)很多人都做过.但是添加"给我写信"这个功能,用的好像不太多.此 ...

随机推荐

  1. github 拷贝项目到本地

    第一步,git config --global --list 验证邮箱 第二步,git config --global user.name "yourname",git confi ...

  2. 如何利用开源思想开发一个SEO友好型网

    如果你有一个网站需要去做SEO优化的时候,不要期望你的努力能立即得到回报.耐心等待并更正内容营销策略,最终会发现你的网站很受用户欢迎.下面就教你如何利用开源思维开发一个SEO友好型网站! 首先,你应该 ...

  3. Python3升级3.6强力Django+杀手级xadmin打造在线教育平台✍✍✍

    Python3升级3.6强力Django+杀手级xadmin打造在线教育平台 教程 Xadmin安装方法: settings.py 的配置: users App 下的 adminx.py 的配置:

  4. [POI2013]MOR-Tales of seafaring

    题目 思博题,发现一旦路径太长我们可以来回走最后一条边,但是这样并不能改变路径长度的奇偶性 所以求一下所有点之间奇最短路和偶最短路就好了,直接暴力\(BFS\)即可 有一个烦人的特判 代码 #incl ...

  5. Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1

    Bubble Cup 12 - Finals Online Mirror, unrated, Div. 1 C. Jumping Transformers 我会状压 DP! 用 \(dp[x][y][ ...

  6. Leetcode187. Repeated DNA Sequences重复的DNA序列

    所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG".在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助. 编写一个函数 ...

  7. BOM相关知识点

    1.BOM概念:Browser Object Model 浏览器对象模型作用:提供了使用JS操作浏览器的接口 2.BOM包含了许多对象信息,包括如下这些:(1)screen 屏幕信息(2)locati ...

  8. LUOGU P2476 [SCOI2008]着色方案

    传送门 解题思路 毒瘤题,,刚开始写了个奇奇怪怪的哈希,结果T了5个点..后来深(kan)入(le)思(ti)考(jie),发现c的范围很小,设$f[a][b][c][d][e][pre]​$表示还能 ...

  9. 洛谷P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome

    题目链接: 点我 题目分析: 玄学\(dp\) 设\(val[s[i] - 'a' + 1]\)表示字母\(s[i]\)的花费 首先发现对于一个已经回文了的串\(s[i, j]\),在\(s[i - ...

  10. exiftool(-k)与gui的联合使用

    首先下载一个exiftool下载后改名字https://sno.phy.queensu.ca/~phil/exiftool/ 根据自己的操作系统选择,我需要这个 然后下载guihttp://u88.n ...