Liferay 7.2 向けのテーマを作成して、クラシックテーマのスタイルをあてる方法

リポジトリをクローンしてすぐに試せます：https://github.com/tsubasahomma/demo-workspace-2020-001

# 0. 開発環境の前提
**OS**
macOS Catalina 10.15.2

**Java**

```bash
$ java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)
```

**Node.js**

```bash
$ node -v
v10.17.0
```

**npm**

```bash
$ npm -v
6.13.7
```

**[Blade](https://portal.liferay.dev/docs/7-2/reference/-/knowledge_base/r/installing-blade-cli)**

```bash
$ blade version                                                                                                                                                                                                                  7.2
blade version 3.9.0.202001232132
```

# 1. Liferay Workspace をセットアップする
次のコマンドでLiferay 7.2用のLiferayワークスペースを作成して、その中へ移動します：

```bash
$ blade init -v 7.2 my-project && cd $_
```

ワークスペースの中身は次のようになります：

```bash
$ tree　-Fa
.
├── .blade.properties
├── .gitignore
├── build.gradle
├── configs/
│   ├── common/
│   │   └── .touch
│   ├── dev/
│   │   └── portal-ext.properties
│   ├── docker/
│   │   └── .touch
│   ├── local/
│   │   └── portal-ext.properties
│   ├── prod/
│   │   ├── osgi/
│   │   │   └── configs/
│   │   │       └── com.liferay.portal.search.elasticsearch.configuration.ElasticsearchConfiguration.config
│   │   └── portal-ext.properties
│   └── uat/
│       ├── osgi/
│       │   └── configs/
│       │       └── com.liferay.portal.search.elasticsearch.configuration.ElasticsearchConfiguration.config
│       └── portal-ext.properties
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle-local.properties
├── gradle.properties
├── gradlew*
├── gradlew.bat
├── modules/
├── settings.gradle
├── themes/
└── wars/

16 directories, 18 files
```

ワークスペースの*local*環境用の portal-ext.properties では、あらかじめ開発者モードが有効になっています：

```properties:configs/local/portal-ext.properties
include-and-override=portal-developer.properties

#
# MySQL
#
#jdbc.default.driverClassName=com.mysql.cj.jdbc.Driver
#jdbc.default.url=jdbc:mysql://localhost/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
#jdbc.default.username=root
#jdbc.default.password=
```

Freemarkerのリソース変更チェックを無効化するための、OSGi設定ファイルの配置先フォルダを作成します：

```bash:配置先フォルダの作成
$ mkdir -p configs/local/osgi/configs
```

作成したフォルダ内に次の内容の設定ファイルを配置します：

```config:configs/local/osgi/configs/com.liferay.portal.template.freemarker.configuration.FreeMarkerEngineConfiguration.config
allowedClasses=[ \
  "", \
  ]
localizedLookup="false"
macroLibrary=[ \
  "FTL_liferay.ftl\ as\ liferay", \
  ]
resourceModificationCheck="0"
restrictedClasses=[ \
  "com.liferay.portal.json.jabsorb.serializer.LiferayJSONDeserializationWhitelist", \
  "java.lang.Class", \
  "java.lang.ClassLoader", \
  "java.lang.Compiler", \
  "java.lang.Package", \
  "java.lang.Process", \
  "java.lang.Runtime", \
  "java.lang.RuntimePermission", \
  "java.lang.SecurityManager", \
  "java.lang.System", \
  "java.lang.Thread", \
  "java.lang.ThreadGroup", \
  "java.lang.ThreadLocal", \
  ]
restrictedMethods=[ \
  "com.liferay.portal.model.impl.CompanyImpl#getKey", \
  ]
restrictedVariables=[ \
  "httpUtilUnsafe", \
  "objectUtil", \
  "serviceLocator", \
  "staticFieldGetter", \
  "staticUtil", \
  "utilLocator", \
  ]
templateExceptionHandler="rethrow"
```

# 2. バンドルを起動する
使用するLiferayのバンドルと、バンドルを展開するディレクトリは、次の場所で設定されています：

```properties:gradle.properties（デフォルトの一部抜粋）
    #
    # Set the URL pointing to the bundle Zip to download. If the URL points to a
    # DXP bundle (e.g., https://api.liferay.com/...), set the
    # "liferay.workspace.bundle.token.download" property to true. The default
    # value is the URL for Liferay Portal CE 7.0 GA7, Liferay Portal CE 7.1 GA4,
    # or Liferay Portal CE 7.2 GA1, depending on the portal version the
    # workspace is targeting.
    #
    liferay.workspace.bundle.url=https://releases-cdn.liferay.com/portal/7.2.1-ga2/liferay-ce-portal-tomcat-7.2.1-ga2-20191111141448326.tar.gz

    #
    # Set the folder that contains the Liferay bundle downloaded from the
    # "liferay.workspace.bundle.url" property. The default value is "bundles".
    #
    #liferay.workspace.home.dir=bundles
```

上記で指定されているバンドルを初期化します（完了まで数分かかる場合があります）：

```bash
$ blade server init
Executing gradle task initBundle...


server init completed successfully.
```

*${liferay_workspace}/configs/local/*内のファイルが適用されたバンドルが、*bundles/*へ展開されていることを確認します：

```bash
$ ls bundles
data
deploy
license
logs
osgi
portal-ext.properties
readme.html
tomcat-9.0.17
tools
```

バンドルを起動します：

```bash
$ blade server start                                                                                                                                                                                                                           master
To view the log execute 'tail -f /path/to/my-project/bundles/tomcat-9.0.17/logs/catalina.out'
Tomcat started.
```
ログファイルのパスは適宜読み替えてください。

# 3. テーマ作成する
[テーマジェネレータ]を利用してテーマを作成します。
*${liferay_workspace}/themes/*内で、次のコマンドを実行します：

```bash
$ yo liferay-theme
```

プロンプトに従い入力します。途中、ターゲットとするtomcatのパスとアクセスURLを尋ねられるので、次のように入力します：

```bash
? Select your deployment strategy Local App Server
? Enter the path to your app server directory: /path/to/my-project/bundles/tomcat-9.0.17
? Enter the url to your production or development site: http://localhost:8080
```

以上で[Styledテーマ][]を継承したテーマが作成されました。

---

## 3.1 テーマの継承について
[テーマジェネレータ]で作成されたテーマには、テンプレートファイルなどが存在しないことに気づいたかもしれません。これはテーマの継承によるものです。

Liferayには次の2つのベーステーマが存在します：

1. **[Unstyled]**: 基本的なマークアップ、関数及び画像を提供する。
2. **[Styled]**: [Unstyled]を継承し、追加のスタイルを提供する（基本的にはこちらを使用する）。

# 4. テーマに [Clay][] を読み込む
LiferayのUI/UXガイドライン「[Lexicon][]」のWeb実装である「[Clay][]」のCSSを、テーマで利用可能にするために、次の`.scss`ファイルをそれぞれ配置します。

```scss:src/css/clay.scss
@import "clay/atlas";
```

```scss:src/css/_imports.scss
@import "bourbon";

@import "mixins";

@import "compat/mixins";

@import "clay/atlas-variables";
```

```scss:src/css/_clay_variables.scss
/*
中身は空で大丈夫です。
Atlas、Bootstrap及びClay Baseの変数を変更したい場合に、このファイルに追記します。
*/
```

作成したテーマにClay CSSを読み込んで、カスタマイズできるようになりました。

# 5. 再利用可能にする
[テーマジェネレータ]には、任意に作り込んだテーマ簡単に再利用するための[kickstart]というコマンドがあります。初期状態では利用できるテーマが無いため、ここまでのステップで作成したテーマを`gulp kickstart`で再利用できるようにしてみます。

作成したテーマフォルダへ移動して、次のコマンドを実行します。

```bash
$ npm link # npmのグローバルにテーマをリンクする
$ 
```

テーマを再利用するには、次のコマンドを実行します：

```bash
$ yo liferay-theme # 任意の名前のテーマを作成
$ cd <作成したテーマ>
$ gulp kickstart
[14:50:14] Using gulpfile ＜作成したテーマ＞/gulpfile.js
[14:50:14] Starting 'kickstart'...
[14:50:14] Warning: the kickstart task will potentially overwrite files in your src directory
? Where would you like to search? Search globally installed npm modules
Warning: found 1 packages (matching criteria) with no liferayTheme section in package.json
? Select a theme my-liferay-theme
[14:50:33] Finished 'kickstart' after 18 s
```

これで、Clay CSSを読み込んだ状態からテーマづくりをスタートできます。

注意点は、[kickstart]は初回限りの継承となり、**ある程度作り込まれたテーマ上で実行すると既存ファイルが上書かれます**。したがって、テーマづくりのはじめの段階で実行します。

ヘッダー、ナビゲーションおよびフッターなど、共通箇所をある程度作り込んだテーマで、`npm link`しておけば、すばやく新規テーマ開発をスタートできます。

[init.ftl]:https://github.com/liferay/liferay-portal/blob/7.2.x/modules/apps/frontend-theme/frontend-theme-unstyled/src/main/resources/META-INF/resources/_unstyled/templates/init.ftl
[portal_normal.ftl]:https://github.com/liferay/liferay-portal/blob/7.2.x/modules/apps/frontend-theme/frontend-theme-unstyled/src/main/resources/META-INF/resources/_unstyled/templates/portal_normal.ftl
[navigation.ftl]:https://github.com/liferay/liferay-portal/blob/7.2.x/modules/apps/frontend-theme/frontend-theme-unstyled/src/main/resources/META-INF/resources/_unstyled/templates/navigation.ftl
[init_custom.ftl]:https://github.com/liferay/liferay-portal/blob/7.2.x/modules/apps/frontend-theme/frontend-theme-unstyled/src/main/resources/META-INF/resources/_unstyled/templates/init_custom.ftl
[Lexicon]:https://liferay.design/lexicon/
[Clay]:https://clayui.com/
[Unstyled]:https://github.com/liferay/liferay-portal/tree/7.2.x/modules/apps/frontend-theme/frontend-theme-unstyled
[Styled]:https://github.com/liferay/liferay-portal/tree/7.2.x/modules/apps/frontend-theme/frontend-theme-styled
[テーマジェネレータ]:https://portal.liferay.dev/docs/7-2/reference/-/knowledge_base/r/installing-the-theme-generator-and-creating-a-theme
[kickstart]:https://portal.liferay.dev/docs/7-2/frameworks/-/knowledge_base/f/copying-an-existing-themes-files