Pictnotes メインイメージ

お仕事メモ

パンくずリストのカスタマイズ

<ul><li>とかのタグで構成されているパンくずリストを作成する場合
ただし、検証が甘い。



baserCMSで用意されている、$this->BcBaser->crumbs だと、<ul><li>とかのタグで構成されているパンくずリストには対応できません。
でもってちょっとカスタマイズというか改造。

<dl id="breadList">
  <dt><a href="/">HOME</a></dt>
  <dd><a href="/shop/">直営店</a></dd>
  <dd>本店</dd>
</dl>
といったケースのパンくずリストのタグを作りたい場合、 ベースとしては、デフォルトのnada-iconsにのElementsフォルダにある、crumbs.phpを利用してください。

crumbs.phpの
$this->BcBaser->crumbs(' &gt; ', 'ホーム');

$crumb = $this->BcHtml->getCrumbList(array('separator'=>'','firstClass'=> false,'lastClass'=> false), array('text'=> '<dt>HOME</dt>','escape'=> false));
echo $crumb ;
と変更
getCrumbListは、baserCMSの機能でなく、HtmlHelperのメソッドとなります。
http://book.cakephp.org/2.0/ja/core-libraries/helpers/html.html#HtmlHelper::getCrumbList
こちらを使うと、ul,liとかのタグで囲んでくれます。
ただ、これul,liしか対応してないので、今回の dl, dd(dt)は非対応、なのでちょっとカスタマイズ。
BcHtmlHelper.php にgetCrumbListのメソッドをまるっとコピーして、そちらを見るようにしてしまいます。

/**
 * Returns breadcrumbs as a (x)html list
 *
 * This method uses HtmlHelper::tag() to generate list and its elements. Works
 * similar to HtmlHelper::getCrumbs(), so it uses options which every
 * crumb was added with.
 *
 * ### Options
 * - `separator` Separator content to insert in between breadcrumbs, defaults to ''
 * - `firstClass` Class for wrapper tag on the first breadcrumb, defaults to 'first'
 * - `lastClass` Class for wrapper tag on current active page, defaults to 'last'
 * - `firstTag` use tag, defaults to 'ul'
 * - `secondTag` use tag, defaults to 'li'
 *
 * @param array $options Array of html attributes to apply to the generated list elements.
 * @param string|array|boolean $startText This will be the first crumb, if false it defaults to first crumb in array. Can
 *   also be an array, see `HtmlHelper::getCrumbs` for details.
 * @return string breadcrumbs html list
 * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/html.html#creating-breadcrumb-trails-with-htmlhelper
 */
	public function getCrumbList($options = array(), $startText = false) {
		$defaults = array('firstClass' => 'first', 'lastClass' => 'last', 'separator' => '', 'firstTag' => 'ul', 'secondTag' => 'li');
		$options = array_merge($defaults, (array)$options);
		$firstClass = $options['firstClass'];
		$lastClass = $options['lastClass'];
		$separator = $options['separator'];
		$firstTag = $options['firstTag'];
		$secondTag = $options['secondTag'];
		unset($options['firstClass'], $options['lastClass'], $options['separator'], $options['firstTag'], $options['secondTag']);

		$crumbs = $this->_prepareCrumbs($startText);
		if (empty($crumbs)) {
			return null;
		}

		$result = '';
		$crumbCount = count($crumbs);
		$ulOptions = $options;
		foreach ($crumbs as $which => $crumb) {
			$options = array();
			if (empty($crumb[1])) {
				$elementContent = $crumb[0];
			} else {
				$elementContent = $this->link($crumb[0], $crumb[1], $crumb[2]);
			}
			if (!$which && $firstClass !== false) {
				$options['class'] = $firstClass;
			} elseif ($which == $crumbCount - 1 && $lastClass !== false) {
				$options['class'] = $lastClass;
			}
			if (!empty($separator) && ($crumbCount - $which >= 2)) {
				$elementContent .= $separator;
			}
			$result .= $this->tag($secondTag, $elementContent, $options);
		}
		return $this->tag($firstTag, $result, $ulOptions);
	}

オプションに、firstTag' と 'secondTag を追加してタグを自由に設定出来るようにしただけです。これで、dl,ddのタグで出力出来るようになります。

