[baserCMS]テーマヘルパを利用してWordPress風味のコンテンツネームを取得する


WordPressでは、以下のようにして、bodyタグにコンテンツの class を埋め込むことができます。

```php
<body <?php body_class(); ?>>
```

これを、baserCMSで似たように出力されるようにしてみました。

## 環境

- baserCMS 3.0.2
- PHP 5.2.6


## ファイルの作成
以下にphpファイルを作成します。
/app/webroot/theme/YOUR_THEME/Helper/HELPER_NAMEHelper.php

「HELPER_NAME」の箇所は、テーマの名前をキャメル記法で記述します。

- 参考: テーマヘルパー: http://basercms.net/functions/theme_helper

## ファイルの中身
ファイルに以下のコードを記述します。
class HELPER_NAMEHelper extends AppHelper 内の「HELPER_NAME」の箇所は、先ほどのファイル名で付けた名称と同じです。

```php
<?php
/**
 * ThemeHelper
 */
class HELPER_NAMEHelper extends AppHelper {
/**
 * ヘルパー
 *
 * @var array
 */
	var $helpers = array('BcBaser');
	
/**
 * コンテンツを特定する文字列を取得する
 * URLを元に、階層構造やカテゴリ名を保持した文字列を取得する
 * 
 * @param array $options オプション（初期値 : array()）
 *  - `underscore` : ハイフン区切りではなく、アンダースコア区切りで出力する（初期値 : false）
 *	- `category_hierarchy` : カテゴリ階層の接頭語を出力する文字列（初期値 : ctcLv）
 * @return string
 */
	public function getContentNameWpStyle($options = array()) {
		$options = array_merge(
			array(
				'detail' => false,
				'underscore' => false,
				'imploder' => ' ',
				'category_hierarchy' => 'ctcLv',
			), $options);
		
		// ビューにセットされている値を取得
		$viewVars = $this->_View->viewVars;
		if ($options['underscore']) {
			$separator = '_';
		} else {
			$separator = '-';
		}
		$bodyClass = array();
		
		if ($this->BcBaser->isHome()) {
			// トップページのとき
			$bodyClass[] = 'home';
			$bodyClass[] = 'page';
			$bodyClass[] = "page{$separator}home";
		} else {
			$other = true;
			if ($this->BcBaser->isPage()) {
				$other = false;
				// 固定ページのとき
				$bodyClass[] = 'page';
				if (isset($this->request->data['Page'])) {
					$bodyClass[] = "page{$separator}". $this->request->data['Page']['id'];
					$bodyClass[] = "page{$separator}". $this->request->data['Page']['name'];
				}
				
				foreach ($this->request->params['pass'] as $categoryKey => $categoryValue) {
					$categoryKey = $categoryKey + 1;
					$bodyClass[] = $options['category_hierarchy'] . $categoryKey ."{$separator}". $categoryValue;
				}
				
				$categoryCount = count($this->request->params['pass']) - 1;
				$bodyClass[] = $options['category_hierarchy'] . $categoryCount;
			} else {
				// HomeControllerのとき
				if ($this->request->params['controller'] == 'home') {
					$other = false;
					$bodyClass[] = 'home';
					if (!empty($this->request->params['action'])) {
						$bodyClass[] = $this->request->params['action'];
					}
					if (!empty($this->request->params['pass'])) {
						foreach ($this->request->params['pass'] as $passKey => $passValue) {
							$passKey = $passKey + 1;
							$bodyClass[] = $options['category_hierarchy'] . $passKey ."{$separator}". $passValue;
						}
					}
				}
				// ブログのとき
				if (!empty($viewVars['blogContent'])) {
					$other = false;
					$blogContent = $viewVars['blogContent'];
					$bodyClass[] = $this->request->params['plugin'];
					//$bodyClass[] = 'blog';
					$bodyClass[] = $this->request->params['plugin'] ."{$separator}". $blogContent['BlogContent']['id'];
					$bodyClass[] = $this->request->params['plugin'] ."{$separator}". $blogContent['BlogContent']['name'];
					if ($this->BcBaser->isBlogHome()) {
						$bodyClass[] = $this->request->params['plugin'] ."{$separator}". $this->request->params['action'];
					} elseif ($this->BcBaser->isBlogSingle()) {
						$bodyClass[] = 'single';
						$bodyClass[] = "post{$separator}". $viewVars['post']['BlogPost']['id'];
						if (!empty($viewVars['post']['BlogCategory'])) {
							$bodyClass[] = "category{$separator}". $viewVars['post']['BlogCategory']['name'];
						}
					} elseif ($this->_View->Blog->isCategory()) {
						$bodyClass[] = $this->request->params['action'];
						$bodyClass[] = $this->request->params['pass'][0];
						$bodyClass[] = "category{$separator}". $this->request->params['pass'][1];
					} elseif ($this->_View->Blog->isYear()) {
						$bodyClass[] = $this->request->params['action'];
						$bodyClass[] = $this->request->params['pass'][0];
						$bodyClass[] = "archives{$separator}". $viewVars['year'];
					} elseif ($this->_View->Blog->isMonth()) {
						$bodyClass[] = $this->request->params['action'];
						$bodyClass[] = $this->request->params['pass'][0];
						$bodyClass[] = "archives{$separator}". $viewVars['year'] ."{$separator}". $viewVars['month'];
					} elseif ($this->_View->Blog->isDate()) {
						$bodyClass[] = $this->request->params['action'];
						$bodyClass[] = $this->request->params['pass'][0];
						// TODO BlogControllerの日付アーカイブで日付がsetされたら改修する
						if (isset($viewVars['day'])) {
							$bodyClass[] = "archives{$separator}". $viewVars['year'] ."{$separator}". $viewVars['month'] ."{$separator}". $viewVars['day'];
						} else {
							$bodyClass[] = "archives{$separator}". $viewVars['year'] ."{$separator}". $viewVars['month'] ."{$separator}". $this->request->params['pass'][3];
						}
					} elseif ($this->_View->Blog->isTag()) {
						$bodyClass[] = $this->request->params['action'];
						$bodyClass[] = $this->request->params['pass'][0];
						$bodyClass[] = "tag{$separator}". $this->request->params['pass'][1];
					} elseif ($this->_View->Blog->getBlogArchiveType() == 'author') {
						$bodyClass[] = $this->request->params['action'];
						$bodyClass[] = $this->request->params['pass'][0];
						$bodyClass[] = "author{$separator}". $this->request->params['pass'][1];
					}
				}
				// フォームのとき
				if (!empty($viewVars['mailContent'])) {
					$other = false;
					$mailContent = $viewVars['mailContent'];
					$bodyClass[] = $this->request->params['plugin'];
					//$bodyClass[] = 'mail';
					$bodyClass[] = $this->request->params['plugin'] ."{$separator}". $mailContent['MailContent']['id'];
					$bodyClass[] = $this->request->params['plugin'] ."{$separator}". $mailContent['MailContent']['name'];
					
					$freezed = $viewVars['freezed'];
					// フォーム表示
					if ($this->request->params['action'] == 'index') {
						$bodyClass[] = "mail{$separator}". $this->request->params['action'];
					}
					// 確認画面
					if ($this->request->params['action'] == 'confirm') {
						$bodyClass[] = "mail{$separator}". $this->request->params['action'];
						if (!$freezed) {
							$bodyClass[] = "mail{$separator}error";
						}
						if ($freezed) {
							$bodyClass[] = "mail{$separator}novalidate";
						}
					}
					// 送信完了
					if ($this->request->params['action'] == 'submit') {
						$bodyClass[] = "mail{$separator}". $this->request->params['action'];
					}
				}
				// 固定ページ、ブログ、メール以外のコンテンツの場合
				if ($other) {
					$bodyClass[] = $this->BcBaser->getContentsName($options['detail'], $options);
					if (!empty($this->request->params['plugin'])) {
						$bodyClass[] = $this->request->params['plugin'] ."{$separator}". $this->request->params['action'];
					}
					if (!empty($this->request->params['controller'])) {
						$bodyClass[] = $this->request->params['controller'];
					}
					if (!empty($this->request->params['action'])) {
						$bodyClass[] = $this->request->params['action'];
					}
					if (!empty($this->request->params['pass'])) {
						foreach ($this->request->params['pass'] as $passKey => $passValue) {
							$passKey = $passKey + 1;
							$bodyClass[] = $options['category_hierarchy'] . $passKey ."{$separator}". $passValue;
						}
					}
				}
			}
		}
		return implode($options['imploder'], $bodyClass);
	}
	
}

```

## 利用方法

使い方は、以下のように、レイアウトなどの bodyタグを書いている箇所に付けます。

```php
<body class="<?php echo h($this->YOUR_THEME->getContentNameWpStyle()) ?>">
```

オプション全開の例は以下です。

```php
<?php echo h($this->YOUR_THEME->getContentNameWpStyle(array(
	'underscore' => false,				// true: ハイフン区切りになります。
	'imploder' => ' ',					// 出力文字列の繋ぎの文字列を指定できます。
	'category_hierarchy' => 'ctcLv',		// カテゴリ階層の接頭語を出力する文字列を指定できます。
))) ?>
```

## 今後の利用
baserCMSの今後の展開次第で、コアに盛り込まれるかもしれませんし、されないかもしれません。
それまでの繋ぎとして公開します。

また、この機能を作成するに当り、[n1215](https://github.com/n1215 "https://github.com/n1215")さんに多大なアドバイスをいただきました。
本当にありがとうございました_(．．)_

- 経緯: https://github.com/baserproject/basercms/pull/230