百技网

 找回密码
 立即注册
搜索
《防爆磁力启动器原理与维修》 * 技术教程集合 * PLC入门教程 电工基础教程
论坛使用帮助 PLC视频教程下载 升级VIP用户的方法成伟新帖
查看: 906|回复: 0

[discuz开发] discuz!X帖子图片附件显示原理

[复制链接]
发表于 2020-5-12 01:27:00 | 显示全部楼层 |阅读模式
使用discuz论坛发帖后,看贴时你会发现如果上传了图片附件,会自动显示,如下图

有没有想过这里面有些黑科技?我们来剖析代码。

定位到template/defalut/forum/viewthread_node_body.htm,这里存放着每层楼帖子内容(包含该楼层附件),我们截取显示附件的相关代码
  • <div class="pattl">
  •                                 <!--{if $post['imagelist'] && $_G['setting']['imagelistthumb'] && $post['imagelistcount'] >= $_G['setting']['imagelistthumb']}-->
  •                                         <!--{if !isset($imagelistkey)}-->
  •                                                 <!--{eval $imagelistkey = rawurlencode(dsign($_G[tid].'|100|100'))}-->
  •                                                 <script type="text/javascript" reload="1">var imagelistkey = '$imagelistkey';</script>
  •                                         <!--{/if}-->
  •                                         <!--{eval $post['imagelistthumb'] = true;}-->
  •                                         <div class="bbda cl mtw mbm pbm">
  •                                                 <strong>{lang more_images}</strong>
  •                                                 <a href="javascript:;" class="xi2 attl_g">{lang image_small}</a>
  •                                                 <a href="javascript:;" class="xi2 attl_m">{lang image_big}</a>
  •                                         </div>
  •                                         <div id="imagelist_$post[pid]" class="cl" style="display:none"><!--{echo showattach($post, 1)}--></div>
  •                                         <div id="imagelistthumb_$post[pid]" class="pattl_c cl"><img src="{IMGDIR}/loading.gif" width="16" height="16" class="vm" /> {lang image_list_openning}</div>
  •                                 <!--{else}-->
  •                                         <!--{echo showattach($post, 1)}-->
  •                                 <!--{/if}-->
  •                                 <!--{if $post['attachlist']}-->
  •                                         <!--{echo showattach($post)}-->
  •                                 <!--{/if}-->
  •                         </div>

复制代码

注意内嵌PHP函数showattach(),如果是图片附件,会显示缩略图或原图,非图片附件会显示文件图标,那函数怎么判断该文件是否为图片,继续查看函数原型,定位于source/function/function_attachment.php
  • function showattach($post, $type = 0) {
  •         $type = !$type ? 'attachlist' : 'imagelist';
  •         $return = '';
  •         if(!empty($post[$type]) && is_array($post[$type])) {
  •                 foreach($post[$type] as $aid) {
  •                         if(!empty($post['attachments'][$aid])) {
  •                                 $return .= $type($post['attachments'][$aid], $post['first']);
  •                         }
  •                 }
  •         }
  •         return $return;
  • }

复制代码

通过函数的第二参数$type定义附件的类型,1为imagelist,非1为attachlist。然后我们要注意$type($post[‘attachments’][‘aid’],$post[‘first’])这句,根据$type的值会转义成attachlist($post[‘attachments’][‘aid’],$post[‘first’])或imagelist($post[‘attachments’][‘aid’],$post[‘first’])。这里有个小技巧:函数在调用时函数名可以用变量代替。

这个函数仅仅封装了表面的设定,具体生成html代码看来是imagelist()这个函数工作,所以要找出原型,但是却在source文件夹中找了半天都找不到?不是所有的php函数都写在source里的吗?别着急,先告诉各位该函数的位置在template/default/forum/discuzcode.htm中,函数原型如下
  • function imagelist($attach, $firstpost = 0) {
  •         global $_G;
  •         $attach['refcheck'] = (!$attach['remote'] && $_G['setting']['attachrefcheck']) || ($attach['remote'] && ($_G['setting']['ftp']['hideurl'] || ($attach['isimage'] && $_G['setting']['attachimgpost'] && strtolower(substr($_G['setting']['ftp']['attachurl'], 0, 3)) == 'ftp')));
  •         $aidencode = packaids($attach);
  •         $widthcode = attachwidth($attach['width']);
  •         $is_archive = $_G['forum_thread']['is_archived'] ? "&fid=".$_G['fid']."&archiveid=".$_G[forum_thread][archiveid] : '';
  •         $attachthumb = getimgthumbname($attach['attachment']);
  •         $pluginhook = !empty($_G['setting']['pluginhooks']['viewthread_attach_extra'][$attach[aid]]) ? $_G['setting']['pluginhooks']['viewthread_attach_extra'][$attach[aid]] : '';
  •         $guestviewthumb = !empty($_G['setting']['guestviewthumb']['flag']) && !$_G['uid'];
  •         if($guestviewthumb) {
  •                 $guestviewthumbcss = guestviewthumbstyle();
  •         }
  • -->
  • <!--{/eval}-->
  • <!--{block return}-->
  •         <!--{if $attach['attachimg'] && $_G['setting']['showimages'] && (($_G['group']['allowgetimage'] || $_G['uid'] == $attach['uid']) || (($guestviewthumb)))}-->
  •         <ignore_js_op>
  •                 <!--{if !IS_ROBOT}-->
  •                         <dl class="tattl attm">
  •                                 <dt></dt>
  •                                 <dd>
  •                                         <!--{if !$guestviewthumb}-->
  •                                                 <p class="mbn">
  •                                                         <a href="forum.php?mod=attachment{$is_archive}&aid=$aidencode&nothumb=yes" {if $_GET['from'] != 'preview'}onmouseover="showMenu({'ctrlid':this.id,'pos':'12'})" id="aid$attach[aid]"{/if} class="xw1" target="_blank">$attach[filename]</a>
  •                                                         <em class="xg1">($attach[attachsize], {lang downloads}: $attach[downloads])</em>
  •                                                 </p>
  •                                                 <div class="tip tip_4" id="aid$attach[aid]_menu" style="display: none" disautofocus="true">
  •                                                         <div>
  •                                                                 <p>
  •                                                                         <a href="forum.php?mod=attachment{$is_archive}&aid=$aidencode&nothumb=yes" target="_blank">{lang download}</a>
  •                                                                         <!--{if helper_access::check_module('album')}-->
  •                                                                                 &nbsp;<a href="javascript:;" onclick="showWindow(this.id, this.getAttribute('url'), 'get', 0);" id="savephoto_$attach[aid]" url="home.php?mod=spacecp&amp;ac=album&amp;op=saveforumphoto&amp;aid=$attach[aid]&amp;handlekey=savephoto_$attach[aid]">{lang save_to_album}</a>
  •                                                                         <!--{/if}-->
  •                                                                         <!--{if $firstpost && $_G['fid'] && $_G['forum']['picstyle'] && ($_G['forum']['ismoderator'] || $_G['uid'] == $attach['uid'])}-->
  •                                                                                 &nbsp;<a href="forum.php?mod=ajax&action=setthreadcover&aid=$attach[aid]&fid=$_G[fid]">{lang set_cover}</a>
  •                                                                         <!--{/if}-->
  •                                                                 </p>
  •                                                                 <p>
  •                                                                         <span class="y">$attach[dateline] {lang upload}</span>
  •                                                                         <a href="javascript:;" onclick="imageRotate('aimg_$attach[aid]', 1)"><img src="{STATICURL}image/common/rleft.gif" class="vm" /></a>
  •                                                                         <a href="javascript:;" onclick="imageRotate('aimg_$attach[aid]', 2)"><img src="{STATICURL}image/common/rright.gif" class="vm" /></a>
  •                                                                 </p>
  •                                                         </div>
  •                                                         <div class="tip_horn"></div>
  •                                                 </div>
  •                                                 <p class="mbn">
  •                                                         <!--{if $attach['readperm']}-->{lang readperm}: <strong>$attach[readperm]</strong><!--{/if}-->
  •                                                         <!--{if $attach['price']}-->{lang price}: <strong>$attach[price] {$_G['setting']['extcredits'][$_G['setting']['creditstransextra'][1]][unit]}{$_G['setting']['extcredits'][$_G['setting']['creditstransextra'][1]][title]}</strong> &nbsp;[<a href="forum.php?mod=misc&action=viewattachpayments&aid=$attach[aid]" target="_blank">{lang pay_view}</a>]
  •                                                                 <!--{if !$attach['payed']}-->
  •                                                                         &nbsp;[<a href="forum.php?mod=misc&action=attachpay&aid=$attach[aid]&tid=$attach[tid]" target="_blank">{lang attachment_buy}</a>]
  •                                                                 <!--{/if}-->
  •                                                         <!--{/if}-->
  •                                                 </p>
  •                                                 <!--{if $attach['description']}--><p class="mbn xg2">{$attach[description]}</p><!--{/if}-->
  •                                         <!--{/if}-->
  •                                         $pluginhook
  •                                         <!--{if $guestviewthumb}-->
  •                                                 <!--{eval}-->
  •                                                 <!--
  •                                                         $thumbpath = helper_attach::attachpreurl().'image/'.helper_attach::makethumbpath($attach['aid'], $_G['setting']['guestviewthumb']['width'], $_G['setting']['guestviewthumb']['height']);
  •                                                         $makefile = 'forum.php?mod=image&aid='.$attach['aid'].'&size='.$_G['setting']['guestviewthumb']['width'].'x'.$_G['setting']['guestviewthumb']['height'].'&key='.dsign($attach['aid'].'|'.$_G['setting']['guestviewthumb']['width'].'|'.$_G['setting']['guestviewthumb']['height']).'&type=1';
  •                                                 -->
  •                                                 <!--{/eval}-->
  •                                                 {$guestviewthumbcss}
  •                                                 <div class="guestviewthumb">
  •                                                         <img id="aimg_$attach[aid]" class="guestviewthumb_cur" aid="$attach[aid]" src="{STATICURL}image/common/none.gif" onerror="javascript:if(this.getAttribute('makefile')){this.src=this.getAttribute('makefile'); this.removeAttribute('makefile');}" file="$thumbpath" makefile="$makefile" alt="$attach[imgalt]" title="$attach[imgalt]"/>
  •                                                         <br>
  •                                                         <a href="member.php?mod=logging&action=login" onclick="showWindow('login', this.href+'&referer='+encodeURIComponent(location));">{lang guestviewthumb}</a>
  •                                                 </div>
  •                                         <!--{elseif !$attach['price'] || $attach['payed']}-->
  •                                                 <div class="mbn savephotop">
  •                                                 <!--{if $_G['setting']['thumbstatus'] && $attach['thumb']}-->
  •                                                         <a href="javascript:;"><img id="aimg_$attach[aid]" aid="$attach[aid]" src="{STATICURL}image/common/none.gif" zoomfile="{if $attach[refcheck]}forum.php?mod=attachment{$is_archive}&aid=$aidencode&noupdate=yes&nothumb=yes{else}{$attach[url]}$attach[attachment]{/if}" file="{if $attach[refcheck]}forum.php?mod=attachment{$is_archive}&aid=$aidencode{else}{$attach[url]}$attachthumb{/if}" alt="$attach[imgalt]" title="$attach[imgalt]" w="$attach[width]" /></a>
  •                                                 <!--{else}-->
  •                                                         <img id="aimg_$attach[aid]" aid="$attach[aid]" src="{STATICURL}image/common/none.gif" zoomfile="{if $attach[refcheck]}forum.php?mod=attachment{$is_archive}&aid=$aidencode&noupdate=yes&nothumb=yes{else}{$attach[url]}$attach[attachment]{/if}" file="{if $attach[refcheck]}forum.php?mod=attachment{$is_archive}&aid=$aidencode&noupdate=yes{else}{$attach[url]}$attach[attachment]{/if}" $widthcode alt="$attach[imgalt]" title="$attach[imgalt]" w="$attach[width]" />
  •                                                 <!--{/if}-->
  •                                                 </div>
  •                                         <!--{/if}-->
  •                                 </dd>
  •                         </dl>
  •                 <!--{else}-->
  •                         <dl class="tattl attm">
  •                         <!--{if !$attach['price'] || $attach['payed']}-->
  •                                 <dd>
  •                                         <!--{if $attach['description']}--><p>{$attach[description]}</p><!--{/if}-->
  •                                         <img src="{if $attach[refcheck]}forum.php?mod=attachment{$is_archive}&aid=$aidencode&noupdate=yes{else}{$attach[url]}$attach[attachment]{/if}" alt="$attach[imgalt]" title="$attach[imgalt]" />
  •                                 </dd>
  •                         <!--{/if}-->
  •                         </dl>
  •                 <!--{/if}-->
  •         </ignore_js_op>
  •         <!--{/if}-->
  • <!--{/block}-->
  • <!--{eval}-->
  • <!--
  •         return $return;
  • }

