これだけ知っておけばとりあえずconcrete5でサイトを作れるまとめ

Web制作者にとって、新しいCMSに手を出すときに気になる要素は、テンプレートの作り方、デザインカスタマイズの自由度だと思います。特にいったんクライアントがデザインにGOサインを出したら、実装の都合で変更しにくい風潮があると感じられる日本では特に…:sweat_smile:

デザインカスタマイズについて、いかに最低限のドキュメントだけ読んで何とかなるかという点では、[concrete5](https://concrete5-japan.org/)はCMSの中でもピカイチだと思います。そこで、個人的に「**これだけ知っていれば普通のサイトは作れるようになる**」と思う知識をまとめてみました。ここでいう普通のサイトとは、concrete5の標準機能でできる範囲のサイトという意味です。

なぜconcrete5は、ドキュメントを読む量が少なくて済むのでしょうか。それは、サイトを作り上げるのに、マウス操作で実現する範囲が他のCMSより多いからだと思います。逆にいうと、テンプレートは少ない知識で楽に作れますが、反対にCMSの操作に慣れる時間は相応に必要になりますで、そこはトレードオフとしてご理解いただければと思います。

concrete5の操作については、[YouTubeの勉強会動画シリーズ](https://www.youtube.com/channel/UCgAuPHI9Kdacn8cAeVpjFZg)もご参照ください。

# コンテンツの概念

必ず頭に入れておきたいのは、concrete5にとってのコンテンツの概念です。

利用者の多いWordPressでは、投稿、固定ページ、アーカイブページ、のようなページごとの分類があり、それぞれにあらかじめ機能が異なります。concrete5では、そのような機能に依存したページの分類はありません。**全てのWebページは、等しくただのページです**。

concrete5では、ページはブロックを配置するための器に過ぎません。WYSIWYGエディタでテキストが編集できる**記事**ブロックを置けば固定ページになりますし、お知らせの一覧を表示するために**ページリスト**ブロックを置けばアーカイブページになりますし、サイト内検索結果を表示するために**検索**ブロックを置けば検索結果ページになります。

置くブロックによってページの性格が変わるというconcrete5の特徴により、サイトマップ設計の自由度が増します。WordPressではサイトマップ設計に合わせてパーマリンクをいじるのが一苦労ですが、そう言った苦労はありません。逆に、適切なブロックを置くまではページは空っぽ。この自由度が逆に、「何をしていいか分からない」という最初のつまづきを招きます。まずは、いろんなブロックを置いていじってみて、ページとブロックの関係性を感覚でつかみましょう。

ブロックを置ける場所はエリアで規定されています。多くのテーマは、全幅、右サイドバー、左サイドバー、のようなレイアウトのバリエーションをページテンプレートとして持っており、ページテンプレートでエリアの配置があらかじめ決まっています。

エリアは、画面上の操作でレイアウトを内包することができ、レイアウトのパターンもデザイナーの自由に定義して増やすことができます。

以上の構成を図示したものが下図になります。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8033/4e9fa6bb-426f-96e0-2c7b-be3bcaa1fc36.png)

図を見ながら、concrete5の[操作動画](https://youtu.be/oOiyRkOeXX8)も見比べてみてください。

# デザインカスタマイズのために、何を作るべきか

concrete5では、テーマとブロックテンプレート、この２つを作る作業がデザインカスタマイズになります。

# オーバーライドの概念

実際にデザインカスタマイズに着手する前に理解しておくべきなのが**オーバーライド**の概念です。と言っても、難しいものではありません。

concrete5をダウンロードすると、**application**フォルダと**concrete**フォルダ、**packages**フォルダに大きく分かれています。

packagesフォルダは、マーケットプレイスから入手したテーマやアドオンが格納される場所ということだけ覚えておいてください。

concrete5のコアファイルはconcreteフォルダに格納されています。**この中身は変更不可です**。なぜなら、concrete5をバージョンアップすると、concreteフォルダの中身が上書きされるので、自分で何か中身を変更していたとしても、それが消えてしまうからです。concrete5をカスタマイズしたければ、applicationフォルダを使います。

applicationフォルダ内は、concreteフォルダとほとんど似たような構成のフォルダが並んでいますが、中身は空っぽです。**concreteフォルダ内のカスタマイズしたいファイルを、applicationフォルダにコピーしてから変更する**。これがオーバーライドの原則です。

例えば、concrete5に同梱されているjQueryのバージョンが古いので、新しくしたいなと思ったとします。ファイルは以下に格納されています。

```
/concrete/js/jquery.js
```

このファイルをapplicationフォルダでオーバーライドできます。新しいバージョンのjQueryファイルを、以下に設置してみてください。

```
/application/js/jquery.js
```

設置するだけで、concrete5はオーバーライドされたjquery.jsを読み込んでくれます。簡単ですね！

実際には、リクエストのたびにオーバーライドの有無を確認しているとサーバー負荷がかかりますので、どのファイルがオーバーライドされているかはキャッシュされています。オーバーライドしたのに反映されないぞ、と思った場合は、管理画面からキャッシュをクリアしてみましょう。

* [コアファイルをオーバーライドする](https://concrete5-japan.org/help/5-7/recipes/override-almost-any-core-file-in-5-7/)

# テーマ

テーマとはすなわち、**ページテンプレートとCSSやJavaScriptなどのアセットの集合体**です。

## テーマのファイル構成

concrete5に同梱されている**Elemental**テーマは、下記のようなファイルで構成されています。

| ファイル名 | 用途 |
| ---- | ---- |
| css | テーマで使用するcssファイルの置き場所です。フォルダ名に特に決まりはありません。 |
| elements | ヘッダーやフッターなど、どのレイアウトでも共通にインクルードするパーツの置き場所です。フォルダ名に特に決まりはありません。 |
| default.php | デフォルトページテンプレートです。テーマの基本となるレイアウトです。ファイル名は default.php である必要があります。 |
| blank.php, full.php, left_sidebar.php, right_sidebar.php | ページテンプレートです。テーマで用意されているレイアウトのバリエーションの数だけ存在します。ファイル名は自由につけて構いません。 |
| page_forbidden.php, page_not_found.php | 403, 404エラー用のテンプレートです。 |
| page_theme.php | テーマの設定ファイルです。レイアウトの定義などを行います。 |
| view.php | シングルページ用のテンプレートファイルです。ログイン画面やマイアカウントページなどを自作テーマで表示したい場合以外は、なくても良いです。 |

ページテンプレートは、管理画面から登録することで、使えるようになります。登録の際のハンドル名とファイル名が対応します。

<img width="867" alt="Screen Shot 2019-08-28 at 8.39.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8033/fbde3019-8469-a6be-8f55-3c0c3f3857c4.png">

登録したページテンプレートは、各ページの**デザイン**メニューで切り替えに使用できます。

<img width="610" alt="Screen Shot 2019-08-28 at 8.42.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8033/f9ac7b74-9ce0-500a-156a-f94afce78d78.png">

## テーマの置き場所

自作テーマはapplicationフォルダ内に設置します。

```
/application/themes/my_great_theme
```

`my_great_theme` 部分は、テーマのハンドル名として扱われます。英小文字とアンダーバーの組み合わせであれば、自由に設定できます。

## page_theme.php の作成

テーマの名前や、レイアウトの定義などは `page_theme.php` に記述します。

```
/application/themes/my_great_theme/page_theme.php
```

中身の基本は下記のようになります。

```php:自作テーマのpage_theme.php作例
<?php
namespace Application\Theme\MyGreatTheme;

use Concrete\Core\Page\Theme\Theme;

class PageTheme extends Theme
{
    /**
     * テーマ名
     * /
    public function getThemeName()
    {
        return '俺のスゲーテーマ';
    }

    /**
     * テーマの説明文
     * /
    public function getThemeDescription()
    {
        return '俺による俺のための俺カッケーなテーマ';
    }
}
```

冒頭の `namespace` で始まる宣言が名前空間です。この `MyGreatTheme` が、テーマのハンドルの `my_great_theme` の各単語の先頭を大文字にして、アンダーバーを詰めたものになります。ここのスペルミスでテーマが認識されないのが地味にハマりポイントなのでご注意を。

あとは色々な設定がこのファイルからできるのですが、ドキュメントを見たり、Elementalのpage_theme.phpからコピペで大体なんとかなります。

* [テーマでグリッドフレームワークをサポートする](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/adding-grid-support-to-your-theme/)
* [コアのJavascriptとCSSをテーマで使用する](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/advanced-css-and-javascript-usage/requiring-core-javascript-or-css-in-a-theme/)
* [コアのJavascriptやCSSをテーマから上書きする](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/advanced-css-and-javascript-usage/overriding-or-providing-core-javascript-or-css-in-a-theme/)
* [ブロック、エリア、エディターにカスタムCSSクラスを追加する](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/advanced-css-and-javascript-usage/adding-custom-css-classes-to-blocks-areas-and-the-editor/)

## ページテンプレートの作成

これもぶっちゃけ Elemental テーマからのコピペでなんとかなりますが、やるべきことが何かはおさらいしておきます。やることはほぼこの３点のみ。

### concrete5のUIを読み込む

concrete5のツールバーや、各種メニューを読み込ませるために入れる必要があるコードです。

```php
<!-- head タグ内にコピペ -->
<?php View::element('header_required'); ?>
```

```php
<!-- body の開始タグ直後にコピペ -->
<div class="<?php echo $c->getPageWrapperClass()?>">
```

```php
<!-- body の閉じタグ直前にコピペ -->
</div>
<?php View::element('footer_required'); ?>
```

### テーマのCSSやJSのパスを通す

ぶっちゃけ /application からパスを書いても動きますが、一応PHPでテーマのパスを出力するのがお作法です。

```php
<link rel="stylesheet" type="text/css"
 href="<?php echo $view->getThemePath()?>/css/style.css">
```

### エリアを定義する

ブロック配置可能にしたい要素の中身に、エリアの定義を記述します。これも非常に簡単でコピペでOKです。

```php:エリアの定義
<nav>
<?php
/**
 * グローバルエリア
 * ヘッダーのロゴやフッターのコピーライドなど、どのページでも共通の領域
 * /
$a = new GlobalArea('Header Navigation');
$a->display();
?>
</nav>

<main>
<?php
/**
 * 通常のエリア
 * ページごとに中身が異なります
 * /
$a = new Area('Main');
$a->display($c);
</main>
```

エリア名は自由につけて構いません。日本語でも動きますが、慣習としてエリア名は英語で記述し、必ず１画面に１つ Main エリアを設置します。

このエリアの中にブロックが配置できるわけですが、さらにレスポンシブグリッドでの分割をサポートしたい場合は、ちょこっとやることがあります。詳しくはヘルプを参照。

* [エリアでグリッドレイアウトを有効にする](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/adding-grid-support-to-your-theme/enabling-grid-support-for-areas-and-layouts/)
* [エリアとブロックのコンテナ](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/adding-grid-support-to-your-theme/area-and-block-containers/)
* [独自のグリッドフレームワークのサポートを追加する](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/adding-grid-support-to-your-theme/advanced-create-and-use-your-own-grid-framework/)
* [高度なエリアの操作](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/advanced-area-operations/)
* [複雑なカスタムレイアウトプリセットをテーマに追加する](https://concrete5-japan.org/help/5-7/developer/designing-for-concrete5/adding-complex-custom-layout-presets-in-your-theme/)

以上の３点でテーマ作成作業は終了なのですが、他にもいくつか覚えておくと良い記述があります。

### アクセス拒否

ページテンプレートのPHPはサーバー上にアップされていますので、直接 /concrete/themes/elemental/default.php などのURLでアクセス可能です。この時、不要なエラーが出力されてサーバー情報が露出することを防ぐため、全てのテンプレートファイルの冒頭に、直接アクセスされた時に「アクセス拒否」と表示されるコードを入れるのがお作法です。

```php:アクセス拒否
<?php defined('C5_EXECUTE') or die("Access Denied.");
```

### ファイルのインクルード

ヘッダーやフッターなど、どのページテンプレートでも共通のパーツをインクルードしたいときは、次のように書きます。

```php:ファイルのインクルード
<?php $this->inc('elements/header.php'); ?>
```

### lang属性値の出力

多言語サイトを構築している際は、lang属性が正しい言語で出力されるようにしておきましょう。

```php:lang属性値の出力
<html lang="<?php echo Localization::activeLanguage() ?>">
```

# ブロックテンプレート

テーマができたら、次なブロックテンプレートです。concrete5では、ページに設置したブロックは、個別に画面上でテンプレートを変更できます。次のスクリーンショットは、**オートナビ**ブロックの**デザイン＆カスタムテンプレート**メニューから、テンプレートを画面上で変更しようとしているところです。

<img width="487" alt="Screen Shot 2019-08-28 at 9.35.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8033/4fb53d2a-5284-8852-9d8e-db3beed357e6.png">

画面を見ると、「（何も選択されていません）」「パンくず」「レスポンシブヘッダーナビゲーション」の３つの選択肢があるのが分かると思います。これら３つのテンプレートは、下記のディレクトリに格納されています。

```
/concrete/blocks/autonav/view.php
/concrete/blocks/autonav/templates/breadcrumb.php
/concrete/blocks/autonav/templates/responsive_header_navigation/view.php
```

concrete5のブロック関連のファイルは、**blocks**ディレクトリに格納されています。その中に、オートナビブロックであれば**autonav**、ページリストブロックであれば**page_list**など、それぞれディレクトリが分かれています。

ブロックのディレクトリ内の**view.php**がデフォルトのテンプレートになり、画面で「（何も選択されていません）」を選択するとこのファイルが使われます。ブロックのディレクトリ内の**templates**ディレクトリ内に、カスタムテンプレートを設置できるという仕組みになっています。

それでは、concrete5に同梱されている「パンくず」テンプレートをカスタマイズしてみましょう。オーバーライドの原則を思い出してください。

```
/concrete/blocks/autonav/templates/breadcrumb.php
```

このファイルを複製して、

```
/application/blocks/autonav/templates/breadcrumb.php
```

ここに置く。シンプルですね。あとは、コーディングに合わせて `<ol class="breadcrumb">` を `<ul class="breadcrumb_nav">` に変更するなり、好きに改変すればOK。

既存のテンプレートの改変ではなく、追加したいときはどうすれば良いか？単にファイルを設置すればOKです。

```
/application/blocks/autonav/templates/my_wonderful_navigation.php
```

それぞれのブロックテンプレートは、素のPHPです。独自のテンプレートエンジンは採用されていません。シンプルに、それぞれのブロックの `view.php` をapplicationフォルダに複製して、必要なclass名の変更やdivの追加などやっていけば大丈夫です。

**「え？それだけ？もっと解説ないの？」**と思われるかもしれませんが、ぶっちゃけ、ないです。なぜかというと、ナビゲーションでサイト内のどんなページを何階層、何順で表示するかとか、新着情報の一覧をどこに何件表示するかとか、**WordPressであればテンプレートに書いて定義することは、全部画面上で、マウス操作で設定するから**です。

そのため、concrete5ではテーマもテンプレートも慣れればあっという間にできあがります。どちらかというと、できたテンプレートを画面上で設定していくほうが時間がかかるくらいです。ここ、ブログ型CMSをずっと触ってきた人にとっては、大きな発想の転換が必要です。

ブロックテンプレートは、PHPとCSS、JavaScriptをセットで作ることもできます。

* [CSSやJavaScriptをカスタムテンプレートから自動で読み込む](https://concrete5-japan.org/help/5-7/developer/working-with-blocks/working-with-existing-block-types/creating-additional-custom-view-templates/automatically-including-css-and-javascript-in-custom-templates/)

# その他の知識

テーマとブロックテンプレートの作り方が分かれば、concrete5でサイトを作れます。祝・卒業！頑張ってください！

と言いたいところですが、その他必須で知っておくべき知識もいくつか補足しておきます。

ブロックテンプレートは、コアの`view.php`を複製して改変すれば良い、とお伝えしましたが、その中で見慣れないconcrete5独自のPHPがありますので、紹介しておきます。

## 翻訳関数

concrete5のテンプレートに度々登場する `t()` 関数は、中の英語を翻訳して表示するための関数です。日本語のみのサイトを作るなら使う必要がないくらいです。多言語サイトであれば、この関数で括ったテキストは、管理画面の「サイトインターフェースを翻訳」ページから翻訳を登録できます。

```php:t()関数の使用例
<?=t('Empty Auto-Nav Block.')?>
```

## ヘルパー

テンプレート内では、文字列や画像、日付の処理を助けるヘルパークラスがよく使われています。

```php:ヘルパーの使用例
<?php
// テキストヘルパーの呼び出し
$th = Core::make('helper/text');
// テキストヘルパーを使って指定した文字数で切り詰め
$th->wordSafeShortText($description, 50);

// 日付ヘルパーの呼び出し
$dh = Core::make('helper/date');
// 日付ヘルパーを使ってローカライズされた書式で日付を表示
$date = $dh->formatDateTime($dateTime);
?>
```

* [Getting helpers in concrete5 5.7+](https://documentation.concrete5.org/developers/appendix/concrete5-version-8-coding-styles/helpers)
* [フォームウィジェットリファレンス](https://concrete5-japan.org/help/5-7/developer/appendix/form-widget-reference/)
* [ページの公開日を指定したフォーマットで表示したい](https://concrete5-japan.org/help/5-7/recipes/get-collection-public-date-with-custom-format/)

## レシピ集

その他、デザインカスタマイズの際に必要な知識は、日本語公式サイトの[レシピ集](https://concrete5-japan.org/help/5-7/recipes/)にまとめて行っています。まだまだ記載されていないTipsもありますので、デザインカスタマイズで困った！ということがある方は、コメント欄にてレシピ集への追加をリクエストください。

それでは、concrete5で良いWebデザインライフを！

あ、[世界一わかりやすいconcrete5導入とサイト制作の教科書](https://amzn.to/2zn9kpX)も見てね！