2007-04-27

在Blogger首页显示文章摘要二解

在首页显示摘要是个不错的主意,可惜Blogger默认不支持.
网上倒是有一些解决方案,不过我都不大喜欢,因为需要修改文章模板,每次创建文章时还要指定哪里是摘要,哪里是全文,不爽.

我希望摘要的生成是自动的,可且应当便于修改. 网上好像有个这样的脚本,不过我网络不好,下不来...

经过两天的研究,我完成了两种方案.

方案一,根据行数定摘要.

修改模板, 加入CSS
/* added by WangLu
for summary display */
div.wl_summary{
height: 10em;
max-height: 10em;
overflow-y: hidden;
}

另外在post-body的定义中,把<p><data:post.body/></p>
改为
<!-- added by WangLu -->
<!-- display summary on the main page -->
<b:if cond='data:blog.pageType == "item"'>
<p><data:post.body/></p>
<b:else/>
<p>
<div class='wl_summary'>
<data:post.body/>
</div>
</p>
...
<br/>
<br/>
<a expr:href='data:post.url'>Read more...</a>
</b:if>

就行了.

此法优点是改动少,速度快,代码简单,且发文时无需添加额外信息
不过需要说明几点:
1. 在Firefox里指定height或max-height都可以达到效果,但是IE不支持max-height
2. 关于height的值可能需要根据实际字体进行修改, 设置不当容易出现半个字的情况.
3. 即使文章很短,也会出现'...'和Read more字样,逻辑上有点小问题.
4. 未显示的部分实际也已下载(查看源代码就能看到),因此不会减少数据下载量


方案二:根据字数定摘要.(我现在采用的方案)

仍需要修改模板,在post-body的定义中,把<p><data:post.body/></p>
改为
<!-- added by WangLu -->
<!-- display summary on the main page -->
<b:if cond='data:blog.pageType == "item"'>
<p><data:post.body/></p>
<b:else/>
<WL_SUMMARY />
<div class='wl_body'>
<p>
<data:post.body/>
</p>
</div>
<div class='wl_read_more'>
...<br/>
<br/>
<a expr:href='data:post.url'>Read more...</a>
</div>
</b:if>


然后添加javascriot页面元素(我这里直接往模板里写总出错)
<!-- added by WangLu for displaying summary in the main page -->
<script type="text/javascript">
var all_summaries = document.getElementsByTagName("WL_SUMMARY");
var num_of_char = 250;

for (var i=0; i < all_summaries.length ; ++i)
{
var summary = all_summaries.item(i);

var b = summary.nextSibling; //body
while( (!b) || (b.className!="wl_body")) b = b.nextSibling;
if(!b) continue; //error!

var r = b.nextSibling; //readmore
while( (!r) || (r.className!="wl_read_more")) r = r.nextSibling;
if(!r) continue; //error!

if (b.innerHTML.length < num_of_char)
r.style.display="none"; //don't show 'read more' for short articles
else
b.innerHTML = b.innerHTML.substring(0,num_of_char); //truncate
}
</script>

就好了.

此法优点是逻辑正确,能自动判断是否需要显示摘要,而且发文时无需添加额外信息.
不过需要说明几点:
1. 代码中寻找wl_body和wl_read_more时出于效率考虑,直接顺序查找,故不可交换二者顺序.
2. 不要在别处使用WL_SUMMARY或wl_body,wl_read_more
3. 显示摘要是直接砍innerHTML,对复杂的HTML代码可能会出问题
4. 这种方法实际也是下载后在删去,因此不会减少下载量.而且如果你的机器较慢,可能会看到文字先出现后消失. 不过这样最后确实可以节省一点内存
5. 按照我使用的模板的写法,这段脚本应该会在posts之后调用,对别的模板不予保证.(另一种想法是把脚本写成函数,然后放到文章所在<div>的onload去,不过这时函数应该提前声明,不知是否可行,我没有尝试)
6. 由于网络的原因,我这里修改页面元素的速度尚可,但是改模板就慢的不行了.我想出了一种简单地在这两种摘要模式中切换的方法:
保留第一种的CSS,但不要添加class='wl_summary'.
上一步并不影响第二种方法,因此照上述文字做即可.
如果想用第一种方法,只需把脚本中b.innerHTML=...一行改为b.className="wl_summary".
用这种方法实现的第一种方法可以兼顾二者的优点,卡行比较优美,且可以自动判断是否显示Read more,不错。

No comments: