Drupal8中的Twig
Drupal8中Twig替換了PHPTemplate作為預設的模板引擎,導致的結果之一就是模版的字尾由原來的.tpl.php變成了.html.twig
搜尋Twig模版中的變數在使用Twig模版的時候,大部分的變數都以註釋的形式寫在了模版中。然後,當我們新增了變數,我們就需要一個可以搜尋到當前模版所有變數的方法。Twig提供了dump函式。
dump函式並不會列印所有的輸出,除非開啟了debug。
dump函式用於列印單個變數的資訊或者模版中的所有變數。
單個變數如果你的模版中有一個title變數,下面在你的模版中dump出這個變數的內容:
|
|
要打印出模版中的所有的變數,你可以:
|
|
要打印出變數的鍵:
|
|
PS: 這裡的_context是一全域性變數,指當前模版中所有的上下文和變數,比如透過theme函式傳遞的變數,preprocess函式處理的變數,或者呼叫set設定的變數。
全域性變數:
_context 當前模版中所有的上下文和變數_charset 只當前的編碼方式慎用dump()dump()函式雖然可以輸出所有的變數,但是卻帶來了巨大的記憶體消耗,故你可以迴圈_context來檢視所有的鍵:
|
|
接下來再加上一些條件判斷,就可以看到你需要的變量了。
Drupal8主題模版命名慣例Drupal是按照一定的命名慣例來載入模版的,這就方便開發者可以覆蓋原有的模版。當然,記得清除快取。
HTMLHTML模版提供了包括head,title以及body標籤等基礎結構的html頁面。
基礎模版:html.html.twig(位於:core/modules/system/templates/html.html.twig)
下面是一些你可以覆蓋的基礎模版的例子:
html—internalviewpath.html.twightml—node—id.html.twightml.html.twigPage模版名稱模式:page—[front|internal/path].html.twig
基礎模版:page.html.twig(位於: core/modules/system/templates/page.html.twig)
下面是page模版的模版建議,舉個例子“http://www.example.com/node/1/edit”:
page—node—edit.html.twigpage—node—1.html.twigpage—node.html.twigpage.html.twigRegions模版名稱模式:region—[region].html.twig
基礎模版:region.html.twig(位於: core/modules/system/templates/region.html.twig)
當一個頁面的區域中有內容時,系統會從區塊系統或者一個類似於hook_page_build()的方法中呼叫區域模版。
Blocks模版名稱模式:block—[module|-delta]].html.twig
基礎模版:block.html.twig (位於: core/modules/block/templates/block.html.twig)
block—module—delta.html.twigblock—module.html.twigblock.html.twig這裡的module就是模組名,delta是模組給區塊設定的內部id標識
Nodes模版名稱模式:node—[type|nodeid]—[viewmode].html.twig基礎模版:node.html.twig (位於: core/modules/node/templates/node.html.twig)
模版建議:
node—nodeid—viewmode.html.twignode—nodeid.html.twignode—type—viewmode.html.twignode—type.html.twignode—viewmode.html.twignode.html.twigTaxonomy terms
taxonomy-term.html.twigtaxonomy-term--<vocab-machine-name>.html.twignode–<nid>.html.twig, ie: node–<nid>.html.twig, ie: taxonomy-term--ingredients.html.twigtaxonomy-term--<tid>.html.twig, ie: taxonomy-term--1.html.twigFields
field–<field-type>.html.twig, ie: field–long-text.html.twigfield–<field-name>.html.twig, ie: field–phone-number.html.twigComments
comment.html.twigcomment-wrapper.html.twigForums模版名稱模式:forums—[[container|topic]—forumID].html.twig
基礎模版: forums.html.twig (位於: core/modules/forum/templates/forums.html.twig)
模版建議:
論壇容器:forums—containers—forumID.html.twigforums—forumID.html.twigforums—containers.html.twigforums.html.twig論壇主題內容forums—topics—forumID.html.twigforums—forumID.html.twigforums—topics.html.twigforums.html.twigPHPTemplate與Twig主題範例的比較接下來,看下PHPTemplate與Twig的區別。
關於TwigTwig是基於php的編譯模版語言。當你的頁面需要渲染顯示的時候,Twig引擎會找到對應的模版並把它編譯成php模版,存放在sites/default/files/php_storage/目錄下。
1.DocblockPHPTemplate:
|
|
Twig:
|
|
PHPTemplate檔案:node—article.tpl.phpTwig檔案:node—article.html.twig
PHPTemplate函式:theme_node_links()Twig檔案:node-links.html.twig
3.變數輸出一個變數
PHPTemplate:
|
|
Twig:
|
|
輸出一個雜湊鍵值
PHPTemplate:
|
|
Twig:
|
|
變數賦值
PHPTemplate:
|
|
Twig:
|
|
陣列初始化
PHPTemplate:
|
|
Twig:
|
|
PHPTemplate:
|
|
Twig:
|
|
PHPTemplate:
|
|
Twig:
|
|
PHPTemplate:
|
|
Twig:
|
|
PHPTemplate:
|
|
Twig:
|
|
PHPTemplate:
|
|
Twig:
|
|
check_plain:
PHPTemplate:
|
|
Twig:
|
|
Translate:
PHPTemplate:
|
|
Twig:
|
|
Translate with substitutions:
PHPTemplate:
|
|
Twig:
|
|
Drupal8 Twig(採用trans標籤擴充套件)
|
|
implode:
PHPTemplate:
|
|
Twig:
|
|
PHPTemplate的例子中$usernames需要是一個字串陣列。原生的Twig也需要$usernames是一個字串陣列。但是Drupal8中的twig還可以是一個可以渲染的陣列物件。這就是Drupal8中的twig與原生twig的本質區別。Drupal8中的twig可以“列印”出純文字和可渲染的陣列。
舉個例子:
|
|
在上面的例子中,每一個數據項都是以逗號相隔的。但是,輸出的結果卻是:
|
|
Escape:
PHPTemplate:
|
|
原生Twig:
|
|
Drupal 8 Twig2:
|
|
|
|
類似於
|
|
twig模版引擎提供了一個debug工具。
啟用debugging在sites/default/services.yml啟用Twig Debugging。
設定debug變數為true
|
|
出於效能考慮,Twig模版被編譯成一個PHP類存放在磁碟上,但這意味著預設情況下,你的模版不會在你做出更改時發生重新整理。為了使Twig模版可以自動重新整理,啟用services.yml中的deubg選項。欲知詳情,參見:https://drupal.org/node/1903374
列印所有的變數
|
|
|
|
Twig中的Filters用於修改變數。Filters和變數之間用管道符號(|)分隔,還可能帶點可選的引數。多個filters可以鏈式的連在一起,前一個的輸出作為下一個的輸入。
例如:
|
|
Drupal的Twig模版中使用的filter由所有的Twig引擎自帶的filter和drupal中的幾個特殊的filters組成。
Twig filters詳見:twig filter列表
Drupal自身的filtersDrupal中的filters是在Drupal\Core\Template\TwigExtension::getFilters().中宣告的。
翻譯filterst
t filter呼叫Drupal的t函式翻譯給定的字串,可用於任何字串。
例如:
例如:
|
|
|
|
儘可能避免使用|raw filter,特別是你正在輸出一些使用者輸入的資料的時候。詳見https://www.drupal.org/node/2296163:
|
|
drupal_escape
drupal_escape用於將一個字串進行安全處理後進行插入操作並輸出顯示,它替代了twig預設的escape filter。參見twig_drupal_escape_filter
safe_join
safe_join將幾個字串用給定的分隔符連線在一塊兒。
例如:
|
|
without
例如:
|
|
clean_class
clean_class filter會處理出一個安全的可用的html類名。詳見:Html::getClass()
clean_id
clean_id filter會處理出一個安全的可用的html id。詳見:Html:getID()
format_date
format_date filter格式化日期字串,詳見:DateFormatter::format()
Functions—-Twig模版中的函式url()
path()
url_from_path()
link($text, $url, $attributes)
|
|
file_url($uri)
路徑引數需要是相對網站根目錄的相對路徑,將會返回這個檔案的絕對路徑。
attach_library()
Twig最佳實踐—-預處理函式和模版為了使Drupal8的主題效能最大化,以及更加的定製化,請遵照如下的最佳實踐方式:
使用預處理函式返回可渲染陣列總是透過預處理函式返回可渲染陣列,而不是呼叫theme()或者drupal_render()函式。
Twig會自動渲染,故沒有必要呼叫theme()或者drupal_render()函式。此外,為了比直接輸出已經渲染的html程式碼更具定製化,渲染陣列應該傳遞給模版。
|
|
從預處理函式中刪除drupal_render()函式就是不再呼叫它:
|
|
通常情況下,drupal_render()函式是在新增表格資料的時候呼叫。
|
|
舉個例子:
之前的做法:
預處理函式中:
|
|
現在的做法:
模版中:
之前(PHPTemplate模版):
|
|
之後(預處理):
|
|
之後(Twig模版):
|
|
建立drupal8主題的第一步,就是建立一個THEMENAME.info.yml檔案。有一點很重要,.info.yml檔案中的“type”鍵需要設定成“theme”。
建立一個.info.yml檔案在主題資料夾的根目錄建立.info.yml檔案。資料夾的名字應該保持與.info.yml檔名相同。所以,如果你的主題命名為“Fluffiness”,那麼資料夾的名字就是“fluffiness”,而.info.yml檔案的名字是“fluffiness/fluffiness.info.yml”。
例如:
|
|
在你的drupal站點中,核心提供的主題包含著很多.info.yml檔案可以供你查閱例項。
主題的位置主題必須放置在Drupal安裝根目錄的“themes”資料夾中。注意,核心的主題,例如:Bartik和Seven位於core/themes資料夾下。
一個好的建議是,建立一個名為“contrib”的資料夾用於存放下載的貢獻主題,而“custom”資料夾用於存放自定義的主題。
主體名稱必須小寫。
Drupal的目錄結構:
|
|
|
|
下面,介紹一下主題資料夾中的通用檔案。
*.info.yml主題必須包含*.info.yml檔案,此檔案定義了meta資料,樣式,還有區塊和區域資訊。
*.breakpoints.yml響應式設計相關的設定,詳見:*.breakpoints.yml設定
*.theme*.theme檔案是一個php檔案,包含了所有的邏輯處理程式碼和輸出前的預處理。
css/一個好的建議就是將css檔案存放在“css”自目錄下。
js/存放著主題需要的js檔案。
images/存放主題需要的圖片
screenshot.png主題的預覽圖
templates/核心主題Bartik的目錄結構:
|
|
為主題新增區域需要兩步:
在主題檔案.info.yml中新增區域的meta-data編輯page.html.twig檔案列印新的區域info檔案中新增區域區域定義成ragions鍵的子元素:
|
|
Region 鍵應是個字串,可以包含下劃線“_”。
模版中新增區域為了顯示區域中的內容,你需要確定新的區域也新增到了page.html.twig模版中。
例如:
|
|
模版中輸出:
|
|
此外,你可以把它們當成是Twig模版的普通變數,可以在任何需要的地方列印輸出。
預設區域可以在page.html.twig模版文件中查閱預設的區域
page.headerpage.primary_menupage.secondary_menupage.highlightedpage.helppage.contentpage.sidebar_firstpage.sidebar_secondpage.footerpage.breadcrumbDrupal8主題中新增樣式和js與Drupal7主題的區別有四個比較重要的區別:
去掉了THEME.info檔案,取而代之的是THEME.info.yml檔案THEME.info.yml檔案中的stylesheets屬性不復存在,改為庫的方式引入THEME.info.yml檔案中的scripts屬性不復存在,改為庫的方式引入每一個頁面的js只在需要時才載入,預設情況下,Drupal對於匿名使用者不會需要js。這意味著,jquery不會再在每個頁面自動載入了。因此,如果你的主題需要jquery或者其它的js,你需要透過“宣告依賴關係”來告訴Drupal這個js需要載入載入css/js的步驟:
將css或者js儲存到一個檔案定義一個包含js和css檔案的“library”在鉤子中,把這個庫追加給渲染陣列定義一個庫在主題資料夾中建立*.libraries.yml檔案來新增庫(假設你的主題名稱是fluffiness,那麼檔名就是fluffiness.libraries.yml)。每一個庫,都是css和js檔案的詳情列表:
|
|
這個例子中,假設cuddly-slider.js檔案位於主題的js子目錄中。
然後,需要記住的是,預設情況下,Drupal8不會在每一個頁面載入jquery;只在需要時載入。因此,我們需要自己宣告,主題的cuddly-slider庫依賴jQuery。
因此,為了保證上例的js/cuddly-slider.js可用,我們需要更新下:
|
|
當然,庫也可以只包含css,或者只包含js。大部分的主題可能會有一個global-styling庫,用於全域性載入樣式檔案:
|
|
而且,正如你所想,庫中定義的css的順序就是將來載入的順序。
在Drupal7中,你可以把媒體查詢屬性(screen, print, all)作為stylesheets屬性的子鍵,而現在你可以把它當作值定義,例如:
|
|
現在預設情況下,所有的js檔案都在頁尾載入。
|
|
你得設定header屬性為true。
覆蓋擴充套件庫那些定義在*.libraries.yml檔案中的庫可以透過主題的*.info.yml檔案中的libraries-override和libraries-extend項進行覆寫和擴充套件。
libraries-override
|
|
libraries-extend
libraries-extend為主題提供了一種可以修改庫的方式。比如,新增額外的主題依賴的庫。
|
|
在Twig模版中追加庫
透過呼叫twig的方法,attach_library()可以在twig模版中追加庫,例如:
|
|
追加給所有的頁面
為了所有頁面都載入這個庫,需要在主題的*.info.yml檔案中,libraries鍵的下面宣告:
|
|
在大部分情況下,你可能不希望所有的頁面載入你的庫,而是部分頁面載入。舉個例子來說,你可能只想在某個特定的區塊中載入,或者使用者訪問某個節點型別時載入。
主題可以透過實現THEME_preprocess_HOOK()方法達到這個效果。
例如,你想要在維護頁面追加你的庫,“HOOK”就是“maintenance_page”,然後你的方法就是:
|
|
你也可以為主題的其它hook做同樣的事情,當然你的函式中也可以包含邏輯處理。
重要提示:最通用的用法是根據當前的路由來載入庫:
|
|
在某些情況下,你可能想要根據某些php計算資訊來載入js。
在這種情況下,像之前一樣,建立一個js檔案並追加進來,再透過drupalSettings(替換Drupal7中的Drupal.settings)追加一些js設定項並由追加的js檔案讀取這些設定項。然後,為了使drupalSettings在我們的js檔案中生效,我們得像引入jQuery一樣操作:我們得在依賴中定義。
就像這樣:
|
|
以及
|
|
這樣cuddly-slider.js就可以訪問drupalSettings.fluffiness.cuddlySlider.foo了(這裡 === ‘bar’)。
在模版中使用attributesattributes是一個在每個twig模版中都有效的物件。attributes用來儲存所有的父容器的相關屬性,並提供有用的方法給開發者處理這些資料。
Attribute的方法attributes.addClass()
單個類:
|
|
多個類:
|
|
將會輸出:
|
|
html標籤與twig語法之間不能有任何空格!
attributes.removeClass()
|
|
將會輸出:
|
|
attributes.setAttribute($attribute, $value)
|
|
將會輸出:
|
|
attributes.removeAttribute($attribute, $value)
|
|
attributes.hasClass($class)
|
|
鏈式
|
|
|
|
將會輸出:
|
|
使用without filter
|
|
這裡列出的是比較重要的Drupal8中的主題變化
Drupal8預設輸出html5除了jQuery2.x之外,Drupal8還引入更多的前端框架,例如:Modernizr,Underscore.js,以及Backbone.js。Drupal8引入了Twig,替換了原來的預設模板引擎PHPTemplate。Drupal8處於效能考慮,預設啟用了類似css、js合併之類的預設特性。在drupal6和drupal7中,可以呼叫drupal_add_css()和drupal_add_js()函式新增css或者js,現在替換成了在渲染陣列中追加#attached屬性呼叫庫的方法。Drupal8不再支援IE6、7、8,啟用jQuery2.0,支援現代HTML5/CSS3瀏覽器。Drupal8不支援那些不支援SVG的瀏覽器(包括IE8和安卓瀏覽器2.3)。Drupal8的css中,減少了id的使用。Drupal8的css結構(檔案結構)基於SMACSS和BEMDrupal8將預處理函式中的css類移到了Twig模版中。