Commit 479924d2 authored by Richard Mansfield's avatar Richard Mansfield
Browse files

Rewrite blog pagination to use templates and not tablerenderer.js


Signed-off-by: default avatarRichard Mansfield <richardm@catalyst.net.nz>
parent c92d63e5
......@@ -31,5 +31,6 @@ $string['title'] = 'Blog';
$string['description'] = 'Display an entire blog';
$string['defaulttitledescription'] = 'If you leave this blank, the title of the blog will be used';
$string['postsperpage'] = 'Posts per page';
?>
......@@ -71,10 +71,36 @@ class PluginBlocktypeBlog extends PluginBlocktype {
$configdata['before'] = $submittedtime;
}
}
$result = $blog->render_self($configdata);
$result = $result['html'] . '<script type="text/javascript">'
. $result['javascript'];
$result .= '</script>';
$limit = isset($configdata['count']) ? intval($configdata['count']) : 5;
$posts = ArtefactTypeBlogpost::get_posts($blog->get('id'), $limit, 0, $configdata);
$template = 'artefact:blog:viewposts.tpl';
$pagination = array(
'baseurl' => $instance->get_view()->get_url() . '&block=' . $instance->get('id'),
'id' => 'blogpost_pagination_' . $instance->get('id'),
'datatable' => 'postlist_' . $instance->get('id'),
'jsonscript' => 'artefact/blog/posts.json.php',
);
ArtefactTypeBlogpost::render_posts($posts, $template, $configdata, $pagination);
$smarty = smarty_core();
if (isset($configdata['viewid'])) {
$smarty->assign('artefacttitle', '<a href="' . get_config('wwwroot') . 'view/artefact.php?artefact='
. $blog->get('id') . '&view=' . $configdata['viewid']
. '">' . hsc($blog->get('title')) . '</a>');
}
else {
$smarty->assign('artefacttitle', hsc($blog->get('title')));
}
$smarty->assign('options', $configdata);
$smarty->assign('description', $blog->get('description'));
$smarty->assign('owner', $blog->get('owner'));
$smarty->assign('tags', $blog->get('tags'));
$smarty->assign('blockid', $instance->get('id'));
$smarty->assign('posts', $posts);
$result = $smarty->fetch('artefact:blog:blog.tpl');
}
return $result;
......@@ -105,6 +131,12 @@ class PluginBlocktypeBlog extends PluginBlocktype {
// blogs
if (empty($configdata['artefactid']) || $blog->get('owner') == $USER->get('id')) {
$elements[] = self::artefactchooser_element((isset($configdata['artefactid'])) ? $configdata['artefactid'] : null);
$elements['count'] = array(
'type' => 'text',
'title' => get_string('postsperpage', 'blocktype.blog/blog'),
'defaultvalue' => isset($configdata['count']) ? $configdata['count'] : 5,
'size' => 3,
);
$elements[] = PluginArtefactBlog::block_advanced_options_element($configdata, 'blog');
}
else {
......
{if !$options.hidetitle}<h2>{$artefacttitle|safe}</h2>{/if}
{$description|clean_html|safe}
{if $tags}<div class="tags">{str tag=tags}: {list_tags owner=$owner tags=$tags}</div>{/if}
{foreach from=$postdata item=post}
{$post.content.html|safe}
{/foreach}
{if $newerpostslink || $olderpostslink}
<div class="blog-pagination">
{if $olderpostslink}<div class="fr"><a href="{$olderpostslink}">{str tag=olderposts section=artefact.blog}</a></div>{/if}
{if $newerpostslink}<div><a href="{$newerpostslink}">{str tag=newerposts section=artefact.blog}</a></div>{/if}
</div>
{/if}
......@@ -196,11 +196,7 @@ class ArtefactTypeBlog extends ArtefactType {
}
/**
* Renders a blog for a view. This involves using a tablerenderer to paginate the posts.
*
* This uses some legacy stuff from the old views interface, including its
* dependence on javascript and the table renderer, which would be nice to
* fix using the new pagination stuff some time.
* Renders a blog.
*
* @param array Options for rendering
* @return array A two key array, 'html' and 'javascript'.
......@@ -208,6 +204,31 @@ class ArtefactTypeBlog extends ArtefactType {
public function render_self($options) {
$this->add_to_render_path($options);
if (!isset($options['limit'])) {
$limit = self::pagination;
}
else if ($options['limit'] === false) {
$limit = null;
}
else {
$limit = (int) $options['limit'];
}
$offset = isset($options['offset']) ? intval($options['offset']) : 0;
$posts = ArtefactTypeBlogpost::get_posts($this->id, $limit, $offset, $options);
$template = 'artefact:blog:viewposts.tpl';
$baseurl = get_config('wwwroot') . 'view/artefact.php?artefact=' . $this->id . '&view=' . $options['viewid'];
$pagination = array(
'baseurl' => $baseurl,
'id' => 'blogpost_pagination',
'datatable' => 'postlist',
'jsonscript' => 'artefact/blog/posts.json.php',
);
ArtefactTypeBlogpost::render_posts($posts, $template, $options, $pagination);
$smarty = smarty_core();
if (isset($options['viewid'])) {
$smarty->assign('artefacttitle', '<a href="' . get_config('wwwroot') . 'view/artefact.php?artefact='
......@@ -218,63 +239,15 @@ class ArtefactTypeBlog extends ArtefactType {
$smarty->assign('artefacttitle', hsc($this->get('title')));
}
$options['hidetitle'] = true;
$smarty->assign('options', $options);
$smarty->assign('description', $this->get('description'));
$smarty->assign('owner', $this->get('owner'));
$smarty->assign('tags', $this->get('tags'));
// Remove unnecessary options for blog posts
unset($options['hidetitle']);
$page = (isset($options['page'])) ? abs(intval($options['page'])) : abs(param_integer('page', 1));
$offset = $page ? $page * self::pagination - self::pagination : 1;
$smarty->assign_by_ref('posts', $posts);
$before = isset($options['before']) ? "a.ctime < '{$options['before']}'" : 'TRUE';
$from ="FROM {artefact} a
LEFT JOIN {artefact_blog_blogpost} bp ON a.id = bp.blogpost
WHERE a.parent = ? AND $before
AND bp.published = 1";
$postcount = get_field_sql("
SELECT COUNT(*) $from",
array($this->get('id'))
);
$postids = get_column_sql("
SELECT a.id
$from
ORDER BY a.ctime DESC
LIMIT ? OFFSET ?",
array($this->get('id'), self::pagination, $offset)
);
$data = array();
foreach($postids as $postid) {
$blogpost = new ArtefactTypeBlogPost($postid);
$data[] = array(
'id' => $postid,
'content' => $blogpost->render_self($options)
);
}
$smarty->assign('postdata', $data);
// Pagination
if ($postcount > self::pagination) {
$baselink = get_config('wwwroot') . 'view/artefact.php?artefact=' . $this->get('id');
if (isset($options['viewid'])) {
$baselink .= '&view=' . $options['viewid'];
}
if ($offset + self::pagination < $postcount) {
$smarty->assign('olderpostslink', $baselink . '&page=' . ($page + 1));
}
if ($offset > 0) {
$smarty->assign('newerpostslink', $baselink . '&page=' . ($page - 1));
}
}
return array('html' => $smarty->fetch('blocktype:blog:blog_render_self.tpl'), 'javascript' => '');
return array('html' => $smarty->fetch('artefact:blog:blog.tpl'), 'javascript' => '');
}
......@@ -602,82 +575,118 @@ class ArtefactTypeBlogPost extends ArtefactType {
* @param integer
* @param integer
* @param integer
* @param boolean
* @param array
*/
public static function get_posts($id, $limit, $offset, $editing=false) {
($result = get_records_sql_assoc("
SELECT a.id, a.title, a.description, " . db_format_tsfield('a.ctime', 'ctime') . ', ' . db_format_tsfield('a.mtime', 'mtime') . ", a.locked, bp.published
FROM {artefact} a
LEFT OUTER JOIN {artefact_blog_blogpost} bp
ON a.id = bp.blogpost
WHERE a.parent = ?
AND a.artefacttype = 'blogpost'
ORDER BY bp.published ASC, a.ctime DESC
LIMIT ? OFFSET ?;", array(
$id,
$limit,
$offset
)))
|| ($result = array());
public static function get_posts($id, $limit, $offset, $viewoptions=null) {
$count = count_records('artefact', 'artefacttype', 'blogpost', 'parent', $id);
$results = array(
'limit' => $limit,
'offset' => $offset,
);
if (count($result) > 0) {
// Get the attached files.
$files = ArtefactType::attachments_from_id_list(array_map(create_function('$a', 'return $a->id;'), $result));
if ($files) {
safe_require('artefact', 'file');
foreach ($files as &$file) {
$file->icon = call_static_method(generate_artefact_class_name($file->artefacttype), 'get_icon', array('id' => $file->attachment));
$result[$file->artefact]->files[] = $file;
}
// If viewoptions is null, we're getting posts for the my blogs area,
// and we should get all posts & show drafts first. Otherwise it's a
// blog in a view, and we should only get published posts.
$from = "
FROM {artefact} a LEFT JOIN {artefact_blog_blogpost} bp ON a.id = bp.blogpost
WHERE a.artefacttype = 'blogpost' AND a.parent = ?";
if (!is_null($viewoptions)) {
if (isset($viewoptions['before'])) {
$from .= " AND a.ctime < '{$viewoptions['before']}'";
}
$from .= ' AND bp.published = 1';
}
// Format dates properly
foreach ($result as &$post) {
$post->ctime = format_date($post->ctime, 'strftimedaydatetime');
$post->mtime = format_date($post->mtime);
if ($editing) {
if (!$post->published) {
$post->publish = ArtefactTypeBlogpost::publish_form($post->id);
}
$post->delete = ArtefactTypeBlogpost::delete_form($post->id);
$results['count'] = count_records_sql('SELECT COUNT(*) ' . $from, array($id));
$data = get_records_sql_assoc('
SELECT
a.id, a.title, a.description, a.author, a.authorname, ' .
db_format_tsfield('a.ctime', 'ctime') . ', ' . db_format_tsfield('a.mtime', 'mtime') . ",
a.locked, bp.published" . $from . '
ORDER BY bp.published ASC, a.ctime DESC',
array($id),
$offset, $limit
);
if (!$data) {
$results['data'] = array();
return $results;
}
// Get the attached files.
$postids = array_map(create_function('$a', 'return $a->id;'), $data);
$files = ArtefactType::attachments_from_id_list($postids);
if ($files) {
safe_require('artefact', 'file');
foreach ($files as &$file) {
$file->icon = call_static_method(generate_artefact_class_name($file->artefacttype), 'get_icon', array('id' => $file->attachment));
$data[$file->artefact]->files[] = $file;
}
}
if ($tags = ArtefactType::tags_from_id_list($postids)) {
foreach($tags as &$at) {
$data[$at->artefact]->tags[] = $at->tag;
}
}
// Format dates properly
foreach ($data as &$post) {
if (is_null($viewoptions)) {
// My Blogs area: create forms for publishing & deleting posts.
if (!$post->published) {
$post->publish = ArtefactTypeBlogpost::publish_form($post->id);
}
$post->delete = ArtefactTypeBlogpost::delete_form($post->id);
}
else {
$by = $post->author ? display_default_name($post->author) : $post->authorname;
$post->postedby = get_string('postedbyon', 'artefact.blog', $by, format_date($post->ctime));
}
$post->ctime = format_date($post->ctime, 'strftimedaydatetime');
$post->mtime = format_date($post->mtime);
}
return array(
'count' => $count,
'data' => array_values($result),
'limit' => $limit,
'offset' => $offset,
);
$results['data'] = array_values($data);
return $results;
}
public function render_posts(&$posts, $blog=null) {
/**
* This function renders a list of posts as html
*
* @param array posts
* @param string template
* @param array options
* @param array pagination
*/
public function render_posts(&$posts, $template, $options, $pagination) {
$smarty = smarty_core();
$smarty->assign('options', $options);
$smarty->assign('posts', $posts['data']);
$posts['tablerows'] = $smarty->fetch('artefact:blog:posts.tpl');
$baseurl = get_config('wwwroot') . 'artefact/blog/view';
if ($blog) {
$baseurl .= '/index.php?id=' . $blog;
$posts['tablerows'] = $smarty->fetch($template);
if ($posts['limit']) {
$pagination = build_pagination(array(
'id' => $pagination['id'],
'class' => 'center',
'datatable' => $pagination['datatable'],
'url' => $pagination['baseurl'],
'jsonscript' => $pagination['jsonscript'],
'count' => $posts['count'],
'limit' => $posts['limit'],
'offset' => $posts['offset'],
'numbersincludefirstlast' => false,
'resultcounttextsingular' => get_string('post', 'artefact.blog'),
'resultcounttextplural' => get_string('posts', 'artefact.blog'),
));
$posts['pagination'] = $pagination['html'];
$posts['pagination_js'] = $pagination['javascript'];
}
$pagination = build_pagination(array(
'id' => 'blogpost_pagination',
'class' => 'center',
'datatable' => 'postlist',
'url' => $baseurl,
'jsonscript' => 'artefact/blog/view/index.json.php',
'count' => $posts['count'],
'limit' => $posts['limit'],
'offset' => $posts['offset'],
'numbersincludefirstlast' => false,
'resultcounttextsingular' => get_string('post', 'artefact.blog'),
'resultcounttextplural' => get_string('posts', 'artefact.blog'),
));
$posts['pagination'] = $pagination['html'];
$posts['pagination_js'] = $pagination['javascript'];
}
/**
......
<?php
/**
* Mahara: Electronic portfolio, weblog, resume builder and social networking
* Copyright (C) 2006-2009 Catalyst IT Ltd and others; see:
* http://wiki.mahara.org/Contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package mahara
* @subpackage artefact-blog
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL
* @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz
*
*/
define('INTERNAL', 1);
define('JSON', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
safe_require('artefact', 'blog');
require_once(get_config('docroot') . 'blocktype/lib.php');
require_once(get_config('docroot') . 'artefact/blog/blocktype/blog/lib.php');
$offset = param_integer('offset', 0);
if ($blockid = param_integer('block', null)) {
$bi = new BlockInstance($blockid);
$configdata = $bi->get('configdata');
$limit = isset($configdata['count']) ? $configdata['count'] : 5;
$posts = ArtefactTypeBlogpost::get_posts($configdata['artefactid'], $limit, $offset, $configdata);
$template = 'artefact:blog:viewposts.tpl';
$pagination = array(
'baseurl' => $bi->get_view()->get_url() . '&block=' . $blockid,
'id' => 'blogpost_pagination_' . $blockid,
'datatable' => 'postlist_' . $blockid,
'jsonscript' => 'artefact/blog/posts.json.php',
);
$configdata['viewid'] = $bi->get('view');
ArtefactTypeBlogpost::render_posts($posts, $template, $configdata, $pagination);
}
else {
// No block, we're just rendering the blog by itself on view/artefact.php
$limit = param_integer('limit', ArtefactTypeBlog::pagination);
$blogid = param_integer('artefact');
$viewid = param_integer('view');
$options = array('viewid' => $viewid);
$posts = ArtefactTypeBlogpost::get_posts($blogid, $limit, $offset, $options);
$template = 'artefact:blog:viewposts.tpl';
$baseurl = get_config('wwwroot') . 'view/artefact.php?artefact=' . $blogid . '&view=' . $viewid;
$pagination = array(
'baseurl' => $baseurl,
'id' => 'blogpost_pagination',
'datatable' => 'postlist',
'jsonscript' => 'artefact/blog/posts.json.php',
);
ArtefactTypeBlogpost::render_posts($posts, $template, $options, $pagination);
}
json_reply(false, array('data' => $posts));
?>
{if !$options.hidetitle}
<h2>{$artefacttitle|safe}</h2>
{/if}
{$description|clean_html|safe}
{if $tags}<div class="tags">{str tag=tags}: {list_tags owner=$owner tags=$tags}</div>{/if}
<table id="postlist_{$blockid}" class="postlist">
<tbody>
{$posts.tablerows|safe}
</tbody>
</table>
<div id="blogpost_page_container_{$blockid}" class="hidden center">{$posts.pagination|safe}</div>
<script>
addLoadEvent(function() {literal}{{/literal}
{$posts.pagination_js|safe}
removeElementClass('blogpost_page_container_{$blockid}', 'hidden');
{literal}}{/literal});
</script>
{foreach from=$posts item=post}
<tr>
<td>
<h3><a href="{$WWWROOT}view/artefact.php?artefact={$post->id}&view={$options.viewid}">{$post->title}</a></h3>
<div>{$post->description|clean_html|safe}</div>
{if $post->tags}
<div class="tags">{str tag=tags}: {list_tags owner=$post->owner tags=$post->tags}</div>
{/if}
{if $post->files}
<table class="cb attachments fullwidth">
<tbody>
<tr><th>{str tag=attachedfiles section=artefact.blog}:</th></tr>
{foreach from=$post->files item=file}
<tr class="{cycle values='r0,r1'}">
<td>
<a href="{$WWWROOT}view/artefact.php?artefact={$file->attachment}&view={$options.viewid}">{$file->title}</a>
({$file->size|display_size})
- <strong><a href="{$WWWROOT}artefact/file/download.php?file={$file->attachment}">{str tag=Download section=artefact.file}</a></strong>
</td>
</tr>
{/foreach}
</tbody>
</table>
{/if}
<div class="postdetails">{$post->postedby}</div>
</td>
</tr>
{/foreach}
......@@ -36,8 +36,15 @@ $id = param_integer('id');
$limit = param_integer('limit', 5);
$offset = param_integer('offset', 0);
$posts = ArtefactTypeBlogPost::get_posts($id, $limit, $offset, true);
ArtefactTypeBlogPost::render_posts($posts, $id);
$posts = ArtefactTypeBlogPost::get_posts($id, $limit, $offset);
$template = 'artefact:blog:posts.tpl';
$pagination = array(
'baseurl' => get_config('wwwroot') . 'artefact/blog/view/index.php?id=' . $id,
'id' => 'blogpost_pagination',
'jsonscript' => 'artefact/blog/view/index.json.php',
'datatable' => 'postlist',
);
ArtefactTypeBlogPost::render_posts($posts, $template, array(), $pagination);
json_reply(false, array('data' => $posts));
?>
......@@ -63,10 +63,16 @@ $blog->check_permission();
$limit = param_integer('limit', 5);
$offset = param_integer('offset', 0);
$editing = true;
$posts = ArtefactTypeBlogPost::get_posts($id, $limit, $offset, $editing);
ArtefactTypeBlogPost::render_posts($posts, $id);
$posts = ArtefactTypeBlogPost::get_posts($id, $limit, $offset);
$template = 'artefact:blog:posts.tpl';
$pagination = array(
'baseurl' => get_config('wwwroot') . 'artefact/blog/view/index.php?id=' . $id,
'id' => 'blogpost_pagination',
'jsonscript' => 'artefact/blog/view/index.json.php',
'datatable' => 'postlist',
);
ArtefactTypeBlogPost::render_posts($posts, $template, array(), $pagination);
$strpublished = json_encode(get_string('published', 'artefact.blog'));
$js = <<<EOF
......
......@@ -992,6 +992,18 @@ abstract class ArtefactType {
return $attachments;
}
public function tags_from_id_list($artefactids) {
if (empty($artefactids)) {
return array();
}
$artefactids = join(',', array_map('intval', $artefactids));
$tags = get_records_select_array('artefact_tag', 'artefact IN (' . $artefactids . ')');
if (!$tags) {
return array();
}
return $tags;
}
public function get_attachments($assoc=false) {
$list = get_records_sql_assoc('SELECT a.id, a.artefacttype, a.title, a.description
FROM {artefact_attachment} aa
......
......@@ -308,6 +308,10 @@ html>body #column-container {
font-weight: bold;
}
.blockinstance-content table.postlist td {
padding: 0;
}
/* group homepage */
.grouphomepage {
width: 100%;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment