增減 Drupal HTML HEAD 的資訊 (Meta Tags & LINKs)

Drupal 頁面的 HTML <head> 有一堆 META TAGs 及 LINKs。這都是經 html.tpl.php 的 $head 輸出 ( $head = drupal_get_html_head() )。您可經由 hook_html_head_alter 修改其內容,比如要刪除 Drupal 的版權及版本宣告:


// 以 Bartik Theme 為例
function bartik_html_head_alter(&$head_elements){
  // dpm($head_elements); // 看看內裏有什麼怪東西

  // 找到了 'system_meta_generator' 這個不想要的傢伙
  unset($head_elements['system_meta_generator']);

  // 想增加 X-UA-Compatible,令 IE 永遠用最新的 Rendering Engine 或 Chrome Frame
  $head_elements['x_ua_Compatible'] = array(
    '#type' => 'html_tag', // 這不是必要的
    '#tag' => 'meta',
    '#attributes' => array(
      'http-equiv' => "X-UA-Compatible",
      'content' => "IE=edge,chrome=1",
    ),
  );
}

**
如果沒有效果:

一、你見鬼了;
二、忘記在 template.php 增減 FUNCTIONS 後重建 CACHES

特殊情況: 要是真的見鬼了,你可以手動修改 html.tpl.php,也不要在此留言帶給我衰氣 🙂
**

此外,也可以在 theme_preprocess_html() 或模組中利用 drupal_add_html_headdrupal_add_html_head_link 增加你想要的東西。

Drupal 8 會有什麼改變?

Drupal 7 差不多一周歲了,使用率也很高,根據 Drupal.org 的資料,D6 & D7 的數據差不多。模組的成熟度也不差,我這邊有相關數據,大家可以分析分析。

即使如此,還有不少個人開發者留戀 Drupal 6,甚至企業也有那方向傾向。或許,對於一些管理公司內部系統的開發者,並沒有必要升級或使用 Drupal 7,他們也許跳過此步,邁向 Drupal 8。在繁體中文世界而言,這也可能反映了相關翻譯處於緩慢或停滯狀態的原因 ?

Drupal 8 開發也近一年,有不少改變,做一個小總結,大家可以參考參考:

