2022年5月4日 星期三

CKAN 前端開發(v2.9): 概覽

http://docs.ckan.org/en/2.9/contributing/frontend/index.html 

前端的 stylesheet 採用 Less (系統需安裝 node.js ) 撰寫。

檔案結構

所有前端用到的檔案都放在 public 目錄下(ckan/lib/default/src/ckan/ckan/public/base)如下,檔名及目錄名稱都需小寫或用減號分隔

css/             --- Less 編譯後的 production  版 CSS 檔
  main.css
less/            --- less 檔。vendor 的樣式檔放在 vendor 目錄,在 main.less 裡 include。
  main.less
  ckan.less
  ...
javascript/     --- 建議使用 main.js 做為起始檔
  main.js
  utils.js
  components/
  ... 
vendor/
--- 存放外部相依檔,版本數字不能出現在檔名,應放在檔頭註解。 
--- 函式庫需以函式庫名稱開頭。 
--- 若相依檔有多個(如bootstrap檔)則整個目錄應用 distributed 方式處理。  
  jquery.js
  jquery.plugin.js
  underscore.js
  bootstrap.css
  ...

Stylesheets

所有樣式檔都以 Less 方式處理,開發前需先編譯:

$ npm run watch

以上指令會偵測所有 less 檔的修改並自動重建。(ctrl-c結束)。以下指令啟用偵錯模式,可看到sourcemaps:

$ DEBUG=1 npm run watch

樣式檔很多,主要有以下兩群:

  • main.less
    網站所有 dependancies、local 樣式,只排除某些情況下才載入的樣式,像是IE才用的 CSS  和只在某個網頁才顯示的外部 apps (如 recline)。
  • ckan.less
    所有 ckan 本身使用的樣式。

    JavaScript

    三部分:

    • Core (such as i18n, pub/sub and API clients)
      • Modules
      • Publisher/Subscriber
      • Client
      • i18n/Jed

    • Modules (small HTML components or widgets)
    • jQuery Plugins (very small reusable components)

    Module

    網頁上所有可互動的元件都應該是一個 module。在 HTML 元素裡加入 data-module 屬性/attribute  進行初始化:

    <select name="format" data-module="autocomplete"></select>

    這種作法的好處是讓它是一個小的可測試元件。所有全域物件應該透過 sandbox 傳入。

    用 global factory 建立新 modules,jQuery 及 Localisation 則透過 this.sandbox.jQuery 及 this.sandbox.translate()。

    ckan.module('my-module', function (jQuery) {
      return {
        initialize: function () {
          // Called when a module is created.
          // jQuery and translate are available here.
        },
        teardown: function () {
          // Called before a module is removed from the page.
        }
      }
    });

    Publisher/subscriber

    在 ckan.pubsub 下有一個簡單的 pub/sub module,透過 this.sandbox.publish/subscribe/unsubscribe,可在 module 間發佈/publish 訊息。

    module 間應透過 publish/subscribe 的方式溝通,讓 UI 上相關區域/area 做對應的刷新。

    ckan.module('language-picker', function (jQuery) {
      return {
        initialize: function () {
          var sandbox = this.sandbox;
          this.el.on('change', function () {
            sandbox.publish('change:lang', this.selected);
          });
        }
      }
    });

    ckan.module('language-notifier', function (jQuery) {
      return {
        initialize: function () {
          this.sandbox.subscribe('change:lang', function (lang) {
            alert('language is now ' + lang);
          });
        }
      }
    });

    Client

    module 不該用 jQuery.ajax() 呼叫 CKAN API,應該透過 client object。

    ckan.module('my-module', function (jQuery) {
      return {
        initialize: function () {
          this.sandbox.client.getCompletions(this.options.completionsUrl);
        }
      }
    });

    多國語系/Internationalization

    參考 Internationalizing strings in JavaScript code.

    生命週期/Life cycle

    CKAN module 在 dom ready 後初始化,ckan.module.initialize() 找出網頁中有 data-module  屬性的的 HTML 元素,試著建立對應的物件。

    <select name="format" data-module="autocomplete" data-module-key="id"></select>

    module 會依 HTML 元素中設定的 data-module-* 屬性建立對應的 sandbox 物件,建立後便呼叫 module 的 initialize() 初始化。

    module 應提供 teardown() 回復原始狀態。


        沒有留言:

        張貼留言