当前版本添加了公告功能,可以在首页显示一些站点公告信息。在install/create_table.zl脚本中,增加了与公告相关的表结构的创建语句,要正常使用公告功能,需要先执行该脚本,在数据库中创建好notice公告表结构。
页面导航:
zenglBlog源代码的相关地址:https://github.com/zenglong/zenglBlog 最新版本对应的tag标签为:v0.7.0
当前版本添加了公告功能,可以在首页显示一些站点公告信息。在install/create_table.zl脚本中,增加了与公告相关的表结构的创建语句:
// 创建公告表 if(mysqlQuery(con, "CREATE TABLE notice( id int NOT NULL AUTO_INCREMENT, title varchar(255) NOT NULL DEFAULT '' COMMENT '公告标题', description varchar(2048) NOT NULL DEFAULT '' COMMENT '公告详细描述', `created_at` timestamp NULL DEFAULT NULL COMMENT '创建时间', `updated_at` timestamp NULL DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET utf8 COLLATE utf8_general_ci COMMENT='公告表'")) finish_with_error(con); endif
要正常使用公告功能,需要先执行该脚本,在数据库中创建好notice公告表结构。如果之前执行过此脚本的话,需要先将install/install.lock安装锁文件删除掉,然后将其他的表结构创建语句,以及插入管理员用户信息的语句给注释掉,接着就可以正常执行该脚本来创建公告表结构了。当前版本移除了create_table.zl中的"DROP TABLE IF EXISTS ..."语句,因为这条语句容易误删除之前安装过的表结构。
在后台添加了公告列表,用于对公告进行管理:
图1:后台公告列表
公告列表右上角有添加公告按钮,列表中有编辑和删除按钮,可以方便的进行公告的添加、修改和删除操作:
图2:公告的添加、修改及删除按钮
在后台添加了公告后,就可以在前台首页看到相关的公告信息了(首页公告按照更新时间排序):
图3:首页展示的公告信息
如果使用index.zl动态脚本访问首页的话,马上就能看到类似上面所示的公告信息,但是如果之前生成过index.html首页静态文件,那么要看到index.html中包含的公告信息的话,就需要在后台执行生成静态页面的操作。
和后台公告列表相关的脚本为admin/notice.zl :
inc 'common.zl'; inc 'helper.zl'; querys = rqtGetQuery(); action = querys['act'] ? querys['act'] : 'list'; if(action == 'list') Notice.list(); elif(action == 'add') Notice.add(); elif(action == 'edit') Notice.edit(); elif(action == 'delete') Notice.delete(); else print 'invalid act'; endif class Notice // 显示公告列表 fun list() global menus, querys; data['title'] = '公告列表:'; setCurMenu(menus, 'notice.zl'); data['menus'] = menus; db = Notice.initDB(); tmp = Mysql.fetchOne(db, "select count(1) as cnt from notice "); total = bltInt(tmp['cnt']); page = get_page(10, total, 10); for(i=page['start']; i <= page['end'];i++) cur = (page['curpage'] == i) ? ' class="active"' : ''; pages[] = '<li'+cur+'><a href="'+page['link']+'page='+i+'">'+i+'</a></li>'; endfor data['page'] = page; data['pages'] = pages; data['notices'] = Mysql.fetchAll(db, "select * from notice order by id desc limit " + page['offset'] + "," + page['limit']); print bltMustacheFileRender("tpl/notice_list.tpl", data); endfun // 初始化数据库连接 fun initDB() global config; db = bltArray(); Mysql.init(db, config, "tpl/error.tpl"); return db; endfun // 显示添加或编辑公告的页面 fun showAdd(db, data, isadd = TRUE) global menus; setCurMenu(menus, 'notice.zl'); csses = bltArray('notice_add.css'); data['csses'] = csses; data['menus'] = menus; data['title'] = isadd ? '添加公告' : '编辑公告'; data['act'] = isadd ? 'add' : 'edit'; print bltMustacheFileRender("tpl/notice_add.tpl",data); endfun // 校验数据 fun validate(db, posts, isadd = TRUE) bltStr(&posts['title'], TRUE); bltStr(&posts['description'], TRUE); if(!posts['title']) data['err_msg'] = '公告标题不能为空'; elif(!posts['description']) data['err_msg'] = '公告详情不能为空'; elif(!isadd && !posts['id']) data['err_msg'] = '无效的公告ID'; endif if(data['err_msg']) data['posts'] = posts; if(posts['id']) data['id'] = posts['id']; endif Notice.showAdd(db, data, isadd); bltExit(); endif endfun // 添加公告 fun add() posts = rqtGetBodyAsArray(); db = Notice.initDB(); if(posts['submit']) Notice.validate(db, posts); bltUnset(&posts['submit']); posts['created_at'] = bltDate('%Y-%m-%d %H:%M:%S'); posts['updated_at'] = posts['created_at']; Mysql.Insert(db, 'notice', posts); data['success_msg'] = '添加公告成功'; endif Notice.showAdd(db, data); endfun // 编辑公告 fun edit() global querys; posts = rqtGetBodyAsArray(); db = Notice.initDB(); if(posts['submit']) id = bltInt(posts['id']); Notice.validate(db, posts, FALSE); bltUnset(&posts['submit']); posts['updated_at'] = bltDate('%Y-%m-%d %H:%M:%S'); Mysql.Update(db, 'notice', posts, 'id=' + id); data['success_msg'] = '编辑公告成功'; else id = bltInt(querys['id']); endif data['posts'] = Mysql.fetchOne(db, "select * from notice where id='"+id+"'"); if(!bltCount(data['posts'])) data['err_msg'] = '无效的公告ID'; id = 0; endif data['id'] = id; Notice.showAdd(db, data, FALSE); endfun // 删除公告 fun delete() global querys; db = Notice.initDB(); id = querys['id'] ? bltInt(querys['id']) : 0; if(id <= 0) ajax_return('无效的公告id'); endif Mysql.Exec(db, "DELETE FROM notice WHERE id="+id); ajax_return(); endfun endclass
这段代码的执行逻辑和文章操作的执行逻辑是差不多的。公告列表使用的模板文件为:admin/tpl/notice_list.tpl,添加和编辑公告所使用的模板文件为:admin/tpl/notice_add.tpl。上面脚本中模板路径使用的是相对于当前脚本的路径,因此,就省略了admin目录。
前台首页的主脚本:index.class.zl也进行了调整,用于显示公告信息:
class Index // 首页内容 fun index(static = FALSE) global querys, categories, db, config; data['head_title'] = data['site_name'] = config['site_name']; data['description'] = config['site_desc']; data['csses'] = bltArray('index.css?v=20181003'); data['head_js'] = bltArray('jquery.yestop.js'); data['thumb_articles'] = Mysql.fetchAll(db, "select id,title,thumbnail,created_at,DATE_FORMAT(created_at, '%Y%m') as format_created from article " + " where thumbnail != '' order by id desc limit 0,4"); data['latest_articles'] = Mysql.fetchAll(db, "select id,title,thumbnail,description,created_at,DATE_FORMAT(created_at, '%Y%m') as format_created from article " + " order by id desc limit 0,5"); data['latest_articles_cnt'] = bltCount(data['latest_articles']); data['notices'] = Mysql.fetchAll(db, "select id,title,description,created_at from notice order by updated_at desc"); data['notices_cnt'] = bltCount(data['notices']); data['categories'] = categories; data['static'] = static; for(i=0;i < 10 && bltIterArray(categories,&i,&v);) item = bltArray(); item['cate_id'] = v['id']; item['cate_name'] = v['name']; item['articles'] = Mysql.fetchAll(db, "select id,title,description,thumbnail,created_at,DATE_FORMAT(created_at, '%Y%m') as format_created from article where cid = "+v['id']+" order by id desc limit 0,5"); items[] = item; endfor data['items'] = items; content = bltMustacheFileRender("/tpl/index.tpl", data); if(!static) print content; else return content; endif endfun endclass
在上面这个首页内容脚本中,data['notices']中存储了从数据库中查询出来的公告信息,而data['notices_cnt']则保存了公告的数量,当公告数量为0时,首页就不会显示和公告相关的界面元素。此外,当前版本的首页中还增加了最近更新数据,这些数据就存储在上面脚本中的data['latest_articles']数组成员中。
前台首页和列表页都增加和内容页一样的返回顶部按钮,当数据很多时,以及在手机上浏览信息时,可以方便的返回顶部。
内容页图片通过js脚本实现了自适应,在手机上可以自动调整图片尺寸,让图片能够在不同尺寸的设备上都能完整的显示出来:
图4:内容页图片自适应
内容页调整的js代码位于tpl/article_show.tpl模板文件中:
<script type="text/javascript"> $(document).ready(function () { $.fn.yestop({yes_image: '/assets/image/yestop.png'}); $(".row .content img").removeAttr("style").addClass("img-responsive center-block"); }); ................................................... </script>
通过给img标签加入img-responsive样式让图片实现自适应。
最后,当前版本还调整了favicon.ico图标,之前的图标占了几十K的大小,现在的图标是个ZL标志,只有几K大小,更适合当前的网站样式:
图5:favicon.ico图标调整
有人这样说过:在人的身体里有两只狼,在不停的竞争,搏杀,一只代表仇恨,嫉妒和恐惧,另一只代表美好,善良和博爱。
—— 《天坑鹰猎》