前幾天在weibo上被人問到,如何方便快捷的實現一個SharePoint計數器呢?嗯,在本文里,我嘗試用最簡單的方法,來創建一個SharePoint網站計數器。在開始之前,讓我們先為這個計數器的功能作如下設定:
- 這是一個最單純的計數器,它的作用就是一個:記錄網站的訪問量。
- 當用戶第一次打開網站的任何頁面時,都會為計數器+1,但是用戶接着刷新頁面或瀏覽網站其它頁面時,計數器不再累計增加。換句話說,我們的這個計數器將是一個真正的訪問量計數器,而不是Page View計數器。
為了讓我們的計數器足夠的“輕量級”,同時減少它對網站頁面載入速度的影響,我們將不使用任何服務器端代碼!是的,我們將不會創建任何Web Part、控件或是頁面之類的東西。所有的功能都通過JavaScript腳本實現,並使用SharePoint 2010 JavaScript Object Model(JSOM)來實現腳本與SharePoint服務器的交互。
當我們為一個SharePoint應用程序創建了js腳本文件之后,通常都會面臨一個常見的問題:如何讓網站中的所有頁面,都能載入這個js腳本文件呢?有多種方法都能實現這個效果,但在這里,我們將使用最簡單的方法:通過Custom Action來實現。
在Visual Studio 2010中新建一個SharePoint 2010項目,然后在項目中添加一個空元素。在元素文件Elements.xml中,添加新的CustomAction標簽。通過設置Location屬性為ScriptLink,就可以方便的將ScriptSrc所指定的js腳本文件,自動“注入”到網站的所有頁面上。
1: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
2: <CustomAction Id="beaee891-f767-4008-a97e-7e65ee985191"
3: Title="ScriptLink.jQuery"
4: Location="ScriptLink"
5: ScriptSrc="~site/HitCounterModule/jquery-1.7.2.min.js"/>
6: <CustomAction Id="beaee891-f767-4008-a97e-7e65ee985191"
7: Title="ScriptLink.jQuery.cookie"
8: Location="ScriptLink"
9: ScriptSrc="~site/HitCounterModule/jquery.cookie.js"/>
10: <CustomAction Id="878410B6-6932-42C8-B551-D99ACBC66B86"
11: Title="ScriptLink.webHitCounter"
12: Location="ScriptLink"
13: ScriptSrc="~site/HitCounterModule/webHitCounter.js"/>
14: </Elements>
在上面的這個元素文件中,我添加了3個CustomAction標簽,它們注冊了3個js腳本文件:
- jquery-1.7.2.min.js:jQuery庫
- jquery.cookie.js:一個用來操作cookie的jQuery插件
- webHitCounter.js:我們將稍后創建它,計數器的邏輯代碼將放到這個腳本文件中
在ScriptSrc屬性中,我指定了“~site/HitCounterModule/xxx.js”這樣的路徑。這是因為稍后,我們將會把這3個腳本文件都放到網站的HitCounterModule這個文件夾中。
接着我們來真正的創建這些js腳本文件。實際上,前面兩個與jQuery有關的腳本文件我們只需要復制過來就好了,真正需要我們編寫的,只有那個webHitCounter.js文件。
在項目中添加一個模塊,將2個jQuery有關的文件復制到模塊文件夾中,並同時在模塊文件夾中創建第3個腳本文件:webHitCounter.js。打開這個模塊的元素文件Elements.xml,Visual Studio已經自動將這3個腳本文件的內容添加到了Elements.xml中,我們來將它的內容按照下面所示稍作修改。Module標簽的Url屬性指定了這些文件都將放到網站的HitCounterModule文件夾中。每個File子標簽都表示要將一個文件放到SharePoint網站中。最終,這個模塊的作用就是將這3個js腳本文件都發布到網站的HitCounterModule文件夾里面。
1: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
2: <Module Name="HitCounterModule" Url="HitCounterModule">
3: <File Path="HitCounterModule\webHitCounter.js" Url="webHitCounter.js" Type="Ghostable" />
4: <File Path="HitCounterModule\jquery-1.7.2.min.js" Url="jquery-1.7.2.min.js" Type="Ghostable" />
5: <File Path="HitCounterModule\jquery.cookie.js" Url="jquery.cookie.js" Type="Ghostable" />
6: </Module>
7: </Elements>
現在,我們的Visual Studio項目中已經包含了所有必需的組件。將各個組件的名稱,按照你喜歡的方式重新命名一下。下面這個截圖是我的Visual Studio里面項目管理器所呈現的樣子(我給各個組件起的名字和你的不一定相同),HitCounterModule是用來將3個js腳本文件發布到網站中的模塊(它也同時包含了這3個js文件),HitCounterJavaScriptCA是用來向網站所有頁面中“注入”那3個js腳本文件的Custom Action,我為Feature起的名字叫做HitCounterWeb。
最后,我們開始做“正事”,編寫webHitCounter.js里面的腳本代碼!
首先,我們來創建一個函數getWebHitCountAsync(),獲取當前網站計數器的值。我們將網站計數器的值存儲在網站對象(SPWeb)的附加屬性里面,並為這個屬性起名為webHitCount。代碼使用了SharePoint 2010 JavaScript Client Object Model來從服務器端拿到網站對象的這個屬性的值。由於JavaScript與服務器端的通信都是基於異步模式,所以我使用了Promise模型來對函數稍微做了一下封裝。
1: function getWebHitCountAsync() {
2: return $.Deferred(function (dtd) {
3: var ctx = SP.ClientContext.get_current();
4: var web = ctx.get_web();
5: var webProps = web.get_allProperties();
6: ctx.load(webProps);
7: ctx.executeQueryAsync(function () {
8: var hitCount = webProps.get_fieldValues()['webHitCount'];
9: if (!hitCount) {
10: hitCount = 0;
11: }
12: dtd.resolve(hitCount);
13: }, function () {
14: dtd.reject(0);
15: });
16: }).promise();
17: }
接着創建一個increaseWebHitCountAsync()函數,它的作用是將網站計數器加一。
1: function increaseWebHitCountAsync() {
2: return $.Deferred(function (dtd) {
3: getWebHitCountAsync().done(function (hitCount) {
4: var ctx = SP.ClientContext.get_current();
5: var web = ctx.get_web();
6: var webProps = web.get_allProperties();
7: webProps.set_item('webHitCount', ++hitCount);
8: web.update();
9: ctx.executeQueryAsync(function () {
10: dtd.resolve();
11: }, function () {
12: dtd.reject();
13: });
14: });
15: }).promise();
16: }
最后,創建一個onPageLoad()函數,並讓它在頁面載入之后運行(通過將函數名放入到_spBodyOnLoadFunctionNames數組)。它的作用是首先調用getWebHitCountAsync()函數,獲取當前網站計數器的值,並調用displayHitCount()函數在頁面上顯示計數器(這個函數的代碼在文章后面)。接着,它檢測一下是否存在一個名為hitted的cookie,如果沒有,它就調用increaseWebHitCountAsync()函數,來將網站計數器加一,並同時寫入這個名為hitted的cookie。
1: function onPageLoad() {
2: ExecuteOrDelayUntilScriptLoaded(function () {
3: getWebHitCountAsync().done(function (hitCount) {
4: displayHitCount(hitCount);
5:
6: if (!$.cookie('hitted')) {
7: increaseWebHitCountAsync().done(function () {
8: $.cookie('hitted', 'true');
9: });
10: }
11: });
12: }, 'SP.js');
13: }
14:
15: _spBodyOnLoadFunctionNames.push('onPageLoad');
為什么要使用這樣的一個cookie呢?這是因為我們希望網站計數器只在用戶第一次打開網站頁面的時候,為計數器加一。所以我們在修改了計數器之后,就向瀏覽器寫入一個標志性的cookie,並不設置它的過期時間。對於沒有過期時間的cookie,瀏覽器默認會在關閉時刪除它,這樣當用戶下次打開瀏覽器再次訪問網站時,這時cookie已經沒有了,於是就會再次將計數器加一。只要用戶持續在瀏覽器里面訪問網站,這個cookie就會一直存在,這樣腳本就只會獲取最新的計數器值,而不會去不停的更新計數器了。
用來將計數器值顯示在頁面上的displayHitCount()函數的實現如下。
1: function displayHitCount(hitCount) {
2: $('<div style="text-align:left;padding-left:10px;margin-top:10px;display:none">網站計數器:' + hitCount + '</div>').appendTo('.ms-quickLaunch').slideDown('slow');
3: }
它的作用就是在頁面左側的快速啟動區域的最下方,顯示出當前網站計數器的值,效果如下圖:
最后要提一句的是,我們創建的這個SharePoint應用程序,完全可以作為一個沙盒解決方案(sandboxed solution)部署到SharePoint中。(嗯,實際上,我鼓勵只要可能,就盡量將SharePoint應用程序編寫成能兼容沙盒解決方案。)
整個項目的源碼下載:http://files.cnblogs.com/kaneboy/SharePointHitCounter.zip
最后(這次是真的最后了),如果你僅僅就是想為網站添加這樣一個計數器,你不懂Visual Studio,也不懂SharePoint開發,唯一的工具就是SharePoint Designer,那么你也是可以使用SharePoint Designer來實現並部署這個網站計數器的。下一篇文章將講述如何使用SharePoint Designer來將這個網站計數器部署到SharePoint網站里面。