Concrete5にVueCLIを使ってUIを構築する。1【環境構築編】
技術スタック concrete5JavascriptVue.js

Concrete5にVueCLIを使ってUIを構築する。1【環境構築編】

2020.08.25

こんにちはjunです。今回はconcrete5というCMSでVueを使ったパッケージのUIを作成していこうと思います。今回の記事ではコンポーネントを作成する前の、concrete5にvueプロジェクトを作成してCMSに結びつける環境構築まで行います。

またConcrete5とそのカスタマイズ方法についてある程度熟知している人向け、基準としてはカスタムパッケージを作成したことがある人向けの記事となります。対象とするConcrete5のバージョンは8.4以降となります。

なぜVue?

なぜVueを使うのか。それはPHPとjqueryによるUI構築が非常に面倒になったからです。Concrete5にはフォーム(テキストエリアとかCMSからのファイル選択フォーム)をPHPで出力してくれる以下の様なヘルパーが存在します。

// ヘルパーを読み込む
$form = Core::make('helper/form');

//テキストinput
echo $form->text($name, $default_value);

//テキストエリア
echo $form-> textarea($name, $default_value);

// ファイルマネージャーヘルパー
$file_selector = Core::make('helper/concrete/file_manager');
echo $file_selector->file('label', 'name_attr', 'Select Photo', $default_fileObj);

上記のコードをページ上で実行すれば以下の様にフォームが現れます。

上から順番にテキストインプット、テキストエリア、そしてconcrete5純正のファイルマネージャーが出現します。name属性が与えられ、postを通じてデータを送ることができます。

簡単なブロックやパッケージUIであれば問題ないのですが、

  • フロント側のバリデーションを実装する
  • 決まったフォームを複数生成する
  • フォーム同士が入力値で依存させる場合(入力値でフォームのパターンが変わる)

上記の際にPHPとjqueryだけでは非常に苦労して工数もかかります。

Vueを使えばリッチなUIが作成可能

今流行りのリッチなUI、フォームはほとんどがVue、React、Backbone,jsなどHTMLテンプレート、jsによる状態管理を行うことで簡単に実装できます。工数を抑えつつも、これらのライブラリを用いることでリッチなUIを作成することもできます。

今回の記事ではVue CLIを用いて作成したUIをconcrete5のパッケージ上で表示させ、入力内容の追加・更新・削除まで行える様に実装していきます。原理がわかれば意外と簡単です。

パッケージの制作準備

パッケージの専用のディレクトリを作成

それではVueで構築したUIを持つパッケージを作成していきましょう。pckageディレクトリ配下にvuetestというカスタムパッケージディレクトリを作ります。またディレクトリ構成は以下の通りにします。

documentroot $ cd ./package
package $ mkdir vuetest && touch ...
package $ tree vuetest
./
└── vuetest
    ├── controller.php
    ├── controllers
    │   └── single_page
    │       └── dashboard
    │           └── vuetest.php
    ├── db.xml
    ├── icon.png
    ├── js
    │
    └── single_pages
        └── dashboard
            └── vuetest
                └── view.php

vueプロジェクトを作成

パッケージに必要なコントローラーやUIを表示するダッシュボード上のシングルページとそのコントローラーも用意します。そしてjsディレクトリを作成してその中にvue cliを用いてプロジェクトを作成します。

package $ cd vuetest/js
js $ vue create packageui

Vue CLI v4.4.6
? Please pick a preset: default (babel, eslint) #default

Vue CLI v4.4.6
✨  Creating project in documentroot/vuetest/js/packageui.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while... 

🎉  Successfully created project packageui.

js $ cd packageui && tree -L 1
.
├── README.md
├── babel.config.js
├── node_modules
├── package-lock.json
├── package.json
├── public

無事にvueのプロジェクトが作成されました。concrete5との都合によりvue.config.jsファイルを作成してwebpackの設定をいじります。

packageui $ touch vue.config.js
module.exports = {
    configureWebpack: {
      output: {
        filename: '[name].js',
        chunkFilename: '[name].js'
      }
    },
  }

これは npm run build,npm run build --mode development.vueファイルを.jsファイルにコンパイルして/dist配下に配置される時に名前がいつも同じになる様に設定します。

buildをするとビルドされたファイルの名前にはハッシュされた英数字がつくのですが、これがビルドの度にころころ変わります。Concrete5でjsファイルをロードする場合は設定した名前が一致しないと読み込めませんので、ビルドの際に設定を変えなくて済む様に上記の設定をします。

もし複数のパッケージで共通のvueファイルを用いる場合