复制代码

也许你会问,为什么这个函数会写在模版文件夹?回顾代码,该函数的返回值是输出一大段显示图片附件的html代码,写在模板中更方便版面格式管理。那么写在php文件中不行吗?php中可以用EOT关键字来封装html代码啊。再仔细看看,这个输出代码中是html中嵌入了php代码,并且使用了discuz封装过的注释符<!—->,看来官方开发者考虑上兼容性弄了这么个黑科技来写函数,也是遛到不行啊!而且这里还可以学会discuz封装的两大关键字,帮助开发者在模版编码中执行php语句、封装html为变量,分别为eval和block。

eval关键字使模板中插入php语句执行,比如要在模版中使用echo语句,格式为<!–{eval ehco 1;}–>,注意只能执行一句。在discuz!X3中,该关键字得到加强,可是用闭合标签执行一段php代码,如下
  • <!--{eval}-->
  • echo 1;
  • echo 2;
  • <!--{/eval}-->

复制代码

而block的用法很简单,在闭合标签里定义变量名输出需要的html代码即可,如下
  • <!--{block return}-->
  • <p>测试</p>
  • <!--{/block}-->

复制代码

在php中变量为$return,当然可以换成任意合法的变量名。实际应用中block标签常用于嵌入式插件的模版开发。对于模板与后台代码的嵌入混合,需要开发者事先做好开发文档,清楚地列明模块实现功能的手段进行应用,避免日后维护时结构不清晰,导致看不懂代码。

探索仍未结束,输出html代码后,只是还有js控制每张图的缩略图显示方式,因此,在template/default/viewthread.htm保证以下脚本已加载
  • <script type="text/javascript" src="{$_G['setting']['jspath']}forum_viewthread.js?{VERHASH}"></script>

复制代码

同时template/default/viewthread_node.htm要有调用缩略图的执行脚本
  • <!--{if !empty($aimgs[$post[pid]])}-->
  • <script type="text/javascript" reload="1">
  •         aimgcount[{$post[pid]}] = [<!--{echo dimplode($aimgs[$post[pid]]);}-->];
  •         attachimggroup($post['pid']);
  •         <!--{if empty($_G['setting']['lazyload'])}-->
  •                 <!--{if !$post['imagelistthumb']}-->
  •                         attachimgshow($post[pid]);
  •                 <!--{else}-->
  •                         attachimgshow($post[pid], 1);
  •                 <!--{/if}-->
  •         <!--{/if}-->
  •         var aimgfid = 0;
  •         <!--{if $_G['forum']['picstyle'] && ($_G['forum']['ismoderator'] || $_G['uid'] == $_G['thread']['authorid'])}-->
  •                 aimgfid = $_G[fid];
  •         <!--{/if}-->
  •         <!--{if $post['imagelistthumb']}-->
  •                 attachimglstshow($post['pid'], <!--{echo intval($_G['setting']['lazyload'])}-->, aimgfid, '{$_G[setting][showexif]}');
  •         <!--{/if}-->
  • </script>
  • <!--{/if}-->

复制代码

其中attachimglstshow($post[‘pid’], <!–{echo intval($_G[‘setting’][‘lazyload’])}–>, aimgfid, ‘{$_G[setting][showexif]}’);就是实现缩略图的显示功能,这里再次看到discuz是如何处理javascript和php混合编码的好思路。

注:此文给出了缩略图显示原理,在模版二次开发/插件开发中若发现图片附件无法正常显示,可按本文给出的思路查找缺失代码进行DEBUG,别忘了前提就是后台设置好附件显示的用户组权限。




上一篇:浅析地方便民网站最有效的营销推广模式
下一篇:站长攻略之软文与百度知道的关系
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /2 下一条

小黑屋|Archiver|手机版|百技网

GMT+8, 2020-6-1 08:57 , Processed in 0.110769 second(s), 22 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表