CakePHP1.2 RC3
ブログの記事など長い文章を一覧で表示するようなページにおいて、「続きを読む」のようなリンクを付けたいことがあると思います。
特定の文字数で文章をカットしてくれるヘルパーがText::truncate()に用意されています。
今回はそれをアレンジして、「続きを読む」リンクを作成してみます。
cake/libs/views/helpers/text.php を app/views/helpers/text.php にコピーします。
そして、truncate メソッドを真似して、truncateJp メソッドを作成します(ほとんど truncate メッソドのままです)。
function truncateJp($text, $length = 100, $ending = '…', $endingOptions = array(), $exact = true, $considerHtml = false) {
if (is_array($ending)) {
extract($ending);
}
if ($considerHtml) {
if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
return $text;
}
$totalLength = mb_strlen($ending);
$openTags = array();
$truncate = '';
preg_match_all('/(<\\/?([\\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
foreach ($tags as $tag) {
if (preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
} else if (preg_match('/<[\\w]+[^>]*>/s', $tag[0])) {
array_unshift($openTags, $tag[2]);
} else if (preg_match('/<\\/([\\w]+)[^>]*>/s', $tag[0], $closeTag)) {
$pos = array_search($closeTag[1], $openTags);
if ($pos !== false) {
array_splice($openTags, $pos, 1);
}
}
$truncate .= $tag[1];
$contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
if ($contentLength + $totalLength > $length) {
$left = $length - $totalLength;
$entitiesLength = 0;
if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
foreach ($entities[0] as $entity) {
if ($entity[1] + 1 - $entitiesLength <= $left) {
$left--;
$entitiesLength += mb_strlen($entity[0]);
} else {
break;
}
}
}
$truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
break;
} else {
$truncate .= $tag[3];
$totalLength += $contentLength;
}
if ($totalLength >= $length) {
break;
}
}
} else {
if (mb_strlen($text) <= $length) {
return $text;
} else {
$truncate = mb_substr($text, 0, $length - mb_strlen($ending));
}
}
if (!$exact) {
$spacepos = strrpos($truncate, ' ');
if (isset($spacepos)) {
if ($considerHtml) {
$bits = mb_substr($truncate, $spacepos);
preg_match_all('/<\\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
if (!empty($droppedTags)) {
foreach ($droppedTags as $closingTag) {
if (!in_array($closingTag[1], $openTags)) {
array_unshift($openTags, $closingTag[1]);
}
}
}
}
$truncate = mb_substr($truncate, 0, $spacepos);
}
}
if (!empty($endingOptions)) {
$Html = new HtmlHelper();
$url = '';
if (isset($endingOptions['url'])) {
$url = $endingOptions['url'];
}
$option = array();
if (isset($endingOptions['target'])) {
$option['target'] = $endingOptions['target'];
}
$truncate .= ' ' . $Html->link($ending, $url, $option);
} else {
$truncate .= $ending;
}
if ($considerHtml) {
foreach ($openTags as $tag) {
$truncate .= '</'.$tag.'>';
}
}
return $truncate;
}
そして、View に下記のように書きます。
<?php e($text->truncateJp($value, 200, '続きを読む', array('url' => $url, 'target' => '_blank'))); ?>
これで「続きを読む」にリンクが張られた状態で表示できます。
truncateJp のオプション説明
第1引数:文章
第2引数:表示させたい全角文字数 - 1
第3引数:「続きを読む」のような文字
第4引数(array):url=>URL、target=>ターゲット先
この投稿への コメント/トラックバック はまだありません...

CakePHPに関する情報をまとめていきます。
開発スピードがアップできればうれしいです。
>>連絡はこちらへどうぞ
CakePHP関連のブックマーク
CakePHP最新版
CakePHP 1.2.3.8166
CakePHPの書籍
CakePHPによる実践Webアプリケーション開発
![]()
CakePHP1.2で作成する人にオススメ。
とても参考になります。
まるごとPHP!(vol.2)
![]()
安藤さんの解説が載っています。
AmazonのPagination部分は参考になります。
CakePHPによるWebアプリケーション開発
![]()
まだ読んだことありません
CakePHPポケットリファレンス![]()
CakePHP1.2 でやるなら、これがあると何かと便利♪
CakePHP徹底入門![]()
CakePHP1.2 を今から始めるならここから
Fast CakePHP![]()
シンプルでわかりやすい CakePHP の入門書
CakePHPガイドブック![]()
CakePHP1.1 ではとても参考にした CakePHP 最初の入門書