今回は vuetestというパッケージとそのディレクトリ配下に専用のvueプロジェクトを作成しますす。しかし複数のパッケージでvueファイルを使用したい場合、applicationディレクトリにjsディレクトリを作成し、vueプロジェクトを作成してください。

コンパイルしたjsファイルをconcrete5と結びつける

vue cliでビルドするとdist配下にコンパイルされたjsファイルが生成されます。そのファイルとレンダー先のconcrete5上のページ(シングルページ)で読み込める様に、このjsファイルをCMSが読み込める様に設定します。

まずとりあえず以下のmain.jsをビルドしてみます。レンダリング先に id="app" という要素があればAppコンポーネントがレンダーされます。

src/main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')
packageui $ npm run build
.
├── README.md
├── babel.config.js
├── dist
│   ├── app.js
│   ├── app.js.map
│   ├── chunk-vendors.js
│   ├── chunk-vendors.js.map
│   ├── css
│   ├── favicon.ico
│   ├── img
│   └── index.html
├

ビルド成功。いらないものもありますが、app.jschunk-vendors.jsが読み込まれる様にすればOKです。

パッケージ専用のjsファイルで作成する場合はパッケージのインストールコントローラ(package/vuetest/controller.php)に以下の様な記述をします。

controller.php
<?php
namespace Concrete\Package\Vuetest;
defined('C5_EXECUTE') or die('Access Denied.');
use \Concrete\Core\Asset\AssetList;
use \Concrete\Core\Asset\Asset;

class Controller extends \Concrete\Core\Package\Package {
    protected $pkgHandle = 'vuetest';
    protected $appVersionRequired = '5.7.4';
    protected $pkgVersion = '1.0.0';

    public function on_start()
    {
        $al = AssetList::getInstance();
        $al->register(
            'javascript', 'package-vue-build', 'js/packageui/dist/app.js',
            array('version' => '1.0.0', 'position' => Asset::ASSET_POSITION_FOOTER, 'combine' => true),
            $this->pkgHandle
        );
        
        $al->register(
            'javascript', 'package-vue-chunk', 'js/packageui/dist/chunk-vendors.js',
            array('version' => '1.0.0', 'position' => Asset::ASSET_POSITION_FOOTER, 'combine' => true),
            $this->pkgHandle
        );
        
        $al->registerGroup('package-vue-production', array(
            array('javascript', 'package-vue-build'),
            array('javascript', 'package-vue-chunk'),
        )); 
    }
...
}

vuetestパッケージのコントローラーで$al->registerを用いて、パスで指定したjsファイルを登録します。2つあるのでを$al->registerGroup用いてのpackage-vue-production名前で2つのjsファイルを読み込む様にグルーピングします。

concrete5ではこの様なjs/cssのアセット登録システムがあり、登録をすれば適当にアセットが読み込むことができる様になります。パッケージのコントローラーでは登録をした ので、次はjsファイルが必要なページのコントローラーで呼び出し を行います。

vuetest/single_pages/dashboard/vuetest/view.php に以下の様に記述します。

<?php
namespace Concrete\Package\Vuetest\Controller\SinglePage\Dashboard;
defined('C5_EXECUTE') or die('Access Denied.');
use \Concrete\Core\Page\Controller\DashboardPageController;

class Vuetest extends DashboardPageController
{
    public $packageHandle = 'vuetest';

    public function view() {
        $this->requireAsset('package-vue-production');
        $this->set('success', 'My success message');
    }
}

この$this->requireAsset('package-vue-production');で「先ほど登録したjsアセットをこのページで読み込め!」と命令しています。設定した後、実際に該当ページで探してみましょう。

いました。/packages/vuetest/js/dist/** と指定したパスにて読み込まれています。それではid="app"を持つ適当なdivを作成して再度みてみましょう。

vuetest/single_pages/dashboard/vuetest/view.php にて

view.php
<?php
defined('C5_EXECUTE') or die('Access Denied.');
?>

<div id="app"></div>

パスの関係上レイアウトが崩れ、画像が読み込めていませんがvue側で記述した内容が無事にレンダリングされています。これでvueとconcrete5のセッティングは完了です。vueプロジェクトでコンポーネントを作成しながら、適切なidを用いてページ上にレンダーします。

次はフォームコンポーネントの作成

以上がconcrete5のパッケージ上にvueプロジェクトを作成して、concrete5に結びつける方法でした。これでvueを使え、レンダーされる環境は整ったので次は情報を登録するための登録フォームと編集画面の作成を行っていきます。

コメント

コメント読み込み中..

Copyright © 2021 jun. All rights reserved.