企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
由于本人不是专业的前端,也没人给我设计一个轻博客。所以我只能利用互联网上的资源。 辛亏有了Bootstrap3,我也能冒充一下前端。 > 它山之石,可以攻玉 # 前端CSS框架选择 本来还犹豫试试Amaze UI的jquery版, 但是Amaze UI 由于出来的晚,不是很完善,也没有像 <http://expo.bootcss.com/> 这样的案例展示墙,想参照自定义要费一番功夫。 ![2015-06-07/5573957e27c5a](http://box.kancloud.cn/2015-06-07_5573957e27c5a.png) 然后幸运的是bootstrap 自带了一个博客案列: ![2015-06-07/55739600701b9](http://box.kancloud.cn/2015-06-07_55739600701b9.png) ![http://v3.bootcss.com/examples/blog/](http://box.kancloud.cn/2015-06-07_5573962267bee.png) 感觉上挺简洁,也支持响应式。 # js类库 - jquery 这是必须的,原生js不会,开发效率慢。jq的组件比较多,也比较熟。 - audiojs 用于音频播放 - bootstrap-table 用于自己实现移植ueditor里音乐搜索功能 - jcrop 图片裁剪库,用于生成头像 - jqnotifybar 用于做自定义提示 - tagsinput 实现发布页面的标签提示 - nprogress 用于ajax请求时的动态等待进度条 - plupload 一个html5上传组件 - smalot-bootstrap-datetimepicker 日期选择器 支持时间的选择 - uploadify swf上传插件,在OneThink和之前的项目里用烂了。 - ueditor 百度文本编辑器 - swipebox 图片展示slidebox # web组件的安装 由于要用到这么多的组件,一个个去官网上下载太麻烦了。索性用了一下 [bower-一个Web的包管理工具](https://github.com/bower/bower)。这货可以解决包依赖问题,虽然下下来的资源可能比你需要的多,因为是将项目框架仓库整个git pull 下来。里面可能会有demo、tests和readme.md。 安装首先要有node,这个去官网下载安装就好。 然后 `npm install -g bower` 全局安装这个命令就好了。 ~~~ # install dependencies listed in bower.json $ bower install # install a package and add it to bower.json $ bower install <package> --save # install specific version of a package and add it to bower.json $ bower install <package>#<version> --save ~~~ 也可以卸载某个包 `$ bower uninstall <package-name>` 具体使用方法,我就不介绍了。大家可以谷歌百度。 当然,有的时候由于项目可能被墙的原因,大家可能下载不了某个包。这时候只能靠人力了。我一般是 “红杏”翻墙访问,然后把下载地址放到115或者百度云盘里离线下载(我的迅雷会员到期了,迅雷没落后就不想充了)。 # 前端资源目录 上面的swipebox 是我自己下的,ueditor是找了一个ThinkPHP整合版,所以手动放置了。 大家可以看下我的前端目录就知道了: ![2015-06-07/55739b1c18b6a](http://box.kancloud.cn/2015-06-07_55739b1c18b6a.png) 一般我喜欢前端资源放Public里。然后 bower_components 是bower安装的目录。 * css 样式目录 * images图片库 * js 自定义js * static 是手动安装的js组件库 html5shiv.js 和respond.js 是为了兼容性的, think.js 是OneThink里,苗儿曾经写过 js的 兼容TP U函数的js实现。还有一个setValue 表单赋值函数。 # 代码实现 ## 变量替换 前面我们找了一个 博客静态页面。 然后,我们TP就要把它套好,能正常访问。 在套之前,我们先定义下模板常量,这样方便我们在模板中使用资源路径。 忘了交代项目目录了: ![整个项目目录](http://box.kancloud.cn/2015-06-07_55739eb79621b.png) 主要是应用目录 分了 Admin后台,Api rest接口,Common 公共模块,Home 前台 。Uploads是上传目录。 test是单元测试目录。用了多入口绑定。因此除了index.php 还有 admin.php、api.php。 README.md 项目介绍文档。 在`/App/Home/Conf/config.php` 前台配置里 配置上模板解析常量 ~~~ <?php return array( /* 模板相关配置 */ 'TMPL_PARSE_STRING' => array( '__STATIC__' => __ROOT__ . '/Public/static', '__BOWER__'=>__ROOT__. '/Public/bower_components', '__IMG__' => __ROOT__ . '/Public/images', '__CSS__' => __ROOT__ . '/Public/css', '__JS__' => __ROOT__ . '/Public/js', ), 'SHOW_PAGE_TRACE'=>true, ); ~~~ 然后把 `view-source:http://v3.bootcss.com/examples/blog/` chrome里右键查看那个博客的源码 复制下来的代码 先存到/App/Home/View/Index/index.html里,然后所有 资源文件的路径替换掉。有的如 `http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js` 这种直接 粘贴地址栏里 访问在右键保存到项目目录里。 替换前: ~~~ <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! --> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="../../favicon.ico"> <title>Blog Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link href="http://cdn.bootcss.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"> <!-- Custom styles for this template --> <link href="blog.css" rel="stylesheet"> <!-- Just for debugging purposes. Don't actually copy these 2 lines! --> <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]--> <script src="../../assets/js/ie-emulation-modes-warning.js"></script> <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="http://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script> <![endif]--> ~~~ 替换后: ~~~ <html> <head> <meta charset="UTF-8"> <title>Freelog - 自由的轻博客</title> <script src="__BOWER__/jquery/dist/jquery.min.js"></script> <script src="__BOWER__/bootstrap/dist/js/bootstrap.min.js"></script> <link href="__BOWER__/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="__CSS__/blog.css"> <link rel="stylesheet" href="__BOWER__/jqnotifybar/css/jquery.notifyBar.css"> <script type="text/javascript" src="__BOWER__/jqnotifybar/jquery.notifyBar.js"></script> <script type="text/javascript" src="__JS__/common.js"></script> <script type="text/javascript"> // var url = window.location.pathname + window.location.search; // url = url.replace(/(\/(p)\/\d+)|(&p=\d+)|(\/(id)\/\d+)|(&id=\d+)|(\/(group)\/\d+)|(&group=\d+)/, ""); var url = '__SELF__'; var no_pic = '__PUBLIC__/images/no-cover.png'; (function(){ var ThinkPHP = window.Think = { "ROOT" : "__ROOT__", //当前网站地址 "APP" : "__APP__", //当前项目地址 "PUBLIC" : "__PUBLIC__", //项目公共目录地址 "DEEP" : "{:C('URL_PATHINFO_DEPR')}", //PATHINFO分割符 "MODEL" : ["{:C('URL_MODEL')}", "{:C('URL_CASE_INSENSITIVE')}", "{:C('URL_HTML_SUFFIX')}"], "VAR" : ["{:C('VAR_MODULE')}", "{:C('VAR_CONTROLLER')}", "{:C('VAR_ACTION')}"] } })(); $(function(){ //单页高亮 $('.navbar-nav li').removeClass('active'); $('a.blog-nav-item[href="'+url+'"]').parent().addClass('active'); }) </script> <!-- Your site ends --> <block name="style"></block> </head> ~~~ 后面所有的静态资源路径都这么解决。 ## 模板继承 前端页面其实很多页面风格一样,只是变了内容区域或者,上下左右某块区域的内容。 ThinkPHP为我们提供了模板继承这个功能,让我们将共同的部分定义成父模板的一个个块,让我们子模板继承了以后,如果不用相应的block去替换,就可以获取父模板里原有块的内容,非常方便。 所以,我将之前的模板先 全部复制了 保存到 Index/base.html里。 然后,定义了一些区块 ~~~ <html> <head> <meta charset="UTF-8"> <title>Freelog - 自由的轻博客</title> <script src="__BOWER__/jquery/dist/jquery.min.js"></script> <script src="__BOWER__/bootstrap/dist/js/bootstrap.min.js"></script> <link href="__BOWER__/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="__CSS__/blog.css"> <link rel="stylesheet" href="__BOWER__/jqnotifybar/css/jquery.notifyBar.css"> <script type="text/javascript" src="__BOWER__/jqnotifybar/jquery.notifyBar.js"></script> <script type="text/javascript" src="__JS__/common.js"></script> <script type="text/javascript"> var url = '__SELF__'; var no_pic = '__PUBLIC__/images/no-cover.png'; (function(){ var ThinkPHP = window.Think = { "ROOT" : "__ROOT__", //当前网站地址 "APP" : "__APP__", //当前项目地址 "PUBLIC" : "__PUBLIC__", //项目公共目录地址 "DEEP" : "{:C('URL_PATHINFO_DEPR')}", //PATHINFO分割符 "MODEL" : ["{:C('URL_MODEL')}", "{:C('URL_CASE_INSENSITIVE')}", "{:C('URL_HTML_SUFFIX')}"], "VAR" : ["{:C('VAR_MODULE')}", "{:C('VAR_CONTROLLER')}", "{:C('VAR_ACTION')}"] } })(); $(function(){ //导航高亮 $('.navbar-nav li').removeClass('active'); $('a.blog-nav-item[href="'+url+'"]').parent().addClass('active'); }) </script> <!-- Your site ends --> <block name="style"></block> </head> <body> <div class="navbar navbar-inverse navbar-fixed-top blog-masthead"> <div class="container"> <div class="navbar-header"> <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="javascript:;">Freelog</a> </div> <div class="blog-nav collapse navbar-collapse" id="example-navbar-collapse"> <ul class="nav navbar-nav"> <li><a class="blog-nav-item" href="{:U('/')}">首页</a></li> <?php if (is_login()): ?> <li><a class="blog-nav-item" href="{:U('/mine/')}">我的文章</a></li> <?php endif ?> <li> <form class="navbar-form navbar-right" id="search" method="GET" action="/Search" role="search"> <div class="form-group input-group"> <input type="text" name="kw" class="form-control" placeholder="输入关键字搜索" value="{$kw|default=""}"> <span class="input-group-btn"> <button class="btn btn-default"> <span class="glyphicon glyphicon-search f20" aria-hidden="true"></span> </button> </span> </div> </form> </li> </ul> <ul class="nav navbar-nav navbar-right"> <li><a href="javascript:;" role="button" aria-expanded="false"><if condition="is_login()">{:session('user.nickname')}</if></a></li> <if condition="is_login()"> <li><a class="blog-nav-item" href="{:U('/user/profile')}">个人信息</a></li> <li><a class="blog-nav-item" href="{:U('/user/logout')}" class="ajax-get">退出</a></li> <else/> <li><a class="blog-nav-item" href="{:U('/user/login')}">登录</a></li> <li><a class="blog-nav-item" href="{:U('/user/reg')}">注册</a></li> </if> </ul> </div> </div> </div> <div class="container" id="main"> <block name="header"> <div class="blog-header"> <h1 class="blog-title">The Bootstrap Blog</h1> <p class="lead blog-description">The official example template of creating a blog with Bootstrap.</p> </div> </block> <div class="row"> <div class="col-sm-8 blog-main"> <block name="main"></block> </div><!-- /.blog-main --> <div class="col-sm-3 col-sm-offset-1 blog-sidebar"> <block name="sidebar"></block> </div><!-- /.blog-sidebar --> </div><!-- /.row --> </div><!-- /.container --> <footer class="blog-footer"> <p>Blog template built for <a href="http://getbootstrap.com">Bootstrap</a> by <a href="https://twitter.com/mdo">@mdo</a>.Modified by <a href="http://weibo.com/u/1342658313">@黑白世界4648</a></p> <p>© {:date('Y', time())} Freelog. 由 Thinkphp 强力驱动.</p> <p> <a href="#">Back to top</a> </p> </footer> <block name="script"></block> </body> </html> ~~~ - `<block name="style"></block>` 页面自定义样式区, - `<block name="header"></block>` 博客标题区 - `<block name="main"></block>` 博客内容区 - `<block name="sidebar"></block>` 侧边栏区 - `<block name="script"></block>` 页面自定义js脚本区 再将index.html 页面改为继承base模板的 ~~~ <extend name="Index/base" /> <block name="header"> <div class="blog-header"> <h4>{$title|default=""}</h4> </div> </block> <block name="main"> <volist name="list" id="post" key="post_k"> <assign name="tpl" value="$post.type"/> <switch name="tpl"> <case value="text"><include file="Index/text" /></case> <case value="picture"><include file="Index/picture" /></case> <case value="music"><include file="Index/music" /></case> <case value="video"><include file="Index/video" /></case> </switch> </volist> <empty name="list"> <div class="text-center"> <img src="__IMG__/logo-grey.png" alt="" width="135"> <br><br> 对不起,没有相应的文章 </div> </empty> {$_page} </block> <block name="sidebar"> <include file="Index/post_btn" /> <div class="sidebar-module sidebar-module-inset"> <h4>热门标签</h4> <ul class="list-unstyled side-tracked-tag"> <volist name="tags" id="tag"> <li> <a class="followed-tag clearfix" href="{:U('/')}?tag={$tag['title']}"> <span class="glyphicon glyphicon-tag" aria-hidden="true"></span> &nbsp;&nbsp; <span class="">{$tag.title}</span> </a> </li> </volist> </ul> </div> <div class="sidebar-module"> <h4>归档</h4> <ol class="list-unstyled"> <volist name="archive" id="vo"> <li><a href="{:U($vo['link'])}">{$vo.text}</a></li> </volist> </ol> </div> </block> <block name="script"> <script type="text/javascript" src="__BOWER__/audiojs/audiojs/audio.min.js"></script> <script src="__STATIC__/swipebox/js/jquery.swipebox.js"></script> <link rel="stylesheet" href="__STATIC__/swipebox/css/swipebox.css"> <script type="text/javascript"> $(function(){ var single = audiojs; single.events.ready(function() { var a1 = single.createAll('', $('.single audio')); }); //图片灯箱 $( '.swipebox' ).swipebox(); }) </script> </block> ~~~ 上面区块中,很多已经是最终现在的代码了。先无视掉。 # 总结 前端实现方面 主要涉及了三个问题,资源选择、资源引入、模板套用。 资源选择 大家可以参考 [代码家园](http://www.daimajiayuan.com/)、[最代码](http://www.zuidaima.com/) 这些个站长资源站点,时不时自己收藏一些 类似于最好的jquery组件之类文章。 模板套用 要会用模板常量和模板继承。后面还会讲到模板include包含。