自己动手编写JEECMS自定义栏目统计标签

 

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

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

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

 

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

[java]  view plain copy
  1. /** 
  2.  * 频道统计实体类 
  3.  * @author www.javake.net 
  4.  */  
  5. public class ChannelStatistics {  
  6.     /** 
  7.      * 文章总数 
  8.      */  
  9.     private long contentAllCount;  
  10.     /** 
  11.      * 待审核文章总数 
  12.      */  
  13.     private long contentCheckingCount;  
  14.     /** 
  15.      * 评论总数 
  16.      */  
  17.     private long commentCount;  
  18.     /** 
  19.      * 阅读总数 
  20.      */  
  21.     private long viewCount;  
  22.     public long getContentAllCount() {  
  23.         return contentAllCount;  
  24.     }  
  25.     public void setContentAllCount(long contentAllCount) {  
  26.         this.contentAllCount = contentAllCount;  
  27.     }  
  28.     public long getContentCheckingCount() {  
  29.         return contentCheckingCount;  
  30.     }  
  31.     public void setContentCheckingCount(long contentCheckingCount) {  
  32.         this.contentCheckingCount = contentCheckingCount;  
  33.     }  
  34.     public long getCommentCount() {  
  35.         return commentCount;  
  36.     }  
  37.     public void setCommentCount(long commentCount) {  
  38.         this.commentCount = commentCount;  
  39.     }  
  40.     public long getViewCount() {  
  41.         return viewCount;  
  42.     }  
  43.     public void setViewCount(long viewCount) {  
  44.         this.viewCount = viewCount;  
  45.     }  
  46. }  


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

[java]  view plain copy
  1. /** 
  2.  * 栏目信息统计Dao接口 
  3.  * @author www.javake.net 
  4.  */  
  5. public interface CmsChannelStatisticDao {  
  6.     /** 
  7.      * 当前栏目文章统计 
  8.      * @param restrictions 
  9.      * @return 
  10.      */  
  11.     public long contentStatistic(Map<String, Object> restrictions);  
  12.     /** 
  13.      * 当前栏目待审核文章统计 
  14.      * @param restrictions 
  15.      * @return 
  16.      */  
  17.     public long contentCheckingStatistic(Map<String, Object> restrictions);  
  18.     /** 
  19.      * 当前栏目评论统计 
  20.      * @param restrictions 
  21.      * @return 
  22.      */  
  23.     public long commentStatistic(Map<String, Object> restrictions);  
  24. }  


 

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

