立即注册 登录
彼岸网 返回首页

天香公主的个人空间 https://www.bian-wang.com/discuz/?10005 [收藏] [复制] [分享] [RSS] https://github.com/txgz999/discuz/wiki

日志

支持显示多图的DIY模块

热度 2已有 772 次阅读2019-3-31 07:48 PM |个人分类:Discuz

Discuz提供了强大的聚合功能,网站里发布的文章日志记录和帖子里的内容都可以通过DIY模块来聚合起来集中显示。聚合起来的内容存放在单独的缓存数表里便于快速显示。但是聚合时提取的内容只是原来内容的一部分,有时会出现想要在DIY模块里显示的内容没在聚合内容里的情形。我们能不能把它们加到聚合内容里去呢?比如有些日志里有很多照片或图片,但聚合时则只能选取一张。有没有可能把日志里所有的图片都显示在DIY模块里呢?这就是本文要讨论的主题。


日志模块的组图显示
1. 首先要修改模块文件source/class/block/space/space_blog.php
1.1 把图片列加到要显示的成员名单里去:在函数fields里下面这行'click8' => array('name' => lang('blockclass', 'blockclass_blog_field_click8'), 'formtype' => 'text', 'datatype' => 'int'),后添加 'piclist' => array('name' => lang('blockclass', 'blockclass_blog_field_piclist'), 'formtype' => 'text', 'datatype' => 'string'), 1.2 在从日志里提取聚合内容时获取日志里所有的图片:在函数getdata里的下面这行'click8'=>$data['click8'],后添加 'piclist'=>implode('|', $this->getpiclist($data['message'])), 这里使用了接下来要引入的函数getpiclist来得到日志里的图片地址列,然后用分隔符将它们合并成一个字符串便于存放在缓存数表里。
1.3 添加上面用到的函数getpiclist的定义: function getpiclist($message) { $piclist = array(); if (!empty($message)) { require_once libfile('function/blog'); $message = blog_bbcode($message); /* include the following two lines only if the site uses the one-key-post feature explained in http://www.bian-wang.com/discuz/home.php?mod=space&uid=10005&do=blog&id=1486 */ require_once libfile('function/url2html'); $message = url2html($message, 0); preg_match_all("/\s*\<img src=[\"\'](.+?)[\"\'].*?\>\s*/is", $message, $matches); if(!empty($matches[1])) { foreach ($matches[1] as $value) { $piclist[] = $value; } } } return $piclist; } 上面函数里有两行只在使用一键贴(链接)的网站里才需要使用。

2. 组图模板
聚合数据里有了图片列信息后,还需要有个模块模板将它显示出来。显示的办法有多种,比如可以将所有图片排成一行滚动显示,又如可以堆起来幻灯显示。下面讨论的办法是将图片从左往右再从上往下一一展示。在管理中心的门户->模块模板里添加一个关于日志模块的模板: <div class="module cl xld"> [loop] <div style="text-align: center; font-weight: bold; font-size: 18px; margin-bottom: 4px;"> <em>< a href="home.php?mod=space&uid={uid}"{target}>{username}</a>:< a href="{url}"{target}>{title}</a></em> </div> <div class="gallery"> <div class="item-template" data="{piclist}"> < a href="{url}"{target}><img></a></div> </div> <script> setGallery('gallery', 0, {picheight}); </script> [/loop] </div> 模板定义里用到的函数setGallery将在下面定义,它接受三个参数:
  • classname:容纳显示的组图容器元素的类名
  • rows:图片最多显示行数,超过部分不显示。如果值为零代表对行数没限制
  • picheight:每行的高度

