基於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),所以不知道會不會是兼容以前的版本,有知道的朋友麻煩告訴我一聲,謝謝哈!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM