From 4a7bd67199d1a123417c45e7b4c1d143f4ec879b Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Thu, 14 May 2015 22:20:17 +0930 Subject: [PATCH] New component for post excerpts, which will be shown in search results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Perhaps also in user activity stream. They are used in the mentions extension. In order to generate the excerpt, each formatter can implement a “strip” method which basically converts block formatting into inline formatting. --- .../js/forum/src/components/post-preview.js | 22 +++++++ framework/core/js/lib/models/post.js | 1 + framework/core/less/forum/discussion.less | 23 ++++++++ .../Api/Serializers/PostBasicSerializer.php | 2 +- .../src/Core/Formatter/FormatterManager.php | 59 +++++++++++-------- .../core/src/Core/Models/CommentPost.php | 20 +++++-- 6 files changed, 97 insertions(+), 30 deletions(-) create mode 100644 framework/core/js/forum/src/components/post-preview.js diff --git a/framework/core/js/forum/src/components/post-preview.js b/framework/core/js/forum/src/components/post-preview.js new file mode 100644 index 000000000..dbc84c6e8 --- /dev/null +++ b/framework/core/js/forum/src/components/post-preview.js @@ -0,0 +1,22 @@ +import Component from 'flarum/component'; +import avatar from 'flarum/helpers/avatar'; +import username from 'flarum/helpers/username'; +import humanTime from 'flarum/helpers/human-time'; + +export default class PostPreview extends Component { + view() { + var post = this.props.post; + var user = post.user(); + + return m('a.post-preview', { + href: app.route.post(post), + config: m.route, + onclick: this.props.onclick + }, m('div.post-preview-content', [ + avatar(user), ' ', + username(user), ' ', + humanTime(post.time()), ' ', + post.excerpt() + ])); + } +} diff --git a/framework/core/js/lib/models/post.js b/framework/core/js/lib/models/post.js index 5cb27fad8..0e5018277 100644 --- a/framework/core/js/lib/models/post.js +++ b/framework/core/js/lib/models/post.js @@ -12,6 +12,7 @@ Post.prototype.user = Model.one('user'); Post.prototype.contentType = Model.prop('contentType'); Post.prototype.content = Model.prop('content'); Post.prototype.contentHtml = Model.prop('contentHtml'); +Post.prototype.excerpt = Model.prop('excerpt'); Post.prototype.editTime = Model.prop('editTime', Model.date); Post.prototype.editUser = Model.one('editUser'); diff --git a/framework/core/less/forum/discussion.less b/framework/core/less/forum/discussion.less index 5fec2ecfa..5f3bc4c7f 100644 --- a/framework/core/less/forum/discussion.less +++ b/framework/core/less/forum/discussion.less @@ -338,6 +338,29 @@ } } +.post-preview { + color: @fl-body-muted-color; + padding-left: 50px; + line-height: 1.7em; + + & .avatar { + float: left; + margin-left: -50px; + .avatar-size(32px); + } + & .username { + color: @fl-body-color; + font-weight: bold; + margin-right: 5px; + } + & time { + margin-right: 5px; + text-transform: uppercase; + font-size: 11px; + font-weight: 600; + } +} + @media @phone { .post-header { & .avatar { diff --git a/framework/core/src/Api/Serializers/PostBasicSerializer.php b/framework/core/src/Api/Serializers/PostBasicSerializer.php index 66e0490e0..5d8cc6aa8 100644 --- a/framework/core/src/Api/Serializers/PostBasicSerializer.php +++ b/framework/core/src/Api/Serializers/PostBasicSerializer.php @@ -39,7 +39,7 @@ class PostBasicSerializer extends BaseSerializer ]; if ($post->type === 'comment') { - $attributes['content'] = str_limit($post->content, 200); + $attributes['excerpt'] = str_limit($post->contentPlain, 200); } else { $attributes['content'] = $post->content; } diff --git a/framework/core/src/Core/Formatter/FormatterManager.php b/framework/core/src/Core/Formatter/FormatterManager.php index 79510d098..4e746fff0 100644 --- a/framework/core/src/Core/Formatter/FormatterManager.php +++ b/framework/core/src/Core/Formatter/FormatterManager.php @@ -26,16 +26,6 @@ class FormatterManager public function add($name, $formatter, $priority = 0) { - $this->remove($name); - - if (is_string($formatter)) { - $formatter = function () use ($formatter) { - $callable = array($this->container->make($formatter), 'format'); - $data = func_get_args(); - return call_user_func_array($callable, $data); - }; - } - $this->formatters[$name] = [$formatter, $priority]; } @@ -44,23 +34,44 @@ class FormatterManager unset($this->formatters[$name]); } - public function format($text) + protected function getFormatters() + { + $sorted = []; + + foreach ($this->formatters as $array) { + list($formatter, $priority) = $array; + $sorted[$priority][] = $formatter; + } + + ksort($sorted); + + $result = []; + + foreach ($sorted as $formatters) { + $result = array_merge($result, $formatters); + } + + return $result; + } + + public function format($text, $post = null) { - $sorted = []; - - foreach ($this->formatters as $array) { - list($formatter, $priority) = $array; - $sorted[$priority][] = $formatter; - } - - ksort($sorted); - - foreach ($sorted as $formatters) { - foreach ($formatters as $formatter) { - $text = $formatter($text); - } + foreach ($this->getFormatters() as $formatter) { + $text = $this->container->make($formatter)->format($text, $post); } return $text; } + + public function strip($text) + { + foreach ($this->getFormatters() as $formatter) { + $formatter = $this->container->make($formatter); + if (method_exists($formatter, 'strip')) { + $text = $formatter->strip($text); + } + } + + return $text; + } } diff --git a/framework/core/src/Core/Models/CommentPost.php b/framework/core/src/Core/Models/CommentPost.php index 619d6bd0f..7d1bbf9de 100755 --- a/framework/core/src/Core/Models/CommentPost.php +++ b/framework/core/src/Core/Models/CommentPost.php @@ -35,7 +35,6 @@ class CommentPost extends Post $post = new static; $post->content = $content; - $post->content_html = static::formatContent($post->content); $post->time = time(); $post->discussion_id = $discussionId; $post->user_id = $userId; @@ -57,7 +56,7 @@ class CommentPost extends Post { if ($this->content !== $content) { $this->content = $content; - $this->content_html = static::formatContent($this->content); + $this->content_html = static::formatContent($this); $this->edit_time = time(); $this->edit_user_id = $user->id; @@ -113,13 +112,24 @@ class CommentPost extends Post public function getContentHtmlAttribute($value) { if (! $value) { - $this->content_html = $value = static::formatContent($this->content); + $this->content_html = $value = static::formatContent($this); $this->save(); } return $value; } + /** + * Get the content formatter as HTML. + * + * @param string $value + * @return string + */ + public function getContentPlainAttribute() + { + return static::$formatter->strip($this->content); + } + /** * Get text formatter instance. * @@ -146,8 +156,8 @@ class CommentPost extends Post * @param string $content * @return string */ - protected static function formatContent($content) + protected static function formatContent($post) { - return static::$formatter->format($content); + return static::$formatter->format($post->content, $post); } }