3. 组图显示的客户端支持
图片列是在一个字符串里,要想显示在网页上需要有javascript代码的支持。在文件static/js/common.js里加入下面的内容: function _randomInteger() { return Math.random().toString(36).substring(2); } // https://www.htmlgoodies.com/beyond/javascript/article.php/3724571/Using-Multiple-JavaScript-Onload-Functions.htm function _addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function () { if (oldonload) { oldonload(); } func(); } } } // classname: class name of the container element to display images // rows: maximum rows to display, 0 means no limit // picheight: image display height, 0 means use the original image height function setGallery(classname, rows, picheight) { var gallery = $C(classname); for (var i = 0; i < gallery.length; i++) { _setGallery(gallery[i], rows, picheight); } } function _setGallery(el, rows, picheight) { if (el.id) return; el.id = 'g' + _randomInteger(); el.style.position = 'relative'; el.style.overflow = 'hidden'; el.style.height = '10px'; var mainpiclist = []; var items = $C('item-template', el); for (var i = 0; i < items.length; i++) { var item = items[i]; var piclist = item.getAttribute('data').split('|'); item.style.display = 'none'; item.removeAttribute('data'); for (var j = 0; j < piclist.length; j++) { var pic = piclist[j]; if (!pic) continue; if (mainpiclist.indexOf(pic.toUpperCase()) >= 0) continue; mainpiclist.push(pic.toUpperCase()); var nitem = item.cloneNode(true); nitem.style.display = ''; nitem.className = 'item'; nitem.style.position = 'absolute'; nitem.style.visibility = 'hidden'; el.appendChild(nitem); var nimg = nitem.getElementsByTagName('img')[0]; nimg.src = pic; } } _addLoadEvent(function () { var tw = el.offsetWidth; var th = 0; var rw = 0; var gutter = 10; var row = 0; var list = []; var mth = 0; var items = $C('item', el); for (i = 0; i < items.length; i++) { var item = items[i]; item.style.visibility = 'visible'; var img = item.getElementsByTagName('img')[0]; var ih = img.offsetHeight; var iw = img.offsetWidth; if (!picheight) picheight = ih; if (ih < picheight) { img.style.height = '0px'; img.style.width = '0px'; } else { if (rw == 0) { th += picheight + gutter; if (!rows || row < rows) mth = th; } list.push(item); img.style.height = picheight + 'px'; iw *= picheight / ih; img.style.width = iw + 'px'; item.style.left = rw + 'px'; item.style.top = (th - picheight) + 'px'; rw += iw + gutter; if (rw >= tw) { var c = list.length; ratio = (tw - (c - 1) * gutter) / (rw - (c - 1) * gutter); for (j = 0; j < list.length; j++) { var item = list[j]; var img = item.getElementsByTagName('img')[0]; img.style.height = (img.offsetHeight * ratio) + 'px'; img.style.width = (img.offsetWidth * ratio) + 'px'; item.style.left = ((parseInt(item.style.left) - j * gutter) * ratio + j * gutter) + 'px'; }; th -= (1 - ratio) * picheight; if (!rows || row < rows) mth = th; row++; rw = 0; list = []; } } } el.style.height = (mth + gutter) + 'px'; }); } 这些代码里含有两个考量:
  • 日志里常会有些小图片如表情图片,它们应该排除在组图显示里,所以在代码里我们去掉了图片高度小于规定的显示高度的图片,这个显示高度可以在DIY模块设置里设置,如果在那里不设置的话默认值为200px
  • 日志里的图片有大有小尺寸不一。怎样能让图片排列整齐,既要完整显示每张图片又不留空白呢?我的做法是在一行的内容凑足之后,将它们按比例缩小到总宽度正好是DIY模块区域的宽度。这样除最后一行外,其它各行都不会有空白之处了

4. 最后还要定义上面用到的汉字字符串
在文件source/language/lang_blockclass.php里加入 'blockclass_blog_field_piclist' => '日志内所有图片',
文章模块的组图显示
首先我们要修改文章模块文件source/class/block/portal/portal_article.php,做法和1是类似的,略有不同的地方是文章可以分页,我们要提取所有分页里的图片。
在函数fields里下面这行 'commentnum' => array('name' => lang('blockclass', 'blockclass_article_field_commentnum'), 'formtype' => 'text', 'datatype' => 'int'), 后添加 'piclist' => array('name' => lang('blockclass', 'blockclass_article_field_piclist'), 'formtype' => 'text', 'datatype' => 'string'), 在函数getdata里的下面这行 'commentnum' => intval($data['commentnum']), 后添加 'piclist'=>implode('|', $this->getpiclist($data['content'], $data['aid'], $data['contents'])), 添加上面用到的函数定义: function getpiclist($content, $aid, $pages) { if ($pages>1) $content.= $this->getadditionalpages($aid); $piclist = array(); if (!empty($content)) { require_once libfile('function/blog'); $content = blog_bbcode($content); /* include the following two lines only if the site uses the one-key-post feature explained in http://www.bian-wang.com/discuz/home.php?mod=space&uid=10005&do=blog&id=1486 */ require_once libfile('function/url2html'); $content = url2html($content, 0); preg_match_all("/\s*\<img src=[\"\'](.+?)[\"\'].*?\>\s*/is", $content, $matches); if(!empty($matches[1])) { foreach ($matches[1] as $value) { $piclist[] = $value; } } } return $piclist; } function getadditionalpages($aid) { $content = ''; $contents = C::t('portal_article_content')->fetch_all($aid); foreach($contents as $value) { if($value['pageorder']>1) $content .= ' '.$value['content']; } return $content; } 然后添加一个有关文章模块的模板,内容和2几乎相同但去掉了作者名: <div class="module cl xld"> [loop] <div style="text-align: center; font-weight: bold; font-size: 18px; margin-bottom: 4px;"> <em>< a href="{url}"{target}>{title}</a></em> </div> <div class="gallery"> <div class="item-template" data="{piclist}"> < a href="{url}"{target}><img></a> </div> </div> <script> setGallery('gallery', 0, {picheight}); </script> [/loop] </div> 3里加的javascript同样适用于文章,不需另作处理。和4类似要定义个字符串在文件source/language/lang_blockclass.php里: 'blockclass_article_field_piclist' => '文章内所有图片',
记录模块的组图显示
首先我们要修改记录模块文件source/class/block/space/space_doing.php,做法和1是类似的,略有不同的地方是我们不仅提取记录里的所有图片,还提取其所有回复里的图片。
在函数fields里下面这行 'replynum' => array('name' => lang('blockclass', 'blockclass_doing_field_replynum'), 'formtype' => 'text', 'datatype' => 'int'), 后添加 'piclist' => array('name' => lang('blockclass', 'blockclass_doing_field_piclist'), 'formtype' => 'text', 'datatype' => 'string'), 在函数getdata里的下面这行 'replynum'=>$data['replynum'], 后添加 'piclist'=>implode('|', $this->getpiclist($data['doid'], $data['message'])), 添加上面用到的函数定义: function getpiclist($doid, $message) { $piclist = array(); $query = C::t('home_docomment')->fetch_all_by_doid($doid); foreach($query as $data) { $message .= ' ' . $data['message']; } if (!empty($message)) { $message = strip_tags($message); require_once libfile('function/url2html'); /* include the following two lines only if the site uses the one-key-post feature explained in http://www.bian-wang.com/discuz/home.php?mod=space&uid=10005&do=blog&id=1486 */ $message = url2html($message, 0); preg_match_all("/\s*\<img src=[\'\"](.+?)[\'\"].*?\>\s*/is", $message, $matches); if(!empty($matches[1])) { foreach ($matches[1] as $value) { $piclist[] = $value; } } } return $piclist; } 然后添加一个有关记录模块的模板,内容和2类似: <div class="module cl xld"> <div class="gallery"> [loop] <div class="item-template" data="{piclist}"> < a href="{url}"{target}><img></a> </div> [/loop] </div> <script> setGallery('gallery', 0, 150); </script> </div> 3里加的javascript同样适用于记录,不需另作处理。和4类似要定义个字符串在文件source/language/lang_blockclass.php里: 'blockclass_doing_field_piclist' => '记录下所有图片',

注:在本文中的代码中,在<符号和a字符相连的地方在两者之间加了一个不应该有的空格,以避免Discuz在保存日志时自动改变日志内容。

发表评论 评论 (8 个评论)

回复 牛肉炖土豆 2019-5-24 09:07 PM
天香公主: 心随风舞的 http://artfaner.com
   不错,好多都可以借鉴
回复 天香公主 2019-5-24 06:08 AM
牛肉炖土豆: 帮哪位造网站呢?能否偷看一眼?
心随风舞的 http://artfaner.com
回复 牛肉炖土豆 2019-5-24 02:58 AM
天香公主: 欢迎欢迎,我最近在帮一个网友用Discuz造个网站,所以有些心得体会记录一下,不然过不久就忘了。
帮哪位造网站呢?能否偷看一眼?
回复 天香公主 2019-4-12 05:36 AM
牛肉炖土豆: 又看到技术帖了,前来支持
欢迎欢迎,我最近在帮一个网友用Discuz造个网站,所以有些心得体会记录一下,不然过不久就忘了。
回复 carry0987 2019-4-12 05:15 AM
天香公主: 文中的模板是将图片从左往右从上往下一一显示。但也可以用其它模板来达到其它的显示效果,如排成一行横向滚动,或叠起来用幻灯显示。 ...
了解,幻燈片部分應該用js就能輕鬆搞定~
回复 牛肉炖土豆 2019-4-12 05:00 AM
又看到技术帖了,前来支持
回复 天香公主 2019-4-6 10:04 PM
carry0987: 原來如此,這樣也就可以將文章內的圖片以輪播的方式顯示在DIY模塊裡了~
文中的模板是将图片从左往右从上往下一一显示。但也可以用其它模板来达到其它的显示效果,如排成一行横向滚动,或叠起来用幻灯显示。
回复 carry0987 2019-4-4 01:31 AM
原來如此,這樣也就可以將文章內的圖片以輪播的方式顯示在DIY模塊裡了~

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

小黑屋|Archiver|彼岸网  

Powered by Discuz! X3.1 © 2001-2014 Comsenz Inc.
GMT-4, 2026-7-14 12:02 PM , Processed in 0.038439 second(s), 21 queries.

返回顶部