基于express+mongodb+pug的博客系统——pug篇
很久之前就想自己搭一个博客了,最开始用hexo+github,但是换电脑后总是有些麻烦。后来使用WordPress,但是用WordPress总觉得没什么技术含量,前后端都是人家写好的,而且买的垃圾虚拟机老是出问题,动不动就要提交工单解决,所以最后干脆就直接在博客园上写了。
最近比较闲,所以正好抽时间简单看了下node.js,然后看了看express,顺便搭了个博客出来练手。当然也不仅是单纯的练手,更多的算是一种探路或者摸索吧,因为公司虽然有大牛,但更多的是忙于应付业务,基本上是没时间去学学新的东西来尝试解决我们在开发中遇到的各种问题,这其中就包括比如重复书写大量相同代码,后期维护困难等。
在此之前,我也没有真正写过后台项目,虽然在学校用PHP+MySQL写过几个简单的页面,但是毕业快一年了,以前的东西都太久没用,基本都快忘记了。所以现在使用node.js+mongoDB也算是从零开始吧,在写的过程中,有简单的去对项目结构等作出一些优化调整,但越往后,理解也就越深,所以更多的干脆就留着下一版来更改吧。
这一个版本算是初级版本吧,基本功能是全的。不过经过这三个多星期的实际操作和阅读一些别人的博客,从代码结构和工程结构方面,都有更深的理解,所以还有很多能够优化的地方。不过并不打算等到都做好了再写,而是先把这段时间遇到的坑记录下来,要不时间越久,忘的也就越多,早点记录,多少还能留下点什么,也能帮助其他新手朋友更容易入门。
这一个版本所用到的库,包括node框架express4.4X、数据库mongoDB、模板引擎pug(原jade)。
废话不多说,进入正题。
我在项目中使用的pug.js是最新2.0版本的。
1.基础文档
在pug中没有结束标签,需要严格使用缩进来表示父子元素之间的关系。
编译前:
doctype html
html
head
title pug基础
body
p.text 必须严格使用缩进,来表明父子和兄弟元素间的关系
编译后:
<!DOCTYPE html> <html> <head> <title>pug基础 </title> </head> <body> <p class="text">必须严格使用缩进,来表明父子和兄弟元素间的关系</p> </body> </html>
2.内容渲染(插值)
各个模板引擎渲染方法都差不多,这里主要是给大家展示在pug模板里插值的写法。
方法一:
插入固定字符串,直接在标签后面敲空格输入字符串就行
插入变量时,输出字符使用#{};输出html代码使用!{}
在使用大括号插值时,还支持JavaScript表达式
编译前:
- var string = "string"; - var html = "<span>htmlString</span>"; p 直接写插入字符串,只需在标签后面敲一个空格 p 需要渲染为字符串的变量#{string}
p 大括号插值也支持JavaScript表达式#{string.toUpperCase()}
p 需要渲染为html代码的变量!{html}
编译后:
<p>直接写插入字符串,只需在标签后面敲一个空格</p> <p>需要渲染为字符串的变量string</p> <p>需要渲染为字符串的变量STRING</p> <p>需要渲染为html代码的变量<span>htmlString</span></p>
方法二:
1.使用=插入text
2.使用!=插入html
3.同样也支持JavaScript表达式
编译前:
- var string = "string"; - var html = "<span>htmlString</span>" p 直接写插入字符串,只需在标签后面敲一个空格 p= '需要渲染为字符串的变量'+string.toUpperCase() p!= '需要渲染为html代码的变量'+html
编译后:
<p>直接写插入字符串,只需在标签后面敲一个空格</p> <p>需要渲染为字符串的变量STRING</p> <p>需要渲染为html代码的变量<span>htmlString</span></p>
3.属性
pug模板中给元素添加属性
简单添加
编译前:
a(class='link' href='www.baidu.com') 百度
编译后:
<a class="link" href="www.baidu.com">百度</a>
三元表达式
编译前:
- var active= true
a(class=active? 'link-active' : '' href="www.baidu.com") 百度
编译后:
<a class="link-active" href="www.baidu.com">百度</a>
class条件
编译前:
- var currentUrl = '/about'
a(class={active: currentUrl === '/'} href='/') Home
a(class={active: currentUrl === '/about'} href='/about') About
编译后:
<a href="/">Home</a> <a class="active" href="/about">About</a>
属性插值
编译前:
- var btnType = 'info'
- var btnSize = 'lg'
button(type='button' class='btn btn-' + btnType + ' btn-' + btnSize)
//- 支持ES6的环境中
button(type='button' class=`btn btn-${btnType} btn-${btnSize}`)
编译后:
<button class="btn btn-info btn-lg" type="button"></button> <button class="btn btn-info btn-lg" type="button"></button>
4.语句
语句包括编程语言中的for、if、switch这些,只是在pug中,稍微有些不同。
case
case语句和JavaScript中的switch语句类似。
编译前:
- var friends = 10
case friends
when 0
p you have no friends
when 1
p you have a friend
default
p you have #{friends} friends
编译后:
<p>you have 10 friends</p>
if
编译前:
- var user = { name: 'tom' }
- var age = false
#user
if user.description
h2.green 如果user.name为true
p.description= user.name
else if age
h2.blue 如果age为true
p.description= age
else
h2.red Description
p.description User has no description
编译后:
<h2 class="green">如果user.name为true</h2>
<p class="description">foo bar baz</p>
each
编译前:
- var arr = ['zero', 'one', 'two'];
- var obj = {name:'tom',age:21,country:'china'};
ul.array
each val, index in arr
li= index + ': ' + val
ul.object
each val, key in obj
li= key + ': ' + val
编译后:
<ul class="array"> <li>0: zero</li> <li>1: one</li> <li>2: two</li> </ul> <ul class="object"> <li>name: tom</li> <li>age: 21</li> <li>country: china</li> </ul>
5.include
通过include,你可以在一个pug模板里,引入另外一个pug组件。
编译前:
//- index.pug
doctype html
html
title include用法
body
include components/head.pug
p 在index.pug文件中引入了head.pug和footer.pug两个组件
include components/footer.pug
//- components/head.pug
h1 这是head.pug组件
//- components/footer.pug
footer 这是footer.pug组件
编译后:
<!DOCTYPE html> <html> <head> <title>include用法</title> </head> <body> <h1>这是head.pug组件</h1> <p>在index.pug文件中引入了head.pug和footer.pug两个组件</p>
<footer>这是footer.pug组件</footer>
</body>
</html>
6.模板继承
include可以帮我们少写很多重复代码,同时更容易去维护每个组件。而继承则能够使模板更加灵活,进一步减少我们的工作量。
在pug里,我们可以使用extends来继承模板,使用block来定义可能会变化或者可扩展的内容。
编译前:
//- layout.pug
doctype html
html
head
title Template Inheritance用法
//- 这里是可以扩展的link区域
block links
link(rel="stylesheet" href='/main.css')
script(src="/jquery.js")
body
head 所有页面的公共头部
//- 这里是可以扩展的内容区域
block content
//- 这里是可以扩展的script区域
block scripts
script(src="/bootstrap.js")
//- index.pug
extends layout.pug
block links
link(rel="stylesheet" href='/bootstrap.css')
link(rel="stylesheet" href="/index.css")
block content
h1 模板继承的用法
p 使用extends来继承模板
p 使用block来自定义模板里的内容
block append scripts
script(src="index.js")
编译后:
<doctype html> <html> <head> <title>Template Inheritance用法</title> <link rel="stylesheet" href="bootstrap.css"> <link rel="stylesheet" href="index.css"> </head> <body> <header> 所有页面的公共头部</header> <h1>模板继承的用法</h1> <p>使用extends来继承模板</p> <p>使用block来自定义模板里的内容</p> <script src="/index.js"></script> <script src="/bootstrap.js"></script> </body> </html>
7.内联script
我们有时也会在html页面内嵌一些JavaScript代码,在pug中也很简单
编译前:
doctype html
html
head
title 内联script
body
h1 需要在此页面中内联一些脚本
script.
console.log('只需要在script后面加上一个.符号')
编译后:
<doctype html> <html> <head> <title>内联script</title> </head> <body> <h1>需要在此页面中内联一些脚本</h1> <script> console.log('只需要在script后面加上一个.符号') </script> </body> </html>
结语:
以上基本涵盖了pug的95%内容,还剩下一点少用的没有一一赘述,比如过滤器(filters)和注释(comments)等,markdown过滤器是个好东西,不过我觉得一般就个人项目,比如博客这样的会用上。
这些东西也足够你在项目中使用了,对于剩下的那5%,大家可以自己去看看官网,了解一下,都挺简单pug.js。
另外在我使用的时候,发现pug的写法除了缩进以外,也可以按照标准的html书写格式来创建模板,插值什么的,通过#{}方式同样好使。
不过在官网上没看见可以使用这种方式创建模板的说明,这是第一次使用pug(jade),所以不知道会不会是兼容以前的版本,有知道的朋友麻烦告诉我一声,谢谢哈!