1. 程式人生 > >編JEECMS自定義欄目統計標籤

編JEECMS自定義欄目統計標籤

檢視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介面。暫時只實現文章總數統計,待稽核文章統計,評論總數cop

/** 
 * 欄目資訊統計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] )


相關推薦

JEECMS定義欄目統計標籤

檢視JEECMS的原始碼發現開發者版本還沒有類似現成的統計標籤,一種解決的辦法是使用現有的JEECMS標籤,像這樣Struts( [@cms_content_list channel=id]${tag_list?size}[/@cms_content_list]) ,但是

軟工實踐第五次作業-爬蟲和定義詞頻統計

system 屬性 project html標簽 ttr ont 標題 改進 提交 軟工實踐第五次作業-爬蟲和自定義詞頻統計 題目地址:https://edu.cnblogs.com/campus/fzu/FZUSoftwareEngineering1816W/homewo

定義過濾器和標籤

第一步:  在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag. 第二步: 在app中建立templatetags模組(模組名只能是templatetags) 第三步: 建立py檔案 from django imp

定義過濾器和標籤,動態顯示選單許可權

1、在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag. 2、在app中建立templatetags模組(模組名只能是templatetags)   3、建立任意 .py 檔案,如:my_tags.py 1 from

CSDN 定義欄目美化

文章目錄 前言 自定義欄目 正片開始 html 程式碼 注意事項 前言 Csdn 自定義欄目的個人設定,由於個人修改了自定義欄目,感覺不錯的話可以自行來取。 首先,不得不說一點,csdn的自定義不如部落格園來的多,但這也

Django定義過濾器和標籤

Django的模板語言包含了各種各樣的內建標籤和過濾器來滿足你的應用需求,不過有時候你也會發現你的需要的功能不在內建的功能中,這時候你可以通過Python語言自定義標籤和過濾器來擴充套件模板引擎,然後在你的模板中使用 {% load %} 來載入使用它們。 首先建立好包檔案: 在你的app下

Spring擴充套件定義的XML標籤

在網上搜了許多,感覺不夠全面,就找了官方文件,下面記錄如何找到對應的文件進入  網上許多部落格都是以dateformat為例項進行編寫的,通過官方的foo,能夠學到更多的東西,下面貼一段程式碼,在官方示例上改了一點解析程式碼: package com.theory.spri

如何給CSDN部落格添加個人微信公眾號二維碼或定義欄目

公眾號檢視文章更清晰 在使用CSDN的過程中,可以看到有些博主的主頁有個人微信二維碼,微信公眾號二維碼等一些個人欄目資訊。這對作者而言,可以讓其他瀏覽部落格的遊客和作者進行更有效的溝通,也可以在這裡對自己的微信公眾號作宣傳,現在新版的CSDN好像只能新增一個自定義欄目,這裡以新增微信二維碼為例進

Django之模板層-定義過濾器以及標籤

自定義標籤與過濾器 在settings中的INSTALLED_APPS配置當前app,不然django無法找到自定義的simple_tag. 在app中建立templatetags模組(模組名只能是templatetags) 建立任意 .py 檔案,如:my_tags.py from d

定義writable統計電話號碼的上下行及總流量

Driver類 public class flowSum { static class mymapper extends Mapper<LongWritable, Text, Text, FlowBean>{ @Override

定義Django過濾器標籤

django的過濾器很多,自帶的過濾器能滿足我們絕大部分的工作要求,但是當我們有特別的需求的時候就需要自定義了。 建立templatetags資料夾 注意,這個資料夾的名字是唯一的,不能更改成其他

定義JSP頁面標籤(有點型別EL表示式)

1.自定義標籤 1.1  標籤語言特點(格式)   <開始標籤 屬性名="屬性值">標籤體</結束標籤>    空標籤    <br/><hr/>    <開始標籤></結束標籤>    

Android 定義View 滑動標籤_At_Swim

public class DragableGridLayout extends GridLayout implements View.OnLongClickListener,View.OnDragListener { private int columCount

關於Go語言,定義結構體標籤的一個妙用.

在Go中首字母大小寫,決定著這此變數是否能被外部呼叫, 例如:在使用標準庫的json編碼自定一的結構的時候: <pre style="margin-top: 0px; margin-bottom: 0px;"><span style=" font-weig

Echarts之地圖定義lable文字標籤&去掉小點

var Echart = echarts.init(document.getElementById("map")); var option = { tooltip: { },

android定義環形統計圖(帶動畫)

一、測試截圖 二、實現原理  package com.freedomanlib; import java.util.Timer; import java.util.TimerTask; import android.annotation.SuppressLint;

Django學習筆記之定義過濾器及標籤

目錄結構: 在專案目錄下 建立個名為common的Python包 將common加入到settings檔案中的INSTALLED_APP列表中 INSTALLED_APPS = [ '

在Struts2中實現定義分頁標籤全攻略(一)

我們先看看這個分頁標籤的效果: 使用標籤的最大好處就是下次再用到的話直接引用就行,而不必重寫。 本人對Struts2自定義標籤沒有太深究,在網上找了一些資料可以參考參考: 其實,開發自定義標籤並不需要Struts2的支援,一般情況下,只需要繼承javax.servle

CSDN VIP如何新增定義欄目

幾個月前我也開始在csdn上開了部落格,一來給自己加幾個少的可憐的流量,再者,讓公眾號的原創文章獲得更多的曝光,讓有需要的同學看到。 寫過csdn部落格的同學都知道,預設只有打賞c幣功能;也沒有專門廣告位;引導欄目,只有側欄csdn自己的引導二維碼。 如何在csdn自定義欄目,加讚賞功能,或者其他等引導,讓

CSDN VIP如何新增引流定義欄目

幾個月前我也開始在csdn上開了部落格,一來給自己加幾個少的可憐的流量,再者,讓公眾號的原創文章獲得更多的曝光,讓有需要的同學看到。 寫過csdn部落格的同學都知道,預設只有打賞c幣功能;也沒有專門廣告位;引導欄目,只有側欄csdn自己的引導二維碼。 如何在csdn自定義欄目,加讚賞功能,或者其他等引導,讓