1. 程式人生 > >《開源框架那點事兒23》:Tiny模板語言(VelocityPlus)初步入門

《開源框架那點事兒23》:Tiny模板語言(VelocityPlus)初步入門

1 關於使用者手冊

本文主要介紹如何在模板中使用Tiny模板語言,通過查閱本手冊,可以對Tiny模板語言 TTL(Tiny Template Language)的用法有一個較全面的認識,並學會如何有效地使用Tiny模板語言。同時,本文提供了較多的例子幫您來學習並掌握它。

2 Tiny模板語言概述

Tiny 模板語言是一個參考Velocity語法的模板語言,它對Velocity模板語言中一些功能不太完全及使用過程中比較不方便的地方進行全面的擴充套件和升級,同時為了更好的適應Web介面層的開發,還提供了強大的佈局功能。本文中的例子都使用Tiny 模板語言來開發。

<HTML>
<BODY>
Hello ${customer.Name}!
<table>
#for( mud : mudsOnSpecial )
   #if ( customer.hasPurchased(mud) )
      <tr>
        <td>
          ${flogger.getPromo( mud )}
        </td>
      </tr>
   #end
#end
</table>
</BODY>
</HTML>

感謝您選擇Tiny模板引擎!

3 Tiny模板語言能為您做什麼?

假設您是一家專門出售Mud的線上商店的頁面設計人員,讓我們暫且稱它為“線上MUD商店”。您的業務非常繁忙,客戶下了各種型別和數量的Mud訂單。他們都是通過使用者名稱和密碼登陸到您的網站,登陸後就允許他們檢視訂單併購買更多的Mud。現在,一種非常流行的Mud正在打折銷售。另外有一些客戶規律性地購買另外一種也在打折但不是很流行的Bright Red Mud,由於購買的人並不多,所以它被安置在頁面的邊緣。另外所有使用者的操作資訊都是被跟蹤並存放於資料庫中的,所以某天有一個問題可能會冒出來:如何給每個使用者定製一個自己的頁面,讓他們瀏覽自己的感興趣的物品。為什麼不使用模板語言來使使用者更好的瀏覽他們感興趣的商品呢?而Tiny模板語言就是一個非常不錯的選擇。

Tiny Template使得定製化Web頁面非常容易。作為一個Web Site的設計人員,您希望每個使用者登陸時都擁有自己的頁面。

您諮詢了一些公司內的軟體工程師,您發現他們每個人都同意客戶應該擁有具有個性化的資訊。那讓我們把軟體工程師應該作的事情放在一邊,看一看您應該作些什麼吧。

您可以在頁面內巢狀如下的TTL宣告:

<HTML>
<BODY>
Hello ${customer.Name}!
<table>
#foreach( mud : mudsOnSpecial )
   #if ( customer.hasPurchased(mud) )
      <tr>
        <td>
          ${flogger.getPromo( mud )}
        </td>
      </tr>
   #end
#end
</table>
</BODY>
</HTML>

使用Tiny模板引擎實現WEB介面就是這麼簡單!本文後續會有更全面的TTL語法介紹,掌握這些,您將會全面體會到Tiny模板引擎的威力。

4 Tiny模板語言簡介

Tiny模板語言的目標是提供一個簡潔、易學的方法將動態內容展現到Web頁面上,使得Web頁面設計者可以在沒有任何程式語言經驗就可以在非常短的時間內(一天?)學會使用它,增強您的網站展現力。

TTL使用引用這種方式將動態內容(一般指Java程式碼中生成的資料物件)顯示到您的Web Site上。Tiny模板語言的變數只是引用中的一種,變數是用來描述要展現到檢視模板中的Java資料物件。當然,Java程式碼也可以從模板TTL中獲取資料,以下是一個寫在HTML中的TTL變數:

#set( a = "Tiny" )

TTL語句:所有的TTL 語句都是以#開頭,且包含一個指令(這裡是set),當用戶訪問您的頁面時, Tiny模板引擎將搜尋頁面中的所有“#”符號,如果確定這是一個TTL語句時就按規則處理動態內容, 符號“#”僅僅只是表明這可能是一個TTL宣告。

符號“#”所跟的set我們用“指令”這一名詞來稱呼它(隨後介紹更多的指令),set指令使用一個表示式(expression) (包含在一對括號裡)將一個值value(這裡是字串“Tiny”)賦給變數a,(變數名在左邊,值在右邊,用“=”組合起來)。

在以上的例子中,變數是a,無需額外特殊符號標記變數,所賦值的字串要用引號括起。而字串的拼接可以使用運算子“+”操作,或者系統函式format進行格式化拼裝。

請理解Tiny模板語言基本規則:

${expression}輸出表達式的計算結果,而expression(表示式)中變數無需額外符號標記變數。而指令則以#開頭來表示,有點“做些什麼動作”的意思。

在上面的例子中,#set用來指定值給一個變數名a, 而變數名a的值就是"Tiny"。

5 Hello Tiny!

在您的HTML文件的任何地方,都可以引用一個變數名來輸出值, 如下例,先給變數foo 賦值為Tiny,然後將它輸出到頁面中。

<html>
<body>
#set( foo = "Tiny" )
Hello ${foo}!
</body>
<html>

在這個頁面上,您看到的將是 "Hello Tiny!"。

為了讓編輯器中的TTL指令更易讀,我們強烈建議您每行只有一條TTL指令,當然這不是必須的。 關於set 指令的更多功能我們隨後再討論。

6 註釋

註釋可以讓您在模板中包含對TTL或其它問題的說明描述以便與閱讀和理解。但它並不會在最終輸出的WEB頁面中看到。如下示例是TTL中的一行註釋。

## This is a single line comment.
## 這裡是行註釋內容

單行註釋是以“##”開頭的一行文字。如要寫下多行註釋,就要像下面那樣,將它們放入“#*”和“*#”間或“#--”和“--#”間:

#*
 Thus begins a multi-line comment. Online visitors won't
 see this text because the Tiny Templating Engine will
 ignore it.
*#
#--這裡是塊註釋內容 --#
#* 這裡是塊註釋內容 *#

雖然引擎只是提供了兩種簡單的註釋方式,但卻能滿足您在頁面上新增必要的說明文字。

之所以支援兩種塊註釋方式,是為了在相容性及方便性方面提供更大的便捷。#* *#方式是為了與Velocity相容,這樣熟悉Velocity的人員更容易上手。#-- --#是為了便於把Html中的註釋改成Tiny模板註釋。

7 引用(References)

TTL中有三種引用references:變數引用(variables),屬性引用(properties)和方法引用(methods)。作為使用TTL的頁面開發者, 您必須和您的Java工程師在特定的引用名稱上達成一致,這樣模板和Java程式碼才可按照你們的預期去結合以輸出正確的內容。

所有的引用在模板中的輸出都表現為一個字串。假設一個引用變數 foo ,它是一個int型變數, Tiny模板引擎在處理時將呼叫它的.toString()去解析這個物件(int),從而獲得代表它的字串。

7.1 變數(variables)

[_a-zA-Z][_a-zA-Z$0-9]*

上面的正則表示式表示,在Tiny框架引擎中,變數必須是以下劃線或大小寫字母開頭的,後續可以跟下劃線或大小寫字母和數字的字串,才可以作為變數名。實際上巨集的名字,也是遵守同樣的規則。

簡單地說,變數不需要任何額外的符號開頭,一個合法的TTL變數名是以字母開頭,後面可以是以下任意字元:

  • 字母(a .. z, A .. Z)
  • 數字(0 .. 9)
  • 下劃線 ("_")

以下是正確的TTL變數名:

foo
mudSlinger
mud_slinger

如果想在TTL中引用一個變數如 foo,可以通過set命令設定自己的值,也可以從Java程式碼中獲取。例如, Java變數foo的值為”bar”, 如果想在模板中輸出這個值,那麼模板中引用${foo}就可以在Web頁面中輸出所需值。另一種方式是在模板中使用如下TTL也可以達到這個目地。

#set(foo = "bar" )
${foo}

只要符合上面的規範的字串都可以作為Tiny框架引擎中的變數,即使是Java的關鍵字也可以。

需要注意的是,由於在進行迴圈時,Tiny模板引擎會在迴圈變數名後附加“For”作為狀態變數,因此,需要注意避免衝突,以影響使用。

7.2 屬性(properties)

TTL的第二種引用是屬性引用,屬性引用不需要任何額外特殊符號開頭,只需簡單地按照“變數名字.變數屬性”的形式即可。如下例:

customer.address
purchase.total

“customer.address”我們設想可能在兩種意思。首先它可能查詢一個型別為Map的customer的引用,並以“address”為key的一個數據物件。另外它可能表示的是Java物件customer中的getAddress()這個方法的返回值(當然也可寫成 customer.getAddress())。當用戶請求Web頁面,Tiny模板引擎將根據具體的customer型別進行處理。如果想在頁面直接輸出這個屬性,那麼應該加一個取值符號${},例如${customer.address}。

注意:在Tiny語言模板使用屬性的引用時,引擎首先會通過Java Bean中的getter/setter實現的,如果沒有找到相應的方法,引擎才會再去尋找該物件的屬性欄位,並且這個屬性訪問許可權只有為public時才能解析引用。而Java物件的其他受保護的資料域是不能直接引用的,Tiny模板引擎遵守Java資料安全規則。

如${foo.name}會解析到 物件foo的 getName()的例項方法或public name這個例項變數,但不會解析到Foos類的 private name這個例項變數。

7.3 方法(methods)

在Java 程式碼中定義方法是最平常的事。方法引用和其它引用一樣也是一個TTL宣告,看如下的例子可能可以更快地理解:

customer.getAddress()
purchase.getTotal()
page.setTitle( "My Home Page" )
person.setAttributes(["Strange", "Weird", "Excited"])

上述兩個例子中customer.getAddress()和purchase.getTotal()可以等同與屬性引用情況: customer.address和 purchase.total。如果您已經領悟到了這點,您的確是很聰明的!後面兩個引用也會直接對應Java物件的對應方法,不同的是傳入了引數。

8 表示式(Expression)

8.1 取值表示式

上文介紹了變數、屬性和方法呼叫等引用的定義。那麼要將這些引用的結果輸出列印都需要經過取值表示式。在Tiny引擎模板中取值表示式分為有兩種:

(1)${expression}:輸出表達式的計算結果

(2)$!{expression}:輸出表達式的計算結果,並轉義其中的 HTML 標籤。

其中expression必須是一個合法的Tiny Template表示式,如果您繼續閱讀本文後續的介紹將會了解表示式規範。Tiny模板引擎取值表示式{}不可以省略,${expression}和$expression不是等價的。如果表示式執行結果為null或void,則不會輸出任何內容。注意:取值表示式作為指令的引數時,不可以採用${expression}形式需要去掉{},同時在字串引數中,也不支援${expression}。也許您現在還不能理解這點,不過繼續閱讀下文您會慢慢領悟的。

8.2 Map常量

{expression:expression,...}

在模板中為了資料儲存、傳遞的方便,Tiny模板語言提供了Map常量的表達方式。Map常量經常直接作為指令或自定義巨集的引數,下面的例子希望能幫助您快速理解如何定義Map常量。

{}  ##表示空Map
{"aa":"aaValue","bb":"bbValue"}##純字串Map
{"aa":1,"bb":"bbValue"}		   ##數字及字串混合Map

上面的例子是告訴您如何定義Map常量,事實上,在模板中定一個Map變數也類似上面的形式,只不過您還需要使用#set指令,並制定一個具體的引數名。下面的例子希望能幫助您快速理解如何呼叫Map常量。

#set(map={"aa":1,"key":"bbValue"})
${map.key}
${map["key"]}
${map.get("key")}

{aa:1}和{"aa":1}的含義是不同的,這一點必須要注意。

{aa:1}表示key值是aa變數的值,${"aa":1}表示key值是"aa"的字串。

因此,如果寫為{aa:1}的形式時,如果沒有aa變數存在,則會報空指標錯誤。

如果不能確認,前面的變數是否為空,可以加一個安全呼叫方式:

${map?.key}
${map?.get("key")}

8.3 陣列常量

[expression,...]

在模板中定義陣列常量也十分簡單,看了下面的例子相信您一定可以掌握。

[]  ##表示空陣列
[1..5]##等價於[1,2,3,4,5]
[5..1]##等價於[5,4,3,2,1]
[(1+4)..1]##等價於[5,4,3,2,1]
[1,2,3,4,5]##純數字陣列
[1,"aa",2,"cc",3]##數字及字串混合陣列
[1,aa,2,"cc",3]##數字,變數,字串混合陣列

而呼叫陣列常量的方式有兩種,一種是直接通過下標索引的方式,另一種是呼叫get(index)方式。

${list[1]}
${list.get(1)}

如果不能確認,前面的變數是否為空,可以加一個安全呼叫方式:${list?.[index]}或${list?.get(1)}

8.4 其他表示式

型別

表示式

說明

邏輯運算

!