[java]  view plain copy
  1. /** 
  2.  * 栏目信息统计Dao实现类 
  3.  * @author www.javake.net 
  4.  */  
  5. import static com.jeecms.cms.entity.main.Content.ContentStatus.passed;  
  6. import static com.jeecms.cms.entity.main.Content.ContentStatus.prepared;  
  7. import static com.jeecms.cms.entity.main.Content.ContentStatus.rejected;  
  8. import static com.jeecms.cms.statistic.CmsStatistic.CHANNELID;  
  9. import static com.jeecms.cms.statistic.CmsStatistic.ISREPLYED;  
  10. import static com.jeecms.cms.statistic.CmsStatistic.SITEID;  
  11. import java.util.Map;  
  12. import org.springframework.stereotype.Repository;  
  13. import com.jeecms.cms.entity.main.Content.ContentStatus;  
  14. import com.jeecms.common.hibernate3.Finder;  
  15. import com.jeecms.common.hibernate3.HibernateSimpleDao;  
  16. @Repository  
  17. public class CmsChannelStatisticDaoImpl extends HibernateSimpleDao  
  18.             implements CmsChannelStatisticDao{  
  19.     /** 
  20.      * 获取文章总数 
  21.      */  
  22.     public long contentStatistic(Map<String, Object> restrictions) {  
  23.         Finder f = createCacheableFinder("select count(*) from Content bean");  
  24.         Integer channelId = (Integer) restrictions.get(CHANNELID);  
  25.         if (channelId != null) {  
  26.             f.append(" join bean.channel channel,Channel parent");  
  27.             f.append(" where channel.lft between parent.lft and parent.rgt");  
  28.             f.append(" and channel.site.id=parent.site.id");  
  29.             f.append(" and parent.id=:parentId");  
  30.             f.setParam("parentId", channelId);  
  31.         } else {  
  32.             f.append(" where bean.site.id=:siteId").setParam("siteId",  
  33.                     restrictions.get(SITEID));  
  34.         }  
  35.         return (Long) find(f).iterator().next();  
  36.     }  
  37.       
  38.     private long contentStatistic(Map<String, Object> restrictions,ContentStatus status) {  
  39.         Finder f = createCacheableFinder("select count(*) from Content bean");  
  40.         if (prepared == status || passed == status || rejected == status) {  
  41.             f.append(" join bean.contentCheckSet check");  
  42.         }  
  43.         Integer channelId = (Integer) restrictions.get(CHANNELID);  
  44.         if (channelId != null) {  
  45.             f.append(" join bean.channel channel,Channel parent");  
  46.             f.append(" where channel.lft between parent.lft and parent.rgt");  
  47.             f.append(" and channel.site.id=parent.site.id");  
  48.             f.append(" and parent.id=:parentId");  
  49.             f.setParam("parentId", channelId);    
  50.         } else {  
  51.             f.append(" where bean.site.id=:siteId").setParam("siteId",  
  52.                     restrictions.get(SITEID));  
  53.         }  
  54.         if (prepared == status || passed == status) {  
  55.             f.append(" and check.rejected=false");  
  56.         } else if (rejected == status) {  
  57.             f.append(" and check.rejected=true");  
  58.         }  
  59.         return (Long) find(f).iterator().next();  
  60.     }  
  61.       
  62.     /** 
  63.      * 待审核文章总数 
  64.      * @param restrictions 
  65.      * @param status 
  66.      * @return 
  67.      */  
  68.     public long contentCheckingStatistic(Map<String, Object> restrictions) {  
  69.         return contentStatistic(restrictions,ContentStatus.prepared);  
  70.     }  
  71.     public long commentStatistic(Map<String, Object> restrictions) {  
  72.         Finder f = createCacheableFinder("select count(*) from CmsComment bean ");  
  73.         Integer channelId = (Integer) restrictions.get(CHANNELID);  
  74.         if (channelId != null) {  
  75.             f.append(" join bean.channel channel,Channel parent");  
  76.             f.append(" where channel.lft between parent.lft and parent.rgt");  
  77.             f.append(" and channel.site.id=parent.site.id");  
  78.             f.append(" and parent.id=:parentId");  
  79.             f.setParam("parentId", channelId);    
  80.         } else {  
  81.             f.append(" where bean.site.id=:siteId").setParam("siteId",  
  82.                     restrictions.get(SITEID));  
  83.         }  
  84.         Boolean isReplyed = (Boolean) restrictions.get(ISREPLYED);  
  85.         if (isReplyed != null) {  
  86.             if (isReplyed) {  
  87.                 f.append(" and bean.replayTime is not null");  
  88.             } else {  
  89.                 f.append(" and bean.replayTime is null");  
  90.             }  
  91.         }  
  92.         return (Long) find(f).iterator().next();  
  93.     }  
  94.       
  95.     private Finder createCacheableFinder(String hql) {  
  96.         Finder finder = Finder.create(hql);  
  97.         finder.setCacheable(true);  
  98.         return finder;  
  99.     }  
  100. }  


 

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

