按照年月把上傳的檔案放置在不同目錄


有一件事, 從架站開始就應該要規畫好; 但是沒經驗的站長怎麼會想得到呢? Drupal 上傳的檔案都放在 [drupal 根目錄]/sites/default/files 底下 -- 包含圖檔跟附加檔。 當你的網站運作一陣子之後, 這底下會出現幾百個、 幾千個檔案, 中英文檔名亂成一團, 不僅難以管理, 而且效能會越來越差。

貴哥學到這個慘痛教訓之後, 搜尋到 File (Field) Paths 模組 (以下簡稱 FFP 模組) 來解決這個問題。 請在瀏覽器裡開啟兩個分頁, 另外也開一個命令列視窗。 以下的操作步驟會在這三個地方切來切去, 分別用 [內容] 表示管理內容的分頁、 用 [FFP] 表示管理 「article 圖片欄」 的分頁、 用 [命令] 表示命令列視窗。

本實驗其中一步有高度風險! 請先用 drush ard ... 指令備份整個網站, 找一部不用的機器 (或虛擬機) 還原網站離線測試。 (請參考 Drupal 搬家/升級/還原筆記。) 如果你在運作中的主機測試, 請不要做 <危險!> 那一步, 並且請用新的文章測試, 測試完後可以把新文章刪掉。

  1. [命令] 下載: drush dl filefield_paths
  2. [命令] 啟用: drush en filefield_paths
  3. [內容] 先 「新增內容」, 張貼一篇文章 (article), 並上載一張帥氣的圖片。 圖片故意取中文檔名找蹅。
  4. [命令] 檢查一下最近 20 分鐘內上傳了哪些檔案, 應該會看到剛剛上傳的圖檔: cd [drupal 根目錄]/sites/default/files ; find . -type f -mmin -20
  5. [FFP] 在 「架構」 => 「內容類型」 => 「article」 => 「管理欄位」 頁面點選 「編輯」, 準備更改上傳圖片的目的地。
  6. [FFP] 點一下 「File (Field) Path settings」, 展開底下的選項。
  7. [FFP] 看到 「檔案名稱」 那一欄, 原本已有預設值 [file:ffp-name-only-original].[file:ffp-extension-original] 這表示 Drupal 會把檔案按照原檔名放到預設的目錄。
  8. File (Field) Path 設定 [FFP] 請改以這串值貼上去: [node:created:custom:Y/m]/[file:ffp-name-only-original].[file:ffp-extension-original] 然後按 「儲存設定」。
  9. [內容] 再張貼一篇 article、 再上載另一張帥氣的圖片, 但先不要按「儲存」。
  10. [命令] 再度 find . -type f -mmin -20 咦, 為什麼 Drupal 依舊把新上傳的圖檔放在相同的目錄底下? FFP 沒有任何效果啊 !? 我在這裡卡了好久。
  11. [內容] 按下 「儲存」。
  12. [命令] 按上箭頭再 find 一次, 發現 Drupal 已經把新上載的圖檔搬到 [drupal 根目錄]/sites/default/files/2015/02 子目錄底下。 (真正的路徑會是你照著本文做實驗的年月。) 這個實驗的重點就是: 根據 這篇問答, 上載成功還不算數。 要等到這個 node (頁面) 儲存完畢, FFP 才知道 node (頁面) 本身的許多相關資訊 (例如頁面建立時間等等), 也才能根據這些資訊把上載的檔案搬到正確的位置。 當然, 目前我們還沒把頁面本身的相關資訊放進 「檔案名稱」 當中; 等一下就會用到。
  13. [FFP] 再次修改 FFP 的 「檔案名稱」 那一欄, 這次改成: [node:created:custom:Y/m]/[node:nid]-[file:fid].[file:ffp-extension-original] <危險!> 並且勾選 「Retroactive update」, 然後按下 「儲存設定」。 系統會回頭把 過去上傳的所有新舊圖檔全部翻出來, 一個一個搬到指定的位置、 更改檔名

以上這些特殊符號稱為 token, 具有變數的效果, 其意義分別是:

  1. [node:created:custom:Y/m] node (頁面) 創建的年月。 年月日時分秒可以有 各種格式
  2. [file:ffp-name-only-original] 上載圖檔的檔名 (不含副檔名) 例如 cloud-city.jpg 的 「cloud-city」 部分。
  3. [file:ffp-extension-original] 上載圖檔的副檔名 例如 cloud-city.jpg 的 「jpg」 部分。
  4. [file:fid] 每個上載檔案自己獨有的編號。
  5. [node:nid] node (頁面) 代號; 也就是頁面網址 (例如 http://.../node/243) 後半段那串數字。

我個人覺得最有用的, 就是 node 創建年月。 上載檔案較少的網站, 可以把檔案按照年份放在不同目錄; 上載檔案較多的網站, 則可以把檔案按照年份及月份放在不同目錄。 重點就是把每個目錄底下的檔案數量控制在一兩百個檔案以下, 以避免增加檔案系統的負擔。

把 node 代號插入檔名, 有助於將來回頭查詢: 「這個檔案屬於哪一個頁面的插圖或附件?」 當然, 它所帶的資訊, 跟 node 創建年月有一點重複。

如果說 [file:ffp-extension-original] 與 [file:ffp-name-only-original] 是檔案的姓與名, 那麼 [file:fid] 就是檔案的身份證字號。 兩者都具有 「指認檔案」 的效果, 而且後者比前者更確定具有唯一性 (但比較不利於使用者閱讀)。 兩者至少應有一個出現。 (除非你採用亂數 token 來區別檔案) 至於如果想把中文檔名換掉, 據說可以用 transliteration 模組; 不過我沒試過。

在 Replacement Patterns 底下可以找到更多的 tokens, 例如現在時間、 創建者 id 等等, 都可變成檔名或路徑的一部分。

active updating 選項也會回頭把過去上傳的舊檔案翻出來, 搬到指定的位置、 更改檔名。 但它並不是立馬修改, 而是每次遇到用戶編輯舊的 node 時才會順手搬動/更名。

不只是 article 的附圖, 其他任何內容類型的任何附加檔也都應該比照處理, 以免上載檔案通通擠在同一個目錄下。 admin 管理員大大沒事就應該用 find 指令查一下最近一兩個月上載的檔案是不是都各得其所。 如果看到未被按照年份或年月放置的檔案, 就應該找到對應的內容類型, 編修它的附加檔案/插圖欄位。 至於 webform 上傳的檔案, 則又是另一回事了。 FFP 管不到它; 目前沒辦法像這樣自動設定, 只能每一頁都手動設定儲存目錄。

經過這樣的處理, 希望你架的網站可以長命百歲, 附加檔滿堂!( Live long and prosper!)

延申閱讀: Organizing uploaded files in folders created by date