&&

||

自增/自減

++

--

不論放在變數前面與後面,沒有區別

算術計算

+

-

*

/

%

空值常量

null

移位運算

>> 

>>> 

<< 

比較運算

==

!= 

 >

>= 

 < 

 <=

==的執行邏輯請檢視13.3 關係和邏輯運算。

方法呼叫

functionName([...])

呼叫框架中的內嵌或擴充套件方法。

陣列讀取

array[i]

數字常量

123

123L

99.99F

99.99d

99.99e99 

-99.99E-10d

0xFF00

0xFF00L

0.001

0.001D

1.10D

 字首0x不可以寫成0X,字尾lfde可以用相應LFDE替換

成員方法呼叫

object.methodName([...])

可以通過框架為某種型別增加新的方法或覆蓋原有方法。

成員屬性訪問

object.fieldName

布林值常量

true

false

字串常量

"abc\r\n"

'abc\u00A0\r\n'

不論是單引號框起來的字串還是雙引號框起來的字串,都是一樣的,唯一的區別有,當字串中包含雙引號或單引號的時候可以少用轉義符。

位運算

~

^

&

|

三元表示式

exp?a:b

exp?:b

a?:b等價於a?a:b,當表示式比較複雜的時候,這種簡寫形式會比較漂亮,也更容易閱讀

Tiny模板引擎對於布林表示式進行多種強力支援,不僅僅只有布林值才可以參與運算,它的執行規則如下:

  • 如果是null,則返回false
  • 如果是布林值,則返回布林值
  • 如果是字串且為空串“”,則返回false
  • 如果是集合,且集合中沒有元素,則返回false
  • 如果是陣列,且陣列長度為0,則返回false
  • 如果是Iterator型別,則如果沒有後續元素,則返回false
  • 如果是Enumerator型別,則如果沒有後續元素,則返回false
  • 如果是Map型別且其裡面沒有KV對,則返回false
  • 否則返回true

在訪問屬性或成員變數的時候,普通的方式是用“.”運算子,也可以使用"?.”運算子,表示如果前置變數非空,都繼續執行取屬性值或呼叫成員函式,避免空指標異常的發生。

#if(0)zero#end會顯示zero,在Tiny模板語言中,只要有值就會返回true。

9 索引表示法

用類似foo[0]的方式可以獲取一個物件的指定索引的值。這種形式類似呼叫get(Object)方法,實際上是提供了一種簡略,比如foo.get(0)。因此以下幾種寫法都是呼叫get方法:

foo[0]     ## foo takes in an Integer look up
foo[i]     ## Using another reference as the index  
foo["bar"]   ## Passing a string where foo may be a Map

Java陣列適用相同的語法,因為Tiny模板引擎將陣列包裝成一個物件,它可以通過get(Integer)獲得指定索引物件的元素。例如:

foo.bar[1].junk
foo.callMethod()[1]
foo["apple"][4]

10 渲染

無論是變數、屬性還是方法等這些引用的最終結果值的渲染輸出本質都會轉換成String物件。例如要取值輸出一個Integer物件${foo},那麼Tiny 模板引擎就會呼叫它的.toString()方法,從而將物件解析轉換成一個字串。

11 與Java無縫對接

至此,您對Tiny模板語言已經有了一定程度的瞭解,相信您已經迫不及待的想使用它來開發應用了。但您不要忘記,Tiny模板語言與Java是無縫對接的,Tiny模板引擎設計者花費了一定的精力做到了與Java很好的相容,並且從Java語法中也汲取了一些優點,使得模板設計者更容易使用TTL。比如對於變數foo:${foo.getBar()}等同於${foo.bar}。

現在您大概瞭解到了Tiny模板語言引用的不同方式但得到的是相同的結果,事實上Tiny模板語言融合了Java和Java Bean的相關簡潔語法和規範來解析Java程式碼中的物件和這些物件的方法及其屬性,使得Java物件的大部分功能都可以展示到檢視中,同時還有較好的處理效能。

12 模板佈局

佈局在Tiny模板引擎中是一個非常重要的概念,通過Tiny模板引擎,可以快速進行頁面構建與渲染,並且減少程式設計師工作量。Tiny模板引擎設計者認為越到底層的程式設計師,所要完成的工作越少。如果您將Tiny模板語言與同類的模板引擎的佈局實現相比會發現,Tiny模板引擎中的佈局具有一定的強制性,這也同時減少了程式設計師的開發工作量,程式設計師不再需要關心佈局檔案的引入,只要放入有佈局檔案的目錄,就會應用佈局;您把它拿出來,它也就沒有了。

