接了一个网站开发的项目,网站系统用的是gpower cms,中文名叫通元内容管理系统, 该系统是Java开发,已经提供了内容管理后台,所以只需要开发前端模板即可。
因为后台数据是直接渲染到前端的,所以使用了基础的html+css进行开发。随着移动化的发展,现在看PC端网页越来越少,好在现在的网页设计脱离了原本花里胡哨的风格,通过给div加背景色、边框和阴影,交互上使用动画效果,页面看起来不仅简洁大方,也省了很多设计的苦恼。顺便学会了flex布局,相比以前用的float浮动,写起来确实很畅快。
在一台Windows 7系统的电脑下部署时,看到了历史悠久的IE浏览器,版本为IE8,考虑到还有部分人在使用旧系统,准备做一下兼容性测试,发现IE浏览器已经打不开网页,而不是像以前显示样式错乱,页面惨不忍睹,省了兼容性的麻烦,更不需要在页面中加入升级浏览器提示。不知道是不是IE自己拒绝访问,还是网页中head标签写的那句<meta http-equiv="X-UA-Compatible" content="IE=edge" />
起了效果,只能说现在的前端真是赶上好时候了。
对比千篇一律的移动端UI设计和小屏展示,不管是从获取内容还是艺术审美的角度,PC端的网页明显更具多样性也更精美,我只能说互联网不能没有网页。据说淘宝开始逐步下线pc端购物功能,这样真的没有必要。
前端模板做好了,但是出现一个问题,怎么绑定后台数据呢?研究了一下,模板引擎是Apache Velocity,但是系统自己定义了很多方法和变量,在没有开发文档的情况下,只好学习该网站的旧模板代码,复用了一部分,自己摸索出了一部分,现在整理了一下,当作记录,如果是以内容展示为主的网站,以下语法基本够用了。
常用变量和方法
$site.fullName #站点标题(后台-站点设置)
$pathUtil.getSiteUrl($site) #站点url,静态资源前添加绝对路径避免引用失效
$cms.getUrl("新闻动态") #根据栏目名获取地址
${curChannel.title} #当前栏目标题
$curArticle.name #当前文章标题
#parse("header.vm") #包含引用模板
站点字段
com.gpower.cms.site.entity.SiteSite@62f219ef[name=我的网站,fullName=<null>,shortName=demo,sortID=46,rootChannelID=1356,rootChannel=<null>,pubUrl=http://www.example.com/demo,path=demo,encoding=<null>,logo=<null>,indexFile=index,indexExt=htm,itemExt=htm,dirType=0,smartGet=0,status=1,ifUse=1,defaultChannelID=<null>,defaultContentType=1,secondaryDomain=0,online_=false,synchronizeResource=0,isMobile=0,articleCount=0,publishArticleCount=0,id=45,name=<null>]
文章字段
com.gpower.cms.content.entity.Conten@4d32fffa[title=在中国买车,越来越便宜了?,titleColor=#333333,parentID=1379,siteID=45,viceTitle=<null>,keyword=<null>,author=财经汽车,source=虎嗅,summary=<null>,status=7,type=1,viewCount=0,viewCountToday=0,sortID=1634863758690,owner=jzy,creationDate=Fri Oct 22 08:49:19 CST 2021,modifiedDate=Fri Oct 22 08:52:23 CST 2021,publishDate=Thu Oct 21 08:40:00 CST 2021,url=<null>,version=<null>,versions=<null>,properties=<null>,isTop=4998,beginDay=<null>,topTime=<null>,topDays=0,lock_=false,lockUser=<null>,srcContentID=<null>,srcContent=<null>,channelName=<null>,allowExtranet=false,name=在中国买车,越来越便宜了?,seoData=<null>,id=c9aff8fcd1f443cd94ae2a45a738e321,name=<null>]
栏目字段
com.gpower.cms.channel.entity.Channel@1abe38ad[name=关于我们,sortID=10,title=关于我们,path=gywm,type=0,status=1,orderBy=sortID DESC,query=<null>,code=,publishType=1,dirType=0,logo=,isTop=1,isSuggest=0,archiveDays=0,pageCount=20,pageType=0,inheritRight=1,siteID=45,parentID=1356,site=<null>,parent=<null>,children=[],indexTemplateID=3dd040f6d346444697034e45de336cdd,itemTemplateID=4ebe52ed699f413bbbdb41688dddc920,indexFile=,indexExt=,itemExt=,extendFields=<null>,defaultContentType=1,dispatchChannels=<null>,workflow=0,srcChannelID=0,maxIndex=0,viewCount=0,viewCountToday=0,isApp=0,creationDate=Mon Apr 24 00:00:00 CST 2017,modifiedDate=Sun Mar 03 21:56:03 CST 2024,permit=1,childrenCount=0,orderByValue=0,owner=xscjzy,compressImg=0,mobileShow=0,indexMobileTemplateID=<null>,itemMobileTemplateID=<null>,topic=false,topicStatus=0,orderByValues={sortID DESC,sortID ASC,publishDate DESC,publishDate ASC},url=<null>,networkType=0,articleCount=0,publishArticleCount=0,id=1386,name=<null>]
获取内容
获取某一栏目的文章列表
<ul>
#foreach($article in $cms.getContentsByChannelName("工作动态",8))
<li><a href="$cms.getUrl($article)">$article.name</a> <span>$cms.format($article.publishDate,"yyyy-MM-dd")</span>
</li>
#end
</ul>
获取文章封面图
- 因为编辑不会给每篇文章添加封面图片,从最近100篇文章中取出5张带封面图的文章,常用于用户幻灯片展示
#set($expNum = 6)
#set($count = 0)
#set($i = 0)
#foreach($article in $cms.getContentsByChannelName("工作动态",100))
#if($cms.getPictureUrl($article)!="")
#set($i=$i+1)
#if($count<$expNum)
<div class="swiper-slide">
<a href="$cms.getUrl($article)" target="_blank">
<img src="$cms.getPictureUrl($article)" alt="$article.name">
<div class="news-swiper-title">
<p>$article.name</p>
</div>
</a>
</div>
#set($count = $count+1)
#end
#end
#end
获取文章摘要
<h3>$article.name</h3>
#if($stringUtil.nullFilter($article.summary)!="")
<p>$stringUtil.summary($article.summary,120)</p>
#else
#set($fullArticle=$cmsService.getArticle($article.id))
<p>$stringUtil.summary($cms.clearHtml($stringUtil.nullFilter($fullArticle.content)),120)</p>
#end
获取导航
<ul class="menu">
#if($curChannel.title == "首页")
<li class="active"><a href="$cms.getUrl("首页")">网站首页</a></li>
#else
<li><a href="$cms.getUrl("首页")">网站首页</a></li>
#end
#foreach($channel in $cms.getTopChildren($rootChannel))
#set($count=$cms.getChannelCountByChannelID($channel.id))
#if ($count == 0)
#if($channel.title==$curChannel.title)
<li class="active">
#else
<li>
#end
<a href="$cms.getUrl($channel)">$channel.title</a></li>
#else
#foreach($cChannel in $cms.getChildren($channel,0,1))
<li>
<a href="$cms.getUrl($channel)">$channel.title</a>
<ul class="dropdown">
#foreach($cChannel in $cms.getChildren($channel))
<li><a href="$cms.getUrl($cChannel)">$cChannel.title</a></li>
#end
</ul>
</li>
#end
#end
#end
</ul>
获取栏目内文章列表
<ul class="post-list">
#foreach($article in $cms.getPageContents($curChannel,$curPage))
<li><a href="$cms.getUrl($article)">$article.name</a>
<span class="date-label">$cms.format($article.publishDate,"yyyy-MM-dd")</span>
</li>
#end
</ul>
获取附件
#if ($cms.getArticleAttachmentCount($curArticle.id, 3)>0)
<div class="post-file">
<h3>附件下载</h3>
<ol>
#foreach($doc in $cms.getAttachments($curArticle))
<li><a href="$cms.getUrl($doc)" target="_blank">$doc.name</a></li>
#end
</ol>
</div>
#end
上下篇文章
<div class="post-jump">
#foreach($article in $cmsService.getPageDatas("select * from cms_content where parentID='$curChannel.id' and status=7 and publishDate>'$cms.format($curArticle.publishDate,'yyyy-MM-dd HH:mm')' order by publishDate asc",1,1))
<div class="post-prev">
<a href="$cms.getUrl($article)">上一篇: $article.title </a>
</div>
#end
#foreach($article in $cmsService.getPageDatas("select * from cms_content where parentID='$curChannel.id' and status=7 and publishDate<'$cms.format($curArticle.publishDate,'yyyy-MM-dd HH:mm')' order by publishDate desc",1,1))
<div class="ppost-next">
<a href="$cms.getUrl($article)">下一篇: $article.title</a>
</div>
#end
</div>
前端获取文章封面图和摘要
- 通过在页面中输出全文,再通过js提取图片和截取文字作为摘要
<ul class="post-list">
#foreach($article in $cms.getPageContents($curChannel,$curPage))
<li class="item">
<div class="item-img" style="display:none;"></div>
<div class="item-content">
<h2 class="item-title"><a href="$cms.getUrl($article)" rel="bookmark">$article.name</a></h2>
<div class="item-excerpt"></div>
<div class="item-summary" style="display: none;">
#set ($fullArticle=$cmsService.getArticle($article.id))
#if($stringUtil.nullFilter($!{fullArticle.content})!= "")
$!{fullArticle.content}
#end
</div>
</div>
</li>
#end
</ul>
<!-- 需引入jQuery -->
<script src="$pathUtil.getSiteUrl($site)/static/js/jquery.slim.min.js"></script>
<script>
$(document).ready(function () {
$(".post-list-pro .item").each(function () {
var summary = $(this).find(".item-summary").html();
var img = imgUrlFun(summary);
var des = filterHTMLTag(summary).substr(1, 150);
if (img !== '') {
$(this).find(".item-img ").show().html("<img src='" + img + "'/>");
}
if (des != "") {
$(this).find(".item-excerpt").html(des + "...");
}
$(this).find(".item-summary").remove();
});
});
//Get Frist Image
function imgUrlFun(str) {
var data = '';
str.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/, function (match, capture) {
data = capture;
});
return data;
}
//Remove HTML tags
function filterHTMLTag(str) {
str = str.replace(/<\/?[^>]*>/g, ''); //去除HTML tag
str = str.replace(/[ | ]*\n/g, '\n'); //去除行尾空白
str = str.replace(/ /ig, '');//去掉
return str;
}
</script>
按浏览量获取当前栏目热门文章
#foreach($article in $cmsService.getPageDatas("select * from cms_content where parentID='$curChannel.id' and status=7 order by viewCount desc",1,6))
<li><a href="$cms.getUrl($article)" title="$article.title">
$stringUtil.summary($article.title,30)</a>
</li>
#end
从上面代码可以看出提供了一个可以直接在前端查询SQL语句的方法
$cmsService.getPageDatas([SQL语句],[从第几条开始],[条数])
获取子栏目
- 常用于侧边栏,用来展示栏目
- 如果有兄弟菜单或子菜单,展示子菜单,否则展示推荐的栏目,isSuggest==1 为推荐
#set($count=$cms.getChannelCountByChannelID($curChannel.id))
#if($count!=0)
#set($c=$curChannel)
#else
#set($c=$cms.getChannel($curChannel.parentID))
#end
<ul class="channel-list">
#if($c.id==1356)
#foreach($channel in $cms.getChildren($c))
#if($channel.isSuggest==1)
#if($channel.title==$curChannel.title)
<li class="current">
<a href="$cms.getUrl($channel)">$channel.title </a>
</li>
#else
<li><a href="$cms.getUrl($channel)">$channel.title</a> </li>
#end
#end
#end
#else
#foreach($channel in $cms.getChildren($c))
#if($channel.title==$curChannel.title)
<li class="current"> <a href="$cms.getUrl($channel)">$channel.title</a> </li>
#else
<li><a href="$cms.getUrl($channel)">$channel.title</a> </li>
#end
#end
#end
</ul>
以上代码可以优化,比如判断是否为当前栏目,可以将class单独设置为变量,不需要写两个li标签导致代码冗余
#if($channel.title==$curChannel.title)
#set($current = "current")
#else
#set($current = "")
#end
<li class=“$current”><a href="$cms.getUrl($channel)">$channel.title </a></li>
获取栏目的图片
- 如果后台没有设置栏目封面,则显示默认栏目图
#if($stringUtil.nullFilter($curChannel.logo)=="")
<div style='background-image: url($pathUtil.getSiteUrl($site)/static/images/cover.webp)'>
#else
<div style='background-image: url($pathUtil.getSiteUrl($site)/${curChannel.path}/$curChannel.logo)'>
#end
工具
搜索
- POST方式提交
- 内含两个字段,query 和 siteID
<form id="search-form" method="post" action="/cms/web/search/index.jsp" target="_blank">
<label>
<input type="text" name="query" type="text" placeholder="" autocomplete="off"></label>
<input name="siteID" value="45" type="hidden">
<button type="submit">搜索</button>
</form>
文章访问统计
<span>阅读量:
<script src="/cms/web/writeLog.jsp?siteID=$curChannel.siteID&channelID=$curChannel.id&contentID=$curArticle.id"></script></span>
分页(展示页码)
<div class="pager">
#set($prePage = $curPage - 1)
#set($leftm=$prePage/5)
#set($left=$leftm*5 + 1)
#set($right=$leftm*5 + 5)
#if($right>$totalPage)
#set($right=$totalPage)
#end
#set($nextPage=$curPage+1)
#set($newPage1 = $left + 5)
#set($newPage2 = $left - 1)
#if($curPage>1)
<a class="prev" href="$cms.getIndexFileName($curChannel,$prePage)">上一页</a>
#else
<a class="prev">上一页</a>
#end
<span class="pager-num">
#foreach($index in [$left..$right])
#if ($index == $curPage)
<a class="active">$index</a>
#else
<a href="$cms.getIndexFileName($curChannel, $index)">$index</a>
#end
#end
</span>
#if($curPage<$totalPage)
<a class="next" href="$cms.getIndexFileName($curChannel, $nextPage)">下一页</a>
#else
<a class="next">下一页</a>
#end
</div>