[java]  view plain copy
  1. /** 
  2.  * 栏目统计 
  3.  * @author www.javake.net 
  4.  */  
  5. import static com.jeecms.common.web.freemarker.DirectiveUtils.OUT_BEAN;  
  6. import static freemarker.template.ObjectWrapper.DEFAULT_WRAPPER;  
  7. import static com.jeecms.cms.statistic.CmsStatistic.SITEID;  
  8. import static com.jeecms.cms.statistic.CmsStatistic.ISREPLYED;  
  9. import static com.jeecms.cms.statistic.CmsStatistic.USERID;  
  10. import static com.jeecms.cms.statistic.CmsStatistic.CHANNELID;  
  11. import java.io.IOException;  
  12. import java.util.HashMap;  
  13. import java.util.Map;  
  14. import org.springframework.beans.factory.annotation.Autowired;  
  15. import com.jeecms.cms.entity.main.ChannelStatistics;  
  16. import com.jeecms.cms.entity.main.CmsSite;  
  17. import com.jeecms.cms.statistic.CmsChannelStatisticDao;  
  18. import com.jeecms.cms.web.FrontUtils;  
  19. import com.jeecms.common.web.freemarker.DirectiveUtils;  
  20. import freemarker.core.Environment;  
  21. import freemarker.template.TemplateDirectiveBody;  
  22. import freemarker.template.TemplateDirectiveModel;  
  23. import freemarker.template.TemplateException;  
  24. import freemarker.template.TemplateModel;  
  25. public class CmsChannelStatisticsDirective implements TemplateDirectiveModel{  
  26.     /** 
  27.      * 输入参数,站点ID。存在时,获取该站点栏目,不存在时获取当前站点栏目。 
  28.      */  
  29.     public static final String PARAM_SITE_ID = "siteId";  
  30.     /** 
  31.      * 输入参数,栏目ID。 
  32.      */  
  33.     public static final String PARAM_ID = "id";  
  34.     @SuppressWarnings("unchecked")  
  35.     public void execute(Environment env, Map params, TemplateModel[] loopVars,  
  36.             TemplateDirectiveBody body) throws TemplateException, IOException {  
  37.         CmsSite site = FrontUtils.getSite(env);  
  38.         Integer id = DirectiveUtils.getInt(PARAM_ID, params);  
  39.         ChannelStatistics statistics = null;  
  40.         Map<String,Object> restrictions = new HashMap<String,Object>();  
  41.         Integer siteId = DirectiveUtils.getInt(PARAM_SITE_ID, params);  
  42.         if (siteId == null) {  
  43.             siteId = site.getId();  
  44.         }  
  45.         if (id != null ) {  
  46.             restrictions.put(CHANNELID, id);          
  47.         } else {  
  48.             restrictions.put(SITEID, siteId);  
  49.         }  
  50.         long contentCount = channelSatistic.contentStatistic(restrictions);  
  51.         long contentCheckingCount = channelSatistic.contentCheckingStatistic(restrictions);  
  52.         long commentCount = channelSatistic.commentStatistic(restrictions);  
  53.           
  54.         statistics = new ChannelStatistics();  
  55.         statistics.setCommentCount(commentCount);  
  56.         statistics.setContentAllCount(contentCount);  
  57.         statistics.setContentCheckingCount(contentCheckingCount);  
  58.           
  59.         Map<String, TemplateModel> paramWrap = new HashMap<String, TemplateModel>(  
  60.                 params);  
  61.         paramWrap.put(OUT_BEAN, DEFAULT_WRAPPER.wrap(statistics));  
  62.         Map<String, TemplateModel> origMap = DirectiveUtils  
  63.                 .addParamsToVariable(env, paramWrap);  
  64.         body.render(env.getOut());  
  65.         DirectiveUtils.removeParamsFromVariable(env, paramWrap, origMap);  
  66.     }  
  67.       
  68.     @Autowired  
  69.     private CmsChannelStatisticDao channelSatistic;  
  70.   
  71.     public void setChannelSatistic(CmsChannelStatisticDao channelSatistic) {  
  72.         this.channelSatistic = channelSatistic;  
  73.     }  
  74. }  


 

第五步:在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] )

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值