diff --git a/inc/config.php b/inc/config.php index ba435609..4a99011f 100644 --- a/inc/config.php +++ b/inc/config.php @@ -467,7 +467,7 @@ // Array('c', 'd', 'e', 'f', 'g'), // Array('h', 'i', 'j'), // Array('k', Array('l', 'm')), - // 'status' => 'http://status.example.org/' + // Array('status' => 'http://status.example.org/') //); // Categories diff --git a/inc/display.php b/inc/display.php index fc15c152..f544b88c 100644 --- a/inc/display.php +++ b/inc/display.php @@ -266,144 +266,9 @@ } public function build($index=false) { - global $board, $config, $memcached, $debug; + global $board, $config; - if(!$this->mod && $config['memcached']['enabled']) { - if($built = $memcached->get($this->memcached_key($index))) { - if($config['debug']) { - $debug['memcached'][] = $this->memcached_key($index); - } - return $built; - } - } - - $built = '
' . - '

' . - // Delete - '' - - // Poster ID - . ($config['poster_ids'] ? - ' ID: ' . poster_id($this->ip, $this->thread) - : '') - - . ' No.' . - // JavaScript cite - ''.$this->id.'' . - '

'; - - if($this->embed) { - // Embedded video (or something else; doesn't have to be a video really) - $built .= - // Actual embedding - $this->embed; - } elseif(!empty($this->file) && $this->file != 'deleted') { - // File info - $built .= '

' . - 'File: ' . $this->file . ' ' . - '(' . - ($this->thumb == 'spoiler' ? - 'Spoiler Image, ' - : '') . - // Filesize - format_bytes($this->filesize) . - // File dimensions - ($this->filex && $this->filey ? - ', ' . $this->filex . 'x' . $this->filey - : '' ); - // Aspect Ratio - if($config['show_ratio'] && $this->filex && $this->filey) { - $fraction = fraction($this->filex, $this->filey, ':'); - $built .= ', ' . $fraction; - } - if($config['show_filename']) { - // Filename - $built .= ', ' . - (strlen($this->filename) > $config['max_filename_display'] ? - '' . - substr($this->filename, 0, $config['max_filename_display']) . '…' . - '' - : - $this->filename - ); - } - - $ext = explode('.', $this->file); - $ext = $ext[1]; - $built .= ')

' . - - // Thumbnail - 'thumb == 'file' ? ' class="file"' : '') . - '>'; - } elseif($this->file == 'deleted') { - $built .= ''; - } - - $built .= $this->postControls(); - - // Body - $built .= '

' . ($index ? truncate($this->body, $this->link()) : $this->body) . '


'; - - if(!$this->mod && $config['memcached']['enabled']) { - $memcached->set($this->memcached_key($index), $built, time() + $config['memcached']['timeout']); - } - - return $built; - } - - function memcached_key($index) { - global $board; - return 'post_' . md5($this->body) . '_' . ($this->file ? $this->file : '-') . '_' . ($index ? 'index_' : '') . $board['uri'] . '_' . $this->id; + return Element('post_reply.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); } }; @@ -502,147 +367,34 @@ return $built; } + public function ratio() { + return fraction($this->filex, $this->filey, ':'); + } + public function build($index=false) { - global $board, $config; + global $board, $config, $memcached, $debug; - if($this->embed) { - // Embedded video (or something else; doesn't have to be a video really) - $built = - // Actual embedding - $this->embed; - } elseif(!empty($this->file) && $this->file != 'deleted') { - // File info - $built = '

' . - 'File: ' . $this->file . ' ' . - '(' . - ($this->thumb == 'spoiler' ? - 'Spoiler Image, ' - : '') . - // Filesize - format_bytes($this->filesize) . - // File dimensions - ($this->filex && $this->filey ? - ', ' . $this->filex . 'x' . $this->filey - : '' ); - // Aspect Ratio - if($config['show_ratio'] && $this->filex && $this->filey) { - $fraction = fraction($this->filex, $this->filey, ':'); - $built .= ', ' . $fraction; + if(!$this->mod && $config['memcached']['enabled']) { + if($built = $memcached->get($this->memcached_key($index))) { + if($config['debug']) { + $debug['memcached'][] = $this->memcached_key($index); + } + return $built; } - if($config['show_filename']) { - // Filename - $built .= ', ' . - (strlen($this->filename) > $config['max_filename_display'] ? - '' . - substr($this->filename, 0, $config['max_filename_display']) . '…' . - '' - : - $this->filename - ); - } - - $ext = explode('.', $this->file); - $ext = $ext[1]; - $built .= ')

' . - - // Thumbnail - 'thumb == 'file' ? ' class="file"' : '') . - '>'; - } elseif($this->file == 'deleted') { - $built = ''; } - $built .= '

'; + $built = Element('post_thread.html', Array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index)); - // Delete - $built .= '' - - // Poster ID - . ($config['poster_ids'] ? - ' ID: ' . poster_id($this->ip, $this->id) - : '') - - . ' No.' . - // JavaScript cite - ''.$this->id.'' . - // Sticky - ($this->sticky ? 'Sticky' : '') . - // Locked - ($this->locked ? 'Locked' : '') . - // [Reply] - ($index ? '[Reply]' : '') . - - // Mod controls - $this->postControls() . - '

'; - - // Body - $built .= '

' . ($index ? truncate($this->body, $this->link()) : $this->body) . '

' . - - // Omitted posts - ($this->omitted || $this->omitted_images? '' . - ($this->omitted ? - $this->omitted . ' post' . ($this->omitted==1?'':'s') . - ($this->omitted_images ? ' and ' : '') - :'') . - ($this->omitted_images ? - $this->omitted_images . ' image repl' . ($this->omitted_images==1?'y':'ies') - :'') . - ' omitted. Click reply to view.':'') . - - // End - '
'; - - // Replies - foreach($this->posts as &$post) { - $built .= $post->build($index); - } - - $built .= '
' . ($this->hr ? '
' : ''); return $built; } + function memcached_key($index) { + global $board; + + return 'thread_' . ($index ? 'index_' : '') . $board['uri'] . '_' . $this->id; + } }; ?> diff --git a/inc/functions.php b/inc/functions.php index 647aee1a..6046b681 100644 --- a/inc/functions.php +++ b/inc/functions.php @@ -732,16 +732,6 @@ while($th = $query->fetch()) { $thread = new Thread($th['id'], $th['subject'], $th['email'], $th['name'], $th['trip'], $th['capcode'], $th['body'], $th['time'], $th['thumb'], $th['thumbwidth'], $th['thumbheight'], $th['file'], $th['filewidth'], $th['fileheight'], $th['filesize'], $th['filename'], $th['ip'], $th['sticky'], $th['locked'], $th['embed'], $mod ? '?/' : $config['root'], $mod); - if($config['memcached']['enabled'] && !$mod) { - if($built = $memcached->get("threadindex_{$board['uri']}_{$th['id']}")) { - $body .= $built; - if($config['debug']) { - $debug['memcached'][] = "threadindex_{$board['uri']}_{$th['id']}"; - } - continue; - } - } - $posts = prepare(sprintf("SELECT * FROM `posts_%s` WHERE `thread` = :id ORDER BY `id` DESC LIMIT :limit", $board['uri'])); $posts->bindValue(':id', $th['id']); $posts->bindValue(':limit', ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']), PDO::PARAM_INT); @@ -771,10 +761,6 @@ $built = '
' . $thread->build(true) . '
'; - if($config['memcached']['enabled'] && !$mod) { - $memcached->set("threadindex_{$board['uri']}_{$th['id']}", $built, time() + $config['memcached']['timeout']); - } - $body .= $built; } @@ -1371,8 +1357,9 @@ $id = round($id); if($config['memcached']['enabled'] && !$mod) { - // Clear cache for index pages - $memcached->delete("threadindex_{$board['uri']}_{$id}"); + // Clear cache + $memcached->delete("thread_index_{$board['uri']}_{$id}"); + $memcached->delete("thread_{$board['uri']}_{$id}"); } $query = prepare(sprintf("SELECT * FROM `posts_%s` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri'])); diff --git a/inc/template.php b/inc/template.php index ed9e01f7..00cdbd36 100644 --- a/inc/template.php +++ b/inc/template.php @@ -6,8 +6,65 @@ } require 'contrib/Twig/Autoloader.php'; + Twig_Autoloader::register(); + class Tinyboard_Twig_Extension extends Twig_Extension { + public function getFilters() { + return Array( + 'filesize' => new Twig_Filter_Function('format_bytes', Array('needs_environment' => false)), + 'truncate' => new Twig_Filter_Function('twig_truncate_filter', array('needs_environment' => false)), + 'truncate_body' => new Twig_Filter_Function('truncate', array('needs_environment' => false)), + 'extension' => new Twig_Filter_Function('twig_extension_filter', array('needs_environment' => false)), + 'sprintf' => new Twig_Filter_Function('sprintf', array('needs_environment' => false)), + 'capcode' => new Twig_Filter_Function('capcode', array('needs_environment' => false)), + 'hasPermission' => new Twig_Filter_Function('twig_hasPermission_filter', array('needs_environment' => false)), + 'date' => new Twig_Filter_Function('twig_date_filter', array('needs_environment' => false)), + 'poster_id' => new Twig_Filter_Function('poster_id', array('needs_environment' => false)), + 'remove_whitespace' => new Twig_Filter_Function('twig_remove_whitespace_filter', array('needs_environment' => false)) + ); + } + public function getName() { + return 'tinyboard'; + } + } + + function twig_remove_whitespace_filter($data) { + return preg_replace('/[\t\r\n]/', '', $data); + } + + function twig_date_filter($date, $format) { + return date($format, $date); + } + + function twig_hasPermission_filter($mod, $permission, $board) { + return hasPermission($permission, $board, $mod); + } + + function twig_extension_filter($value, $case_insensitive = true) { + return 'test'; + $ext = substr($value, strrpos($value, '.') + 1); + if($case_insensitive) + $ext = strtolower($ext); + return $ext; + } + + function twig_sprintf_filter( $value, $var) { + return sprintf($value, $var); + } + + function twig_truncate_filter($value, $length = 30, $preserve = false, $separator = '…') { + if (strlen($value) > $length) { + if ($preserve) { + if (false !== ($breakpoint = strpos($value, ' ', $length))) { + $length = $breakpoint; + } + } + return substr($value, 0, $length) . $separator; + } + return $value; + } + $loader = new Twig_Loader_Filesystem($config['dir']['template']); function Element($templateFile, array $options) { @@ -28,9 +85,10 @@ $twig = new Twig_Environment($loader, Array( 'autoescape' => false, - //'cache' => 'cache', + 'cache' => 'templates/cache', 'debug' => ($config['debug'] ? true : false), )); + $twig->addExtension(new Tinyboard_Twig_Extension()); // Read the template file if(@file_get_contents("{$config['dir']['template']}/${templateFile}")) { diff --git a/templates/index.html b/templates/index.html index 6e978f2d..8cd21eb0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -137,7 +137,7 @@ {% if config.blotter %}
{{ config.blotter }}
{% endif %}
-
+ {% if mod %}{% endif %} {{ body }} diff --git a/templates/post_reply.html b/templates/post_reply.html new file mode 100644 index 00000000..a8ed151a --- /dev/null +++ b/templates/post_reply.html @@ -0,0 +1,98 @@ +{% filter remove_whitespace %} +{# tabs and new lines will be ignored #} +
+ +

+ + + {% if config.poster_ids %} + ID: {{ post.ip|poster_id(post.id) }} + {% endif %} + No. + + {{ post.id }} + + + {% if post.embed %} + {{ post.embed }} + {% elseif post.file == 'deleted' %} + + {% elseif post.file and post.file %} +

File: {{ post.file }} + ( + {% if post.thumb == 'spoiler' %} + Spoiler Image, + {% endif %} + {{ post.filesize|filesize }} + {% if post.filex and post.filey %} + , {{ post.filex}}x{{ post.filey }} + {% if config.show_ratio %} + , {{ post.ratio }} + {% endif %} + {% endif %} + {% if config.show_filename %} + , + {% if post.filename|length > config.max_filename_display %} + {{ post.filename|truncate(config.max_filename_display) }} + {% else %} + {{ post.filename }} + {% endif %} + {% endif %} + ) +

+ + + {% endif %} + + {{ post.postControls }} +

+ {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %} +

+
+
+{% endfilter %} diff --git a/templates/post_thread.html b/templates/post_thread.html new file mode 100644 index 00000000..6caff826 --- /dev/null +++ b/templates/post_thread.html @@ -0,0 +1,128 @@ +{% filter remove_whitespace %} +{# tabs and new lines will be ignored #} + +{% if post.embed %} + {{ post.embed }} +{% elseif post.file == 'deleted' %} + +{% elseif post.file and post.file %} +

File: {{ post.file }} + ( + {% if post.thumb == 'spoiler' %} + Spoiler Image, + {% endif %} + {{ post.filesize|filesize }} + {% if post.filex and post.filey %} + , {{ post.filex}}x{{ post.filey }} + {% if config.show_ratio %} + , {{ post.ratio }} + {% endif %} + {% endif %} + {% if config.show_filename %} + , + {% if post.filename|length > config.max_filename_display %} + {{ post.filename|truncate(config.max_filename_display) }} + {% else %} + {{ post.filename }} + {% endif %} + {% endif %} + ) +

+ + +{% endif %} +

+ + + {% if config.poster_ids %} + ID: {{ post.ip|poster_id(post.id) }} + {% endif %} + No. + + {{ post.id }} + + {% if post.sticky %} + Sticky + {% endif %} + {% if post.locked %} + Locked + {% endif %} + {% if index %} + [Reply] + {% endif %} + {{ post.postControls }} +

+ {% endfilter %}{% if index %}{{ post.body|truncate_body(post.link) }}{% else %}{{ post.body }}{% endif %}{% filter remove_whitespace %} +

+ {% if post.omitted or post.omitted_images %} + + {% if post.omitted %} + {{ post.omitted }} post + {% if post.omitted != 1 %} + s + {% endif %} + {% if post.omitted_images %} + and + {% endif %} + {% endif %} + {% if post.omitted_images %} + {{ post.omitted_images }} image repl + {% if post.omitted_images == 1 %} + y + {% else %} + ies + {% endif %} + {% endif %} omitted. Click reply to view. + + {% endif %} +
{% endfilter %} +{% for post in post.posts %} + {% include 'post_reply.html' %} +{% endfor %} +
{% if post.hr %}
{% endif %} + diff --git a/templates/thread.html b/templates/thread.html index 047cd201..6884d817 100644 --- a/templates/thread.html +++ b/templates/thread.html @@ -130,7 +130,7 @@ {% if config.blotter %}
{{ config.blotter }}
{% endif %}
- + {% if mod %}{% endif %} {{ body }}