用於設定Tiny模板語言的佈局的檔案稱為佈局檔案。佈局佈局檔案的方法結構與普通模板檔案完全相同,只是它的副檔名與模板檔名不同,它的檔名以“.layout”結尾,用以區別。佈局檔案與模板檔案完全相同,只是在佈局檔案中需要放置一個#pageContent標籤,用以標示插入點。

為了更好的理解Tiny模板引擎中的佈局,直接用示例說明,下面是目錄結構:

template
 |
 +- tiny
     |
     +- layout
         |
         +- div
         |  +- aa.page
         |  +- default.layout
         +- default.layout

/template/tiny/layout/div目錄中aa.page的內容如下:

Hello,World

/template/tiny/layout/div目錄中default.layout的內容如下:

<b>
    #pageContent
</b>

/template/tiny/layout目錄中的default.layout的內容如下:

<div>
    #pageContent
</div>

下面是執行結果:

<div>
    <b>
    Hello,World
    </b>
</div>

也就是說,雖然aa.page檔案裡只有Hello,World,但是由於在與它同名路徑中有一個佈局檔案,因此用佈局檔案對其進行了渲染,從而變成下面的內容:

<b>
Hello,World
</b>

但是引擎發現它上層目錄中另外還有一個佈局檔案/template/tiny/layout/default.layout,於是引擎就被渲染出上文看到的最終結果。

在Tiny模板語言中使用佈局十分方便,佈局檔案不需要在模板檔案進行顯式宣告。佈局檔案的命名規範為:模板基本檔名+“.”+佈局副檔名,比如:模板檔名為:aa.page,則模板基本檔名為aa,其佈局副檔名為layout,這個時候它的佈局檔名就是:aa.layout。

Tiny模板引擎中有一個特殊的佈局檔名,它就是default+"."+佈局副檔名,比如:佈局副檔名為layout,這個時候它的佈局檔名就是:default.layout。

為了說明模板佈局的進階用法,請看下面的舉例,假如有下面的目錄:

template
 |
 +- tiny
     |
     +- layout
         +- div
         |  +- aa.page
         |  +- aa.layout
         |  +- bb.page
         |  + default.layout
         +- default.layout

/template/tiny/layout/div目錄中aa.page的內容如下:

Hello,World

/template/tiny/layout/div目錄中bb.page的內容如下:

Hello,悠然

/template/tiny/layout/div目錄中default.layout的內容如下:

<b>
    #pageContent
</b>

/template/tiny/layout/div目錄中aa.layout的內容如下:

<h3>
    #pageContent
</h3>

/template/tiny/layout目錄中的default.layout的內容如下:

<div>
    #pageContent
</div>

aa.page執行結果如下:

<div>
    <h3>
    Hello,World
    </h3>
</div>

bb.page執行結果如下:

<div>
    <b>
    Hello,悠然
    </b>
</div>

聰明的您一定明白了,佈局檔案的渲染過程是這樣的,優先渲染與模板檔案同名的佈局檔案,只有不存在與模板檔案同名的佈局檔案的時候,才會渲染default.layout佈局檔案。詳細的渲染過程分析如下:

aa.page先去找同級aa.layout,如果找到了,渲染同級aa.layout。再往上一級遞迴渲染到上一級的default.layout。

bb.page先去找同級bb.layout,如果找不到,去找同級default.layout。如果找到,渲染同級default.layout。再往上一級遞迴,渲染到上一級的default.layout。

Tiny模板引擎的預設副檔名為layout、component、page,分別代表而已檔案、巨集檔案、頁面檔案。在實際應用當中,也可以根據自己的喜好設定為其它的名字。

13 指令集

在模板中您可以使用“引用”生成動態內容,而指令簡單地說就是設計者在模板中操作Java物件,方便頁面設計者有效地控制輸出內容的格式。

指令總是以#開頭後面緊跟具體的指令符。

13.1 #set指令

#set(name1=expression,name2=expression,[...])用於向當前上下文賦值
#!set(name1=expression,name2=expression,[...])用於向當前模板的上下文賦值。

#set指令通常是用來給一個引用賦值。賦值物件不僅可以是變數引用,還可以是屬性引用。如下示:

#set( primate = "monkey" )