Backend:

  • 最易於看到的分別是資料夾結構改變了,大多 Drupal 核心檔案移動至 /core 資料夾中,更加提倡了 Don't Hack Core 概念。[#22336]
  • 強化多語言,這將會有一個大改變,最終多少還不知 :)。像集中管理 .PO 檔 ([#1260586]) 這點大家會喜歡。
  • PHP 最低版本需求提升至 5.3,底層將整合 Symfony2,還有一些大型的改動計劃。Classes 使用 PSR-0 方案,Namespace 也將進入 D8 (這些不用 Drupal 的 PHP 開發者也應該留意吧 ?)
  • 一些模組及 Garland 版型,正在或即將離開核心..([#1255674])

Frontend:

  • IE6 已死,IE7 也可能跟隨 ([#1217788]),估計其它舊的瀏覽器版本也會於無形中淘汰
  • Drupal 8 將進入 HTML5 時代,HTML5shiv 已進入核心,核心版型正在轉換至 HTML5
  • Javascript 方面也會有不少改變..
  • CSS 將做一次大清除 ([#1089868]),有人建議增加 CSS 的 Sass 版本
  • 關於 Responsive Layouts 相關的東西也會陸陸續續登入 D8..

還有很多未列出… 將對於大多 Drupal 使用者,最關心也是版型、版型、版型,關於如何改善,可以提供個人意見

個人最想要的內置 WYSIWYG、Media 管理工具,沒有什麼進展..這有一點失望。

歡迎轉載 🙂

** 這個 BLOG 瀏覽量很低,可能關心於 Drupal 的中文使用者不多,或我寫的內容實在太不吸引 (自我安慰…也可能是內容傾向於開發、大方向,而不是一步步的簡單教學…就 DrupalTaiwan 而言,我覺得上面的問題不能說上跟 Drupal 有關,大多是 HTML / CSS / PHP / LAMP 技術問題)。本來此 BLOG 也想分享 WordPress 的,但後來決定專一點…甚麼也好,未來一年會傾於 HTML5 / CSS3 / Mobile Site 開發,可能會更少分享 Drupal 的事了 **

Drupal: 殺掉討厭的權重下拉表單

如果你像我一樣很討厭這種長長的權重下拉表單 (Weight Options),Drupal 7.11 及以後的版本能很簡單殺死它。

只要將 Drupal 中的 Variable: drupal_weight_select_max 改變就可以。(@see form_process_weight)

比如在 settings.php 中加入:$conf['drupal_weight_select_max'] = 0

或 Drush:drush vset drupal_weight_select_max 0

 

相反,如果你真的超喜歡下拉,要跟你的伺服器及瀏覽器效能作對,可以改為:$conf['drupal_weight_select_max'] = 99999999

 

Drupal Devel 模組: 你可能不知的事…

大家經常使用 dpm() 嗎?

你知不知雙擊相關的列會顯示出 PHP Array / Object ..

dd() 你用過嗎 ?

dd($node) 可以將 $node Object 寫到系統暫存資料夾 (admin/config/media/file-system) 的 drupal_debug.txt 檔案中。不要再那麼傻,自己寫 file_put_contents… 哦…
相信 Linux 下的 tail -f /tmp/drupal_debug.txt 你也會用了 🙂

ddebug_backtrace() 又如何 ?

PHP 中的 debug_backtrace 用慣了,不如試試 Drupal 下的 ddebug_backtrace(),如:


ddebug_backtrace(user_load(1));

在 Devel 的設定中,還可以更改預設的錯誤處方式哦:
[admin/config/development/devel]

看不懂 Drupal 的 DBTNG Query object ??

像這堆東西:


$query = db_select('users', 'u');
$query
  ->condition('u.uid', 0, '<>')
  ->fields('u', array('uid', 'name', 'status'))
  ->range(0, 50);

試試 dpq($query);

是不是明白多了 🙂

不用 Devel,你也可以這樣:


echo (string) $query;

是還有一些的….

待你自己發現及跟我分享啦,或者試試 Devel Demo 吧!

Drupal Views Render 有點慢

Views 很方便,但似乎有點慢。測試使用 Views 及直接 SQL 的效能差別:

  1000 rows
(Time per request [ms] (mean))
20 rows
(Time per request [ms] (mean))
SQL QUERY (CACHED) 57.276 55.332
SQL QUERY (No Caches) 84.978 59.483
Views (CACHED) 114.723 94.136

** Views (No Caches) 可以略過,因為相差極遠
** 估計消耗是在 Views 存取 CACHES 中 / Ctools。

 

測試程式碼:

SQL QUERY ( CACHED )


if($table_cache = cache_get('table_cache')) {
  echo $table_cache->data;
}
else {
$query = '
SELECT node.title AS node_title, node.type AS node_type, node.status AS node_status, node.created AS node_created
FROM
{node} node
WHERE (( (node.status = '1') ))
ORDER BY node_created DESC
LIMIT 1000 OFFSET 0';

$res = db_query($query);
$val = '';

$val['header'] = array('Title', 'Type', 'Published');

foreach ($res as $value) {
  if($value->node_status == 1) {
    $value->node_status = 'Yes';
  }
  else {
    $value->node_status = 'No';
  }
  unset($value->node_created);

  $val['rows'][] = (array) $value;
 }
 $table = theme('table', $val);
 echo $table;
 cache_set('table_cache', $table);
}

VIEWS ( CACHED )


echo views_embed_view('test');

** 測試預載 CACHES 後,再進行 **

Drupal Fields: field_attach_update() 更新欄位資料

之前透過 node_save() 的方式來儲存新的 NODE 內容,在 Drupal 7 中同樣可以使用,不過如果要更新,方法稍有不同:


$node2 = node_load($nid); // 如果更新 TITLE,需要提供 Node 的 vid
$node2->title = 'new title';
$node2= node_submit($node2);
node_save($node2);

如果不是更新標題,可以用以下方法,但會有很多 PHP NOTICE 錯誤:


$node3 = new stdClass();
$node3->nid = $nid;
$node3->type = "article";
$node3->body[LANGUAGE_NONE][0]['value'] = 'new value';
node_object_prepare($node3); 
$node3 = node_submit($node3);
node_save($node3);

這個排除了 PHP 錯誤提示:


$node4 = node_load($nid);
$node4->body[LANGUAGE_NONE][0]['value'] = 'new value';
node_object_prepare($node4); 
$node4 = node_submit($node4); 
node_save($node4);

不過在 Drupal 7 中,幾乎都是欄位 (Fields),我們可以考慮使用 Field Attach API:


$node5 = new stdClass();
$node5->nid = $nid;          
$node5->type = 'article';
// $node5->status = 1;
$node5->body[LANGUAGE_NONE][0]['value'] = 'new value';
field_attach_presave('node', $node5);
field_attach_update('node', $node5);

兩者分別:

  • node_save() 除了你要更新的欄位外,還有一堆其他更新,例如:NODE 的時間
  • 效能、效能:以執行 1000 次算,Field Attach API 約快兩倍以上

Drupal 上線前,可做的一些設定..

關閉不用的模組

不知你關不關,反正我關了:

  • Color
  • Dashboard
  • (可以考慮以 Syslog 替代)
  • Help
  • Overlay
  • RDF

取消錯誤顯示

[admin/config/development/logging]
大多錯誤信息對最終的使用者何無意義。
https://notabluescreen.com/undefined-index-error

效能選項

盡量透過系統執行 CRON

雖然 D7 內置了 CRON,但不鼓勵使用。原因有二:

  • 內置 CRON 並可靠,只在有人瀏覽網站才會觸發
  • 不幸遇上 CRON 觸發點的使用者,等到天光才看到網頁內容

完全啟用 drupal_fast_404()

https://notabluescreen.com/fast_404_errors

drupal_goto() 遇上失靈時…

drupal_goto() 是 Drupal 的重新導向 Function。有點頑皮,偶然不知何故,愛跟你鬧脾氣,你要它去東,它往西走。要收復這傢伙,可以試試:


// 進行 DEBUG,你會發覺 $_GET['destination'] 被設定了其他路徑,引致失常,
// 所以,方便之一是在使用 drupal_goto() 前殺掉 $_GET['destination']

unset($_GET['destination']);
drupal_goto($path);

另一方法直接得多,就是……PHP 原本的 HEADER Function:


header('Location: ' . $url, TRUE, $http_response_code);
drupal_exit($url); // 或 exit();

Drupal 管理利器: VBO Admin Views

有沒有覺得 Drupal 的管理後台很遜? 沒有搜尋、Taxonomy等等的過濾功能,對著一大堆內容時,不易於管理。今天介紹這模組可能幫到你:Admin Menu 中的 Admin View

這模組其實只是一個預設的 Views,並使用了 VBO 模組功能。你可通過 Views UI 進行更多設定,加一些你想要的 Exposed Filiter,是很彈性的。下載必需的模組及安裝後便可使用。不過你可能發現某些執行的指令好像沒效?這是因為在預設情況下,執行指令會存到佇列 (QUEUE) 中,在執行 CRON 時才真正觸發。要取消只要到 Views 設定便可:

也因為這只是一個 Views + VBO 模組,你可以設定你想要的效果後,將這個 Views 匯出,用在其他 Drupal 網站上,無必要每次設定或安裝上 Admin Menu 🙂

Drupal Error 404 效能問題

D7.9 以前,Drupal 對所有頁面處理是完整地執行整個程序一次,包括 404 錯誤。現在增加了 Fast 404 Error 處理,在程序較早的時期就中段執行下去。

 

預設值下,一些常見的圖片檔案或靜態資源會經 Fast 404 處理,你可以透過 settings.php 中的 $conf 設置:


$conf['404_fast_paths_exclude'] // 排除 Fast 404 處理的路徑

$conf['404_fast_paths'] // Fast 404 處理的路徑

$conf['404_fast_html'] // Fast 404 顯示的錯誤頁面內容

值得留意的是,預設的情況下,Fast 404 還是會進行錯誤記錄 (Logging),如果這對你沒有用途的話,可以移除 settings.php 中 drupal_fast_404() 前的註釋,這會略過其他程序,在 settings.php 執行後立刻終止。或者更佳的情況是使用 .htaccess,怎麼寫?這個要靠自己啦。

** 在 Drupal 7.9 以前,必須手動啟用。
** 相關 ISSUE: http://drupal.org/node/76824