Concrete CMS 8.x テーマスニペット集 完全保存版


テーマを作る上で、良く使うスニペット集を殴り書きです。PHPの開始＆閉じタグを省いているばあいがあるので、適宜、<?php ?> の追加をお願いします。このコードは 5.7.5.6 である程度確認済み。

Katz がテーマ作成の時によく使うコードのたまり場です。

※ 殴り書きなので、もしかしたら間違っているコードあるかも。その場合はお知らせいただくと幸いです。

このページは Concrete CMS 8.x 版です。

- [5.6.x 対応版](http://ja.katzueno.com/2014/05/3104/)
- [5.7.x 対応版](http://ja.katzueno.com/2015/08/3492/)

初稿： 2015/8/27 (木) ※ このページは随時更新していきます。
更新： 2020/7/8 (水)


## 修正 ToDo

※ だんだんと、コードが古くなっています。すいません、近々リニューアルします。 (2019/10/17 追記)


### 古い書き方
- Loader::element
- $u = new User();

### 他

- htmlentitle エンコード、カノニカル化
- 単なる PHP のテクニックのところ、textヘルパーで良い


## PHP コードスニペット：テーマ編

```php
<?php
/*
 *
 * 必須タグ
 *
*/
?>

// 最初の直接アクセス禁止
<?php
defined('C5_EXECUTE') or die(_("Access Denied."));
?>

// <head> 直後に配置
<?php
View::element('header_required', ['pageTitle' => $pageTitle]);
// $pageTitle にタイトル要素を定義すると concrete5 デフォルト設定からオーバーライドされます。
?>

<?php // <body> 開始直後に配置 ?>
<div class="<?php echo $c->getPageWrapperClass()?>">
<!--
タグを閉じるのを忘れずに
<div class="ccm-page page-type-blog page-template-full">
などと page-type-ハンドル や page-templete-ハンドル と CSS クラスが出力されます
-->

<?php
// </body> 直前に配置
<?php
View::element('footer_required');
?>

//エリア宣言
<?php
$a = new Area('【エリア名】');
$a->display($c);
?>

// エリア内レイアウト機能を有効にする
<?php
$a = new Area('【エリア名】');
$a->enableGridContainer();
$a->display($c);
?>

//グローバルエリア宣言
<?php
$a = new GlobalArea('【グローバルエリア名】');
$a->display();
?>

// view.php (Single ページ) 表示用
<?php
Loader::element('system_errors', array('error' => $error));
print $innerContent;
?>

// 便利なコード集

// 現在のページ情報を格納する。テーマファイル以外の場所であるとの最初に宣言必須（下記のコードもこれを使っている所あり）
<?php
$c = Page::getCurrentPage();
?>

// テーマへのパス (テーマ内)
<?php
echo $view->getThemePath();
?>

/*
 *
 * テーマエリアなどオプション
 *
*/
// テーマのカスタマイズ機能を使って LESS をセットする場合
<?php
echo $html->css($view->getStylesheet('main.less'));
?>

// ヘッダーやフッター部分のコードなど、別ファイルに共有部分を追加し埋め込みたい場合
<?php
$view->inc('elements/header.php');
$view->inc('elements/footer.php');
$view->inc('【その他任意のファイル名】');
?>

// 別ファイルに特定の変数の値を渡したい場合
<?php
$view->inc('elements/header.php', array('pageTitle' => $pageTitle));
?>

// エリア内のブロック数を制限する
<?php
$a = new Area('【エリア名】');
$a->setBlockLimit(1); // 1 のところを変えて制限数を変える
$a->display($c);
?>

//エリアがゼロだったら表示しない（Global にしたらグローバルエリアでも可能）
<?php
$a = new Area('【エリア名】');
if ($c->isEditMode() || $a->getTotalBlocksInArea($c) > 0) {
 $a->display($c);
}
?>

<?php
$a = new GlobalArea('【グローバルエリア名】');
if ($c->isEditMode() || $a->getTotalBlocksInArea() > 0) {
 $a->display();
}
?>

// グローバルエリアの編集を表から行わない
// HTML ブロック流しこみなどで、編集モードにした時に、表示が崩れすときなどの対策に使います。
<?php
$a = new GlobalArea('【グローバルエリア名】');
$a->disableControls();
$a->display();
?>

// 編集モードだった場合の条件分岐
<?php
if ($c->isEditMode()) {
// ここにコードや、HTML を書く。
}
?>

// 編集ツールバーが見えたときの条件分岐
<?php
$cp = new Permissions($c);
if ($cp->canViewToolbar()) {
    // ここにコードや、HTML を書く。
}
?>

// ページタイプのデフォルトページだった場合
<?php
if ($c->isMasterCollection()) {
    // ここにコードや、HTML を書く。
}
?>

// ログイン・ログアウトURL (ログイン後に元いたページに戻ります)
<?php
$u = new User(); // これはファイルの最初に一回宣言したら良いだけです
if ($u->isRegistered()) { ?>
<p><a href="<?php echo URL::to('/account')?>">マイアカウント</a><?p>
<p><a href="<?php echo URL::to('/login', 'logout', id(new Concrete\Core\Validation\CSRF\Token())->generate('logout'));?>"><?php echo t('Logout');?></a></p>
<?php } else { ?>
<p><a href="<?php echo URL::to('/register')?>">新規登録</a></p>
<p><a href="<?php echo URL::to('/login', 'forward') . $c->getCollectionID() . '/';?>"><?php echo t('Login');?></a></p>

<?php } ?>

/*
 *
 * ページ情報の取得
 *
*/

// ページ名を取得し htmlentitle エンコード
<?php
echo h($c->getCollectionName());
?>

// ページ名・親階層のページを表示
<?php
$c = Page::getCurrentPage();
$nh = Core::make('helper/navigation');
// concrete5 第4階層以降であれば、第3階層 のページタイトルを表示させる。
// [現在のページタイトル] - [第2階層のページタイトル]
// ページ属性 display_secondary_title がチェックされていれば第2階層のタイトルを表示しない
// $trail [0] はトップ
// $trail [1] は第2階層
echo h($c->getCollectionName());
if (!$c->getAttribute('display_secondary_title')){
	$trail = $nh->getTrailToCollection($c))
	$breadcrumb = array_reverse ($trail);
	if ($breadcrumb[1]) {
		echo . ' - ' .h($breadcrumb[1]->getCollectionName());
	}
}
?>

// ページの「説明」を取得
<?php
echo h($c->getCollectionDescription());
?>

// ページの公開日 (Y/m/d) という日付フォーマットで表示
<?php
echo $c->getCollectionDatePublic('Y/m/d');
?>

// ページのURLスラッグを取得し表示する。
<?php
echo $c->getCollectionHandle();
?>

// ページのURLスラッグを取得し、カノニカル化する
// 例: "about-us" -> "About Us"
<?php
$th = Core::make('helper/text');
$handle = h($c-> getCollectionHandle());
$handle = $th->unhandle($handle);
echo $handle;
?>

// ページの所有者を表示
<?php
$user = User::getByUserID($c->getCollectionUserID());
$username = $user->getUserName();
echo $username;
?>

// ページの所有者の公開プロフィールURLを取得 (要検証)
<?php
$profileurl = URL::to('/members/profile/',$c->getCollectionUserID());
echo $profileurl;
?>

// ページを最初に作った人のIDを取得 (要検証)
<?php
$original_author = Page::getByID($c->getCollectionID(), 1)->getVersionObject()->getVersionAuthorUserName();
echo $original_author;
?>

// 最後に編集した人のユーザーIDを取得
<?php
$last_edited_by = $c->getVersionObject()->getVersionAuthorUserName();
echo $last_edited_by;
?>

// ページ属性の値を出力
<?php
echo $c->getAttribute('【ページ属性のハンドル】');
?>

// ページ属性の値を出力（エスケープ処理）
<?php
echo h($c->getAttribute('【ページ属性のハンドル】'));
?>

// ページ属性の値を出力（複数行に <br> つける）
<?php
echo nl2br(h($c->getAttribute('【ページ属性のハンドル】'));
?>

// 選択属性を表示する
$options = $ui->getAttribute('【ページ属性のハンドル】');
if (is_object($options)) {
// 複数選択の場合
    $optionValue = array();
    foreach ($options as $o) {
        $optionValue = $o->getSelectAttributeOptionValue();
    }
}

// トピックを表示
<?php
$topics = $c->getAttribute('【ページ属性のハンドル】');
if (is_array($topics)) {
    echo $topics[0]->getTreeNodeName(); // 未翻訳
    echo $topics[0]->getTreeNodeDisplayName(); // 翻訳済み
}
?>

// 日付属性を表示させる（いろんなバージョン）をちょっとすっきり
<?php
$dateHelper = \Core::make('helper/date');
$date = $c->getAttribute('【ページ属性のハンドル】');
$date = $dateHelper->formatDateTime($date); // 言語に合わせた日付フォーマット
$date = $dateHelper->formatCustom('Y年m月j日 (D)', $date);
$date = $dateHelper->formatCustom('Y/m/d', $date);
$date = $dateHelper->formatCustom('H:i', $date);
echo $date;
?>

/*
 *
 * サムネイル画像を出力する
 * 詳細は http://concrete5-japan.org/help/5-7/recipes/how-to-get-thumbnail-image/
 * サムネイルを予め 管理画面 - システムと設定 - ファイル - サムネイル画像 から設定しハンドル名を指定する必要があります。
 * 高さを指定しなければ、縦横比を保持して縮小を行います。高さを入力すれば、その大きさに切り抜き表示されます。
 *
*/
<?php
// "thumbnail" というページの画像属性から small と設定したサムネイル画像を表示する
$f = $c->getAttribute('thumbnail'); // これはページ属性を取得する方法です。
if ($f) { // オブジェクトが null だとエラーが出るので、回避処理を付け加えたほうが良い
    $src = $f->getThumbnailURL('small'); // サムネイル画像のハンドルは自由に変更してください。
    // いろいろしたい場合
    $thumbnail = \HtmlObject\Image::create($src);
    $thumbnail->alt('Alt テキスト'); // オプション: Alt テキストを設定する
    $thumbnail->title('Title テキスト'); // オプション: Title テキストを設定する
    $thumbnail->addClass('Class 名'); // オプション: Class 名を加える
    echo $thumbnail;
    // もしくはシンプルに
    echo \HtmlObject\Image::create($src)->alt('Alt テキスト'); // 1つだけオプションを加えるのであれば、このような記述でOK。$img // img タグごと出力されます
}
?>

// 任意でサイズを指定して表示する
<?php
$img = $c->getAttribute('【画像が入っているページ属性のハンドル】');
$src = $img->getRelativePath();
$html = new \HtmlObject\Image();
$img = $html->src($src)
       ->width(640)
       ->height(480)
       ->class('class');
echo $img // img タグごと出力されます
?>


// ページ属性で画像を読み込む（リサイズなし）
<?php
$img = $c->getAttribute('【画像が入っているページ属性のハンドル】');
$fv = $img->getVersion();
$imgWidth = $fv->getAttribute('width'); // 横サイズ
$imgHeight = $fv->getAttribute('height'); // 縦サイズ
echo $img->getRelativePath(); // 画像URL
echo $imgWidth; // 横ピクセル数
echo $imgHeight; // 縦ピクセル数
echo $img->getTitle(); // ファイルタイトル
// 上記4コードを適宜 <img> タグの中に埋め込む

$html = new \HtmlObject\Image();
$img = $html->src($img->getRelativePath())
       ->width($imgWidth)
       ->height($imgHeight)
       ->alt($img->getTitle())
       ->title($img->getTitle())
       ->class('class');
echo $img // img タグごと出力されます
?>

/*
 *
 * ご注意
 * 下記は 5.6 からあるサムネイル画像を作成する古い方法で
 * 将来、消える可能性があります。
 * できるだけ使わないように
 *
*/
// ページ属性で画像を読み込む（リサイズあり）
<?php
$ih = Core::make('helper/image'); // イメージヘルパー読み込み。リサイズ処理で必要
$img = $c->getAttribute('【画像が入っているページ属性のハンドル】');
$thumb = $ih->getThumbnail($img, 縦, 横, true); //リサイズ処理。無制限の場合9999と指定
echo $thumb->src; // リサイズされた画像のURL
echo $thumb->width; // リサイズされた画像の横ピクセル
echo $thumb->height; // リサイズされた画像の縦ピクセル
// 上記3コードを適宜 <img> タグの中に埋め込む
?>

// 著者アバター画像を表示させる
//    後述の /application/config/concrete.php でアバター画像のデフォルトサイズを設定
<?php
$profile = UserInfo::getByUserID($c->getCollectionUserID());
// img タグも出力
print Core::make('helper/concrete/avatar')->outputUserAvatar($profile);
// アバターイメージのパスだけ取得 (なければ false が返されるので、無かった時の no image 画像を出力する処理の追加が必要)
$avatarImageURL = Core::make('helper/concrete/avatar')->getImagePath($profile);
?>

// 現在のページのページタイプのハンドルを取得する
<?php
$c->getPageTypeHandle(); // 5.7 からはこちら
?>
<?php
$c->getCollectionTypeHandle(); // 5.6.x 時代からのコード。
?>

// 現在のページのページテンプレートのハンドルを取得する
<?php
$c->getPageTemplateHandle();
?>

// 特定のページタイプだったらエリアを表示させる
<?php
$pageType = $c->getCollectionTypeHandle();
if ($pageType =='【ページタイプのハンドル】') {
    $a = new Area('【エリア名】');
    $a->display($c);
}
?>

// ヘッダーに js や css を追加させる
// テーマフォルダにリンクが飛ぶ。下層ディレクトリのファイルを指定することも可能。
<?php
$html = Core::make('helper/html');
print $html->css('path/to/my.css');
print $html->javascript('path/to/library.js'); // テーマディレクトリの JS 「テーマpath/to/library.js」を読み込んでいる例
?>

// ヘッダーに js や css を追加させる（パッケージに同梱させた場合）
<?php
$html = Core::make('helper/html');
$pkg = Package::getByHandle('【パッケージハンドル】');
print $html->javascript('path/to/library', $pkg);
print $html->css('path/to/library', $pkg);
?>

<?php
// ファイルの拡張子を取得し、サイズを取得して、Byte, KB, MB など程よくフォーマットを修正して表示する。
$f = $controller->getFileObject(); //ファイルブロックの場合
$c = Page::getCurrentPage(); // 現在表示しているページ。ここを変えると任意のページを指定できる。
$f = $c->getAttribute('【ページ属性】'); //ページ属性の場合
$u = new User(); // ログインしているユーザーを取得
$ui = UserInfo::getbyID($u-getUserID();) // これを変えると任意のユーザーを指定できる。
$f = $ui->getAttribute('【ユーザー属性】'); //ユーザー属性の場合
if ($f) {
    $fv = $f->getVersion();
    $size = $fv->getFullSize(); // Get the file size
    $size = Core::make('helper/number')->formatSize($size);
    $type = strtolower($fv->getExtension()); // get the file extension
}
?>

<?php
// ********************
// ページタイトルなど Meta タグ関係の多言語対応とか 
// ********************
// ※ concrete5 Ver 8 からはサイト名が多言語対応になります
// ・各言語のサイト名 = 各言語トップページの meta_title が各言語のサイト名
// ・各言語の Meta Description や Meta Keywords = 各言語トップページの情報が使われるように
// 
// 現在のページから、トップページまでの $c データを array で取得
// そこから array を -1 (トップページの $c を除いて第1階層の $c からはじまる array になる)
// 第1階層は /ja/ か /en/ の言語のトップページになるので、そのページオブジェクトを $landC に格納
$nh = Core::make('helper/navigation');
$trail = $nh->getTrailToCollection($c);
if (is_array($trail)) {
    if (count($trail) > 1) {
	    $count = count($trail);
    	array_splice($trail, $count - 1);
    	$langC = array_pop($trail);
    } else {
    	$langC = $c;
    }
} else {
    $langC = $c;
}
$siteName = $langC->getCollectionAttributeValue('meta_title');
if (!$siteName) {
	$siteName = Config::get('concrete.site');
}

$pageTitle = $c->getCollectionAttributeValue('meta_title');    
if (!$pageTitle) {
    $collentionName = $c->getCollectionName();
    $pageTitle = $collentionName . ' | ' . $siteName; // [ページ名] | [サイト名] なフォーマット
}

// ページ説明が空だったら、各言語のトップページの説明文が Meta Description に引用される。
$pageDescription = $c->getCollectionAttributeValue('meta_description');
if (!$pageDescription) {
	$pageDescription = $c->getCollectionDescription();
}
if (!$pageDescription && is_object($langC)) {
	$pageDescription = $langC->getCollectionDescription();
}

// Meta Keyword が空だったら、各言語のトップページの meta_keywords が Meta Keywords に引用される。
$pageMetaKeywords = $c->getCollectionAttributeValue('meta_keywords');
if (!$pageMetaKeywords && is_object($langC)) {
    $pageMetaKeywords = $langC->getCollectionAttributeValue('meta_keywords');
}

// 以上のページタイトル、説明、Keyword のデータを elements/header_required.php に渡す。
// Meta Keyword は 5.7.5.6 からの実装なので、それ以前のバージョンでは使えないので注意。
Loader::element('header_required', array(
    'pageTitle' => isset($pageTitle) ? $pageTitle : '',
    'pageDescription' => isset($pageDescription) ? $pageDescription : '',
    'pageMetaKeywords' => isset($pageMetaKeywords) ? $pageMetaKeywords : '',
    )
);
?>

// 単なる PHP のテクニック
// 文字数を全角、半角一緒の長さでトリミングをする方法
// mb_strimwidth() を使う。
// concrete5 のテキストヘルパーだと、全角も1文字としてカウントされるので、半角と全角のバランスが悪くなる。
// 例
<?php
$description = $c->getCollectionDescription(); //現在のページ
$description = $page->getCollectionDescription(); //ページリスト中
if (strlen($description) > 200) $description = mb_strimwidth($description, 0, 200, '...', "UTF-8");
?>
```

## PHP コードスニペット：/config/app.php編

/application/app.php で記述する記述

```php
<?php

return array(
/**
 * Route themes
 * 各管理画面などページでどのテーマを使うか
 * VIEW_CORE_THEME はコアのテーマ
 * '【テーマのフォルダ名】'と記述すれば、自分のテーマを適用できます
 */
'theme_paths'         => array(
    '/dashboard'        => 'dashboard',
    '/dashboard/*'      => 'dashboard',
    '/account'          => '【テーマフォルダ名】',
    '/account/*'        => '【テーマフォルダ名】',
    '/install'          => VIEW_CORE_THEME,
    '/login'            => '【テーマフォルダ名】',
    '/register'         => '【テーマフォルダ名】',
    '/maintenance_mode' => VIEW_CORE_THEME,
    '/upgrade'          => VIEW_CORE_THEME
    )
);

// なお page_forbidden.php (403ページ )や page_not_found.php (404 ページ)は
// テーマのフォルダ内に同名のファイル名を作成すれば自動的に適用されます。
```

## PHP コードスニペット：config/concrete.php編
/application/config/concrete.php でよく使う記述です。

その他詳細は、<a href="https://rescuework.nagoya/blog/config-concrete/">レスキューワーク水野さんのブログ記事</a>をご覧ください。

管理画面で設定するものを強制的に変更したり、管理画面にはない設定を行う部分です。

すべての設定項目は /concrete/config/concrete.php に記載してあります。

```php
<?php
return array(
   /**
     * ------------------------------------------------------------------------
     * concrete5.org からのお知らせやヘルプを受け取るかどうか
     * ------------------------------------------------------------------------
     */
    'external'              => array(

        /**
         * インテリジェント検索でヘルプを含めるかどうか
         *
         * @var bool concrete.external.intelligent_search_help
         */
        'intelligent_search_help' => true, // or false

        /**
         * concrete5 からの最新情報を表示する
         *
         * @var bool concrete.external.news_overlay
         */
        'news_overlay'            => true, // or false

        /**
         * あなたのサイトで concrete5 お知らせを有効にする
         *
         * @var bool concrete.external.news
         */
        'news'                    => false, // or false
    ),
    /**
     * --------------------------------------------------------------------
     * concrete5 のバージョン情報を <head> の generator に出力しないようにする
     * --------------------------------------------------------------------
     */
    'misc'              => array(
        'app_version_display_in_header' => false
    ),

 /**
     * ------------------------------------------------------------------------
     * SEO 設定
     * ------------------------------------------------------------------------
     */
    'seo'               => array(

        /**
         * URL リライト
         *
         * 低レベルで設定された URL_REWRITING_ALL に影響しない
         * 「全ての」アイテムをリライトするかどうかを制御する
         *
         * @var bool
         */
        'url_rewriting'        => false,
        'url_rewriting_all'        => false,
        'redirect_to_base_url' => false,
        'trailing_slash'       => false,
        'title_format'         => '%1$s :: %2$s',
        'page_path_separator'  => '-',
        'group_name_separator' => ' / ',
        'segment_max_length'   => 128,
        'paging_string'        => 'ccm_paging_p'
    ),

    /**
     * ------------------------------------------------------------------------
     * キャッシュ設定
     * ------------------------------------------------------------------------
     */
    'cache'             => array(

        /**
         * Enabled
         *
         * @var bool
         */
        'enabled'                  => true,

        /**
         * Lifetime
         *
         * @var int Seconds
         */
        'lifetime'                 => 21600,

        /**
         * Cache overrides
         *
         * @var bool
         */
        'overrides'                => true,

        /**
         * Cache Blocks
         *
         * @var bool
         */
        'blocks'                   => true,

        /**
         * Cache Assets
         *
         * @var bool
         */
        'assets'                   => false,

        /**
         * Cache Theme CSS/JS
         *
         * @var bool
         */
        'theme_css'                => true,

        /**
         * Cache full page
         *
         * @var bool|string (block|all)
         */
        'pages'                    => false,

        /**
         * Use Doctrine development mode
         *
         * @var bool
         */
        'doctrine_dev_mode'        => false,

        /**
         * How long to cache full page
         *
         * @var string
         */
        'full_page_lifetime'       => 'default',

        /**
    ),

    /**
     * ------------------------------------------------------------------------
     * 多言語設定
     * ------------------------------------------------------------------------
     */
    'multilingual' =>   array(
        'redirect_home_to_default_locale' => false,
        'use_browser_detected_locale' => false,
        'default_locale' => false,
        'default_source_locale' => 'en_US'
    ),

    /**
     * ------------------------------------------------------------------------
     * デザイン・レイアウト設定
     * ------------------------------------------------------------------------
     */
    'design'            => array(
        'enable_custom' => true,
        'enable_layouts' => true
    ),

    /**
     * ------------------------------------------------------------------------
     * 通知メール設定
     * ------------------------------------------------------------------------
     */
    'email'             => array(

        /**
         * Enable emails
         *
         * @var bool
         */
        'enabled' => true,
        'default' => array(
            'address' => 'concrete5-noreply@' . (isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost'),
            'name'    => ''
        ),
        'form_block' => array(
            'address' => false
        ),
        'forgot_password' => array(
            'address' => null,
            'name' => null,
        ),
        'validate_registration' => array(
            'address' => null,
            'name' => null,
        ),
    ),

    /**
     * --------------------------------------------------------------------
     * MISC設定
     * --------------------------------------------------------------------
     */
    'misc'              => array(
        'user_timezones'                => false,
        'package_backup_directory'      => DIR_FILES_UPLOADED_STANDARD . '/trash',
        'enable_progressive_page_reindex'      => true,
        'mobile_theme_id'               => 0,
        'sitemap_approve_immediately'   => true,
        'enable_translate_locale_en_us' => false,
        'page_search_index_lifetime'    => 259200,
        'enable_trash_can'              => true,
        'app_version_display_in_header' => true,
        'default_jpeg_image_compression'     => 80,
        'help_overlay'                  => true, // ユーザーが最初のログイン直後にヘルプ画面を表示するかか
        'require_version_comments'      => false,
    ),

    'theme' => array(
        'compress_preprocessor_output' => true,
        'generate_less_sourcemap' => false,
    ),

    // アイコンの設定
    'icons' => array(
        // ユーザーアバターのデフォルト画像の大きさを設定
        'user_avatar' => array(
            'width' => 80,
            'height' => 80,
            // アバター画像がないユーザーを表示する画像の登録先パス
            'default' => ASSETS_URL_IMAGES . '/avatar_none.png',
        ),
    ),

    // ファイルマネージャーの設定
    'file_manager' => array(
        'images' => array(
            // 画像の exif データを使って画像を回転させるか
            'use_exif_data_to_rotate_images' => false,
            // 画像ライブラリ
            'manipulation_library' => 'gd'
        ),
        // デフォルトで表示するファイルの数
        'results' => 10
    ),

    // ユーザー一覧
    'search_users' => array(
        // デフォルトで表示するユーザーの数
        'results' => 10
    ),


    /**
     * ------------------------------------------------------------------------
     * ホワイトラベリング.
     * ------------------------------------------------------------------------
     */
    'white_label'       => array(

        /**
         * Custom Logo source path relative to the public directory.
         *
         * @var bool|string The logo path
         */
        'logo'                 => false,

        /**
         * Custom Name
         *
         * @var bool|string The name
         */
        'name'                 => false,

        /**
         * Dashboard background image url
         *
         * @var null|string
         */
        'dashboard_background' => null
    ),

    /**
     * ------------------------------------------------------------------------
     * 権限設定
     * ------------------------------------------------------------------------
     */
    'permissions'       => array(
        /**
         * 権限がない場合、ログインページを表示 (true) するか、403 ページを表示 (false) するか
         *
         * @var bool
         */
        'forward_to_login'              => true,

        /**
         * 権限モード
         *
         * @var string The permission model (simple|advanced)
         */
        'model'                         => 'simple',
    ),

    /**
     * ------------------------------------------------------------------------
     * SEO 関連
     * ------------------------------------------------------------------------
     */
    'seo'               => array(

        'tracking'             => array(
            /**
             * 管理画面で入力するトラッキングコード
             *
             * @var string
             */
            'code'          => '',

            /**
             * トラッキングコードの出力位置 (top か bottom)
             *
             * @var string (top|bottom)
             */
            'code_position' => 'bottom'

        ),
        'exclude_words'        => 'a, an, as, at, before, but, by, for, from, is, in, into, like, of, off, on, onto, per, ' .
            'since, than, the, this, that, to, up, via, with',

        /**
         * URL リダイレクト設定
         *
         * Doesn't impact concrete.seo.url_rewriting_all which is set at a lower level and
         * controls whether ALL items will be rewritten.
         *
         * @var bool
         */
        'url_rewriting'           => false,
        'url_rewriting_all'       => false,
        'redirect_to_canonical_url'  => false,
        'canonical_url'          => null,
        'canonical_ssl_url'          => null,
        'trailing_slash'          => false,
        'title_format'            => '%1$s :: %2$s',
        'title_segment_separator' => ' :: ',
        'page_path_separator'     => '-',
        'group_name_separator'    => ' / ',
        'segment_max_length'      => 128,
        'paging_string'           => 'ccm_paging_p'
    ),


    /**
     * ------------------------------------------------------------------------
     * 統計関係の設定
     * ------------------------------------------------------------------------
     */
    'statistics'        => array(
        'track_downloads' => true
    ),

    /**
     * ------------------------------------------------------------------------
     * アクションリミットの設定
     * ------------------------------------------------------------------------
     */
    'limits'            => array(
        'sitemap_pages'           => 100,
        'delete_pages'            => 10,
        'copy_pages'              => 10,
        'page_search_index_batch' => 200,
        'job_queue_batch'         => 10,
        'style_customizer' => array(
            'size_min' => -50,
            'size_max' => 200,
        )
    ),

    /**
     * ------------------------------------------------------------------------
     * アップグレードの設定
     * ------------------------------------------------------------------------
     * /concrete 内のファイルが最新になったら自動的にアップデートスクリプトを走らせる
     */
    'updates' => array(
        'enable_auto_update_core' => true
    ),

);
```

## PHP コードスニペット：ブロック編

```php
<?php
// ブロックグループ
protected $btDefaultSet = 'navigation';
// block の controller.php の class に追加するとブロックグループに追加される。
// 既存のブロックグループ
// basic
// navigation
// form
// social
// multimedia

// 覚えておきたいヘルパーなど
$nh = Core::make('helper/navigation');
$th = Core::make('helper/text');
$ih = Core::make('helper/image'); // もうすぐなくなるので注意
$dh = Core::make('helper/date');
$c = Page::getCurrentPage();
$v = View::getInstance();
$themePath = $v->getThemePath();


// ページリスト関連 (ページリストのループの $pages を $page とforeach)
<?php foreach ($pages as $page) { ?>

// ページリスト等：ページの小ページの数を取得 (ページリストなどに使える)
echo $page->getNumChildren();

// ページリスト等：ページが外部リンクで「_blank」指定があるかどうか
$page->getCollectionPointerExternalLink()

// ターゲット属性「nav_target」を取得
$target = $page->getAttribute('nav_target');

// 複数選択されたトピック属性を表示する
$topics = $page->getAttribute('トピック属性');
if (is_array($topics)) {
    if (count($topics)) {
    	foreach($topics as $topic) {
        	echo $topic->getTreeNodeDisplayName();
    	}
    }
}
```

## PHP コードスニペット：bootstrap/app.php編

コアのクラスをオーバーライドしたい場合。ただし、5.7 以降のバージョンで Bootstrap/app.php の方式を変えようか議論中。

```php
<?php
// ヘルパーのオーバーライドサンプル
Core::bind('helper/form', function() {
 	 return new \Application\Src\Form\Service\Form();
 });
// Core::make('helper/form') で呼び出している /concrete/src/form/Service/Form.php の  Form クラスを、/application/src/form/Service/Form.php にオーバーライドさせる

Core::bind('helper/form/attribute', function() {
 	 return new \Application\Src\Form\Service\Widget\Attribute();
 });
// Core::make('helper/form/attribute') で呼び出している /concrete/src/form/Service/Widget/Attribute.php の  Attribute クラスを、/application/src/form/Widget/Attribute.php を読み込むようオーバーライドしている

// ページネーションのオーバーライドサンプル
Core::bind('manager/view/pagination', function($app) {
    return new \Application\Src\Search\Pagination\View\Manager($app);
});
```

## Javascript コードスニペット

```html
// 相対URLパスの書き方 (via @acliss19xx)
//CCM_BASE_URL + CCM_REL + '/index.php'
//
// htmlブロックタイプはjavascriptの記述を許可していますので
//以下のように書けば絶対パスをべた書きしなくて済みます。
<a href ="#" onclick="location.href = CCM_BASE_URL + CCM_REL + '/index.php'">ホーム</a>
[/code]

<strong>■ ページリスト掲載中の新着記事に「New」マークを付ける方法</strong>
<a href="https://gist.github.com/hissy/9616508">https://gist.github.com/hissy/9616508</a>
```