注意:Tiny模板語言的#set指令賦值的內容可以直接是變數名,但是不需採用${變數名}的形式賦值。如#set( customer.Behavior = $primate )就是一種錯誤的寫法。

“左運算元被賦值“是引用操作的一個規則。=號右側可能是以下型別之一:

  • Variable reference變數引用 
  • String literal字串 
  • Property reference 屬性引用
  • Method reference 命令引用
  • Number literal 數字
  • ArrayList 陣列
  • Map 對映

請看下面例子,可以幫助聰明的您理解上述型別設定的理解:

#set( monkey = bill ) ## variable reference
#set( blame = whitehouse.Leak ) ## property reference
#set( number = 123 ) ##number literal
#set( friend = "monica" ) ## string literal
#set( say = ["Not", friend, "fault"] ) ## ArrayList
#set( map = {"banana" : "good", "kg" : 1}) ## Map

相關推薦

開源框架事兒23Tiny模板語言(VelocityPlus)初步入門

1 關於使用者手冊 本文主要介紹如何在模板中使用Tiny模板語言,通過查閱本手冊,可以對Tiny模板語言 TTL(Tiny Template Language)的用法有一個較全面的認識,並學會如何有效地使用Tiny模板語言。同時,本文提供了較多的例子幫您來學習並掌握它。

開源框架事兒23採用TinyDB元件方式開發

採用TinyDB元件方式開發 步驟 Icon 前文介紹四則運算的流程程式設計開發時,說過流程編排在開發重複功能時,可以利用已有的元件庫快速開發。對於開發人員而言只需要簡單配置流程就可以完成工作了。 開發增刪改查的元件介面。本來這部分很花費時間,如果採用元件複用的話,就可以實現

開源框架事兒19》特斯拉建“樁”與開源的生命力

充電站 otto 期權 eas gb2 平臺 程序 蘋果 名詞 在美國的矽谷,在中國的中關村,很多的技術先驅者懷揣夢想。用激情不懈地追求著他們宏遠的目標和巨大的個人財富。開源。正在成為這個時代眼下最火熱的名詞之中的一個。開源精神,作為一種合作協同的驅動力,正在發展為一種更

開源框架事兒25》框架模板引擎實現方式的改造實錄

port 內嵌 代碼調試 iter put 文件路徑 children nts fault 點滴悟透設計思想,Tiny模板引擎優化實錄! 增加框架設計興趣小組:http://bbs.tinygroup.org/group-113-1.html Tiny模板引擎的實

Map大家族的事兒(2)AbstractMap

bstr ans == new 實現 狀態 返回 說過 後者 AbstractMap是一個抽象類,它是Map接口的一個骨架實現,最小化實現了此接口提供的抽象函數。在Java的Collection框架中基本都遵循了這一規定,骨架實現在接口與實現類之間構建了一層抽象,其目的是

Map 大家族的事兒 ( 5 ) WeakHashMap

WeakHashMap是一個基於Map介面實現的散列表,實現細節與HashMap類似(都有負載因子、雜湊函式等等,但沒有HashMap那麼多優化手段),它的特殊之處在於每個key都是一個弱引用。 首先我們要明白什麼是弱引用,Java將引用分為四類(從JDK1.2開始),強度

Map 大家族的事兒 ( 6 ) LinkedHashMap