が、やはりこれだけでもいまいちで
<dl id="breadList">
の id="breadList" の部分や
  <dt><a href="/">HOME</a></dt>
の dtのタグが再現できません。

なので、ちょっと強引ですが
echo $crumb ;
する前に
$crumb = str_replace('<dd><a href="/"><dt>HOME</dt></a></dd>', '<dt><a href="/">HOME</a></dt>', $crumb);
$crumb = str_replace('<dl>', '<dl id="breadList">', $crumb);
とかで文字列変換をかけてあげれば、とりあえず思い通りにできたりします。

でもまだまだこれだけだと、もともとbaserCMSのcrumbsメソッドは、404 not found になるようなURLとかはリンクを張らない仕様になっているのでそこの機能も追加

BcBaserHelper.phpに

 

/**
 * 表示していいURLかを判別
 *
 * @param string $url
 * @param string $options
 * @return boolean
 * @access public
 * @manual
 */
	public function isViewLink($url = null, $options = array()) {

		if (!is_array($options)) {
			$options = array($options);
		}

		$options = array_merge(array(
			'escape' => false,
			'prefix' => false,
			'forceTitle' => false,
			'ssl' => false
			), $options);

		/*		 * * beforeIsViewLink ** */
		$event = $this->dispatchEvent('beforeIsViewLink', array(
			'url' => $url,
			'options' => $options
			), array('class' => 'Html'));
		if ($event !== false) {
			$options = $event->result === true ? $event->data['options'] : $event->result;
		}

		if ($options['prefix']) {
			if (!empty($this->request->params['prefix']) && is_array($url)) {
				$url[$this->request->params['prefix']] = true;
			}
		}
		$forceTitle = $options['forceTitle'];
		$ssl = $options['ssl'];

		unset($options['prefix']);
		unset($options['forceTitle']);
		unset($options['ssl']);

		// 管理システムメニュー対策
		// プレフィックスが変更された場合も正常動作させる為
		// TODO メニューが廃止になったら削除
		if (!is_array($url)) {
			$prefixes = Configure::read('Routing.prefixes');
			$url = preg_replace('/^\/admin\//', '/' . $prefixes[0] . '/', $url);
		}

		$_url = $this->getUrl($url);
		$_url = preg_replace('/^' . preg_quote($this->request->base, '/') . '\//', '/', $_url);
		$enabled = true;

		if ($options == false) {
			$enabled = false;
		}

		// 認証チェック
		if (isset($this->Permission) && !empty($this->_View->viewVars['user']['user_group_id'])) {
			$userGroupId = $this->_View->viewVars['user']['user_group_id'];
			if (!$this->Permission->check($_url, $userGroupId)) {
				$enabled = false;
			}
		}

		// ページ公開チェック
		if (isset($this->Page) && empty($this->request->params['admin'])) {
			$adminPrefix = Configure::read('Routing.prefixes.0');
			if (isset($this->Page) && !preg_match('/^\/' . $adminPrefix . '/', $_url)) {
				if ($this->Page->isPageUrl($_url) && !$this->Page->checkPublish($_url)) {
					$enabled = false;
				}
			}
		}

		if (!$enabled) {
			//$forceTitleの値に問わず、false
			return false;
		}else{
			return true;
		}

	}


とそのリンク先が表示していいのかのメソッドを追加、ちなみにこのソースは、getLink メソッドの一部を抜粋したソースなので、可能なら getLinkメソッドからこちらを参照するように変更かけるのがただしいのだけど、検証があまいので今回はそのまま、いつか確認ができたら、本体にマージしたいところ。

あとは、crumbs.php (エレメントのファイル)を少し書き直してあげる。
43行目あたりの
                $this->BcBaser->addCrumb($crumb['name'], $crumb['url'], array());
の所を、
                if( $this->BcBaser->isViewLink($crumb['url'])){
                    $this->BcBaser->addCrumb($crumb['name'], $crumb['url'], array());
                } else {
                    $this->BcBaser->addCrumb($crumb['name'], '', array());
                }
として、利用可能なリンク先かどうかのチェックを追加しておわり。
 

baserCMS   2014/02/15   admin