LinkedHashMap繼承HashMap並實現了Map介面,同時具有可預測的迭代順序(按照插入順序排序)。它與HashMap的不同之處在於,維護了一條貫穿其全部Entry的雙向連結串列(因為額外維護了連結串列的關係,效能上要略差於HashMap,不過集合檢視的遍歷時間與

乾貨分享清法網路分析小紅書內容運營事兒

有人說小紅書是“一夜爆紅”,其實不然。事實上,任何平臺的火爆都少不了長期的SEO優化。搜尋公關專家清法認為,雖然小紅書的成功大部分歸功於內容營銷,但是小紅書中的內容運營策略與SEO優化密不可分。一、使用者定位使用者定位是SEO優化過程中必不可少的步驟。我們建一個網站,要考慮使用者有哪些需求,再對使用者的需求進

幹貨分享清法網絡分析小紅書內容運營事兒

女性 發現 不難 不可 文案 最大 標題 官方 集中 有人說小紅書是“一夜爆紅”,其實不然。事實上,任何平臺的火爆都少不了長期的SEO優化。搜索公關專家清法認為,雖然小紅書的成功大部分歸功於內容營銷,但是小紅書中的內容運營策略與SEO優化密不可分。一、用戶定位用戶定位是SE

MVC之前的事兒系列(8)UrlRouting的理解

文章內容 根據對Http Runtime和Http Pipeline的分析,我們知道一個ASP.NET應用程式可以有多個HttpModuel,但是隻能有一個HttpHandler,並且通過這個HttpHandler的BeginProcessRequest(或ProcessRequest)來處理並返回請求,前

MVC之前的事兒系列(7)WebActivator的實現原理詳解

文章內容 上篇文章,我們分析如何動態註冊HttpModule的實現,本篇我們來分析一下通過上篇程式碼原理實現的WebActivator類庫,WebActivator提供了3種功能,允許我們分別在HttpApplication初始化之前,之後以及ShutDown的時候分別執行指定的程式碼,示例如下: [

MVC之前的事兒系列(9)MVC如何在Pipeline中接管請求的?

文章內容 上個章節我們講到了,可以在HttpModules初始化之前動態新增Route的方式來自定義自己的HttpHandler,最終接管請求的,那MVC是這麼實現的麼?本章節我們就來分析一下相關的MVC原始碼來驗證一下我們的這個問題。 先建立一個MVC3的Web Application,選擇預設的模

MVC之前的事兒系列(3)HttpRuntime詳解分析(下)

文章內容 話說,經過各種各樣複雜的我們不知道的內部處理,非託管程式碼正式開始呼叫ISPAIRuntime的ProcessRequest方法了(ISPAIRuntime繼承了IISPAIRuntime介面,該介面可以和COM進行互動,並且暴露了ProcessRequest介面方法)。至於為什麼要呼叫這個方法,

MVC之前的事兒系列(4)Http Pipeline詳細分析(上)

文章內容 繼續上一章節的內容,通過HttpApplicationFactory的GetApplicationInstance靜態方法獲取例項,然後執行該例項的BeginProcessRequest方法進行執行餘下的Http Pipeline 操作,程式碼如下: // Get application i

MVC之前的事兒系列(5)Http Pipeline詳細分析(下)

文章內容 接上面的章節,我們這篇要講解的是Pipeline是執行的各種事件,我們知道,在自定義的HttpModule的Init方法裡,我們可以新增自己的事件,比如如下程式碼: public class Test : IHttpModule { public void Init(HttpAp

MVC之前的事兒系列(2)HttpRuntime詳解分析(上)

文章內容 從上章文章都知道,asp.net是執行在HttpRuntime裡的,但是從CLR如何進入HttpRuntime的,可能大家都不太清晰。本章節就是通過深入分析.Net4的原始碼來展示其中的重要步驟。請先看下圖:   首先,CLR在初始化載入的時候,會載入一個非常重要的類AppManagerApp

MVC之前的事兒系列(6)動態註冊HttpModule

文章內容 通過前面的章節,我們知道HttpApplication在初始化的時候會初始化所有配置檔案裡註冊的HttpModules,那麼有一個疑問,能否初始化之前動態載入HttpModule,而不是隻從Web.config裡讀取? 答案是肯定的, ASP.NET MVC3釋出的時候提供了一個Microsof

MVC之前的事兒系列(10)MVC為什麼不再需要註冊萬用字元(*.*)了?

文章內容 很多教程裡都提到了,在部署MVC程式的時候要配置萬用字元對映(或者是*.mvc)到aspnet_ISPAI.dll上,在.NET4.0之前確實應該這麼多,但是.NET4.0之後已經不要再費事了,因為它預設就支援了。 你可以會問,沒有對映配置,請求這麼可能會走到aspnet_ISPAI.dll

AOP事兒面向切面程式設計(1)

今天我要和大家分享的是 AOP(Aspect-Oriented Programming)這個東西,名字與 OOP 僅差一個字母,其實它是對 OOP 程式設計方式的一種補充,並非是取而代之。翻譯過來就是“面向方面程式設計”,可我更傾向於翻譯為“面向切面程式設計”。

黑產揭祕“打碼平臺”事兒

簡介 網際網路業務的飛速發展,日漸滲透人類的生活,對經濟、文化、社會產生巨大的影響,同時網際網路業務安全也日趨重要。如同網路通訊的基礎安全設施防火牆,網際網路業務安全也有其基礎安全設施--圖片驗證碼和簡訊驗證碼。在網際網路業務中,廣泛使用圖形驗證碼用於區分