如何從零構建個人部落格系統
簡介
這篇文章主要分享部落格裡涉及的Ruby, Rails,前端CSS,JS,ubuntu系統命令等知識。如果有什麼不解的地方可以通過http://liuzhen.me頁面下方的二維碼掃描加我微信。
-
Ruby是一種純粹的物件導向程式語言。它由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)建立於1993年。
-
Ruby on Rails(官方簡稱為Rails,亦被簡稱為RoR),是一個使用Ruby語言寫的開源Web應用框架,它是嚴格按照MVC結構開發的。它努力使自身保持簡單,來使實際的應用開發時的程式碼更少,使用最少的配置。指南: https://ruby-china.github.io/rails-guides/
- CSS 指層疊樣式表, 你在頁面看到的展示效果都是通過CSS做出來的,頁面的佈局,字型大小,顏色,邊框,選單等等. 詳情可以檢視: http://www.runoob.com/css/css-intro.html
- JS 是屬於網路的指令碼語言, 能做的事太多了,像我部落格裡的相簿功能,時間線都是JS做出來的效果。
安裝Rails環境
你可以通過搜尋 Mac/windows/ubuntu install rails
來找到相關文件,這裡提供ubuntu 16.04版本的安裝文件: https://gorails.com/setup/ubuntu/16.04 , Mac的安裝文件: https://ruby-china.org/wiki/mac-nginx-passenger-rails
建立一個Rails專案
安裝好Rails環境之後,你可以建立一個Rails專案了,如果你從來沒用過Rails,可以先用15分鐘學習一下 Rails入門, 瞭解Rails MVC結構。
如果你對Rails有一定的瞭解,可以按照這個模版 https://github.com/80percent/rails-template 提供的操作步驟, 建立一個Rails專案,使用這個模版建立Rails專案的好處是,這個模版相當於一個全家桶,預先新增一個專案經常需要使用的Gem包,釋出需要的puma, mina, monit, nginx配置檔案,關於這幾個東西是什麼,有什麼用後面會講到。
啟動Rails
$ rails s
訪問 localhost:3000
就能看到 hello world 頁面了。
建立資料模型
我的部落格在設計之初只想要文章,相簿,簡歷這幾個功能,這三個功能比較相似,都有標題,內容和可有可無的描述。所以我就用了單表繼承,建了個base表。
$ rails g model Base title:string content:text subtitle:string type:string
type欄位就是用於單表繼承。
執行完這條命令之後,你會看到 db/migrate/xxxx_create_bases.rb
多了一個這樣的檔案,裡面的內容是:
class CreateBases < ActiveRecord::Migration[5.1]
def change
create_table :bases do |t|
t.string :title
t.string :subtitle
t.text :content
t.string :type
t.timestamps
end
end
end
t.timestamps 是時間戳,系統會自動在這個表裡面加上 created_at
, updated_at
兩個欄位。
新增完之後,需要把做一下資料遷移,我一開始學rails的時候對 資料遷移
這個詞很不理解。其實資料遷移的意思就是,我們現在通過命令建立了個資料表的檔案,但是這個檔案沒有被執行,不執行資料庫裡就還沒有這張表,只有在執行了 rails db:migrate
之後,rails才在資料庫裡把這張表給加上,這個操作就叫做 資料遷移。
建立完了Base表,現在就要建立文章表了 Article, 我們需要新增一個 app/models/article.rb
檔案,寫上:
class Article < Base
end
因為Article繼承了Base, 所以就擁有了Base的所有欄位了。
你可以通過 rails c
從控制檯輸入 Article.new
可以看到:
irb(main):006:0* Article.new
=> #<Article id: nil, title: nil, subtitle: nil, content: nil, type: "Article", created_at: nil, updated_at: nil>
type欄位自動就是Article, 這是Rails的一個特性,單表繼承。
輸入Article.all
, 看到的sql語句實際是從bases裡查詢type為Article的所以記錄。
irb(main):007:0> Article.all
Article Load (127.0ms) SELECT "bases".* FROM "bases" WHERE "bases"."type" IN ('Article') LIMIT $1 [["LIMIT", 11]]
相簿表Photo
,簡歷表Resume
和Article
的建立方式相同.
表建立好了,我們就可以建立Controller
了,Controller
需要區分前端和後端,前端就是提供給使用者查詢的,後臺是提供自己新增,更新,刪除操作的。另外後臺因為是管理的地方所以不能讓所有人都訪問,所以需要設定成通過使用者名稱和密碼登入。這樣別人就無法訪問你的後臺。
後端設計
為了與前臺有所區分,所以需要加一下名稱空間: 這裡設定成 admin
. 先在 config/routes.rb
裡新增路由,
Rails.application.routes.draw do
namespace :admin do
root 'dashboard#index', as: 'root'
resources :articles
resources :photos
resource :resume, only: [:edit, :update]
end
end
root 'dashboard#index', as: 'root'
設定後臺的root
路由。使用 rails routes
命令可以檢視具體的路由資訊。
控制器
controllers
目錄下新增admin
目錄,這個目錄下用於存放所有的後臺檔案,後臺新增一個 app/controllers/admin/base_controller.rb
檔案,繼承了 ApplicationController
, 這麼做是為了admin
下的所有controller
繼承 Admin::BaseController
後,使用者訪問後端連結就會先校驗當前使用者是否登入,如果沒有登入就跳轉到登入頁面。
程式碼如下:
class Admin::BaseController < ApplicationController
layout 'admin'
before_action :authenticate_user
def authenticate_user
unless session[:login]
redirect_to new_session_path
end
end
end
因為article
, photo
, resume
這幾個功能比較相似,所以我只講一下article
控制器:app/controllers/admin/articles_controller.rb
程式碼:
class Admin::ArticlesController < Admin::BaseController
def index
@articles = Article.all.order(created_at: 'DESC').page(params[:page])
end
def new
@article = Article.new
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to admin_articles_path
else
render 'new'
end
end
def edit
@article = Article.find(params[:id])
end
def update
@article = Article.find(params[:id])
if @article.update(article_params)
flash[:notice] = '更新成功'
redirect_to admin_articles_path
else
render 'edit'
end
end
def destroy
@article = Article.find(params[:id])
if @article.destroy
flash[:notice] = '刪除成功'
else
flash[:notice] = "刪除失敗, 原因: #{@article.errors.messages.to_s}"
end
end
private
def article_params
params.require(:article).permit(:title, :subtitle, :content)
end
end
控制檯裡面很簡單,就是增,刪,改,查。需要注意的就是redirect_to
, render
的區別,什麼時候要用render
, 什麼時候用redirect_to
.
render
是指直接薰染某個頁面.
redirect_to
是指告訴瀏覽器,讓瀏覽器再重新傳送一個指定路由的請求操作。
如:create action
裡寫到如果儲存成功就 redirect_to admin_articles_path
, 如果失敗就 render 'new'
.
-
假如儲存成功,就會告訴瀏覽器, 讓瀏覽器再向伺服器傳送一個
admin/articles
路由請求,然後進入index action
裡,查詢所有Action
記錄,再薰染index.html
頁面,返回給瀏覽器。 - 假如儲存失敗,就用使用者填寫的@article資訊薰染
new.html
頁面,並用flash裡的資訊,告訴使用者提交失敗的原因,如果失敗後用redirect_to new_admin_articles_path
,也能跳轉到new
頁面,但是使用者提交的資訊就沒有了。
view
.row
.offset-md-2.col-md-8
= simple_form_for [:admin, @article] do |f|
= f.error_notification
= f.input :title
= f.input :subtitle
= f.text_area :content, id: 'editor_content', class: 'simditor', autofocus: true
= f.submit '提交', class: 'btn btn-primary'
= link_to '取消', admin_articles_path
javascript:
new Simditor({
textarea: $('#editor_content'),
toolbar: ['title', 'bold', 'italic', 'underline', 'strikethrough', 'fontScale', 'color', '|', 'ol', 'ul', '|', 'blockquote', 'code', 'table', 'link', 'image', 'hr', 'indent', 'outdent', 'alignment']
});
這個有點需要講的是編輯器使用了simditor
外掛,具體要加哪些資訊可以看一下這個文件: http://simditor.tower.im/, 但是要支援上傳圖片功能需要在admin下新增一條路由: post '/upload', to: 'photos#upload'
, 在photos controller
裡新增一個upload action
,把上傳的圖片儲存到資料庫。
前端設計
前端的controller
繼承ApplicationController
,前端的因為只設計到查詢,所以新增路由的時候加上only
, 如: resources :articles, only: [:index, :show]
, 就只新增兩條路由,如果不加only
預設會建立 7 條路由。
前端功能主要就涉及到css.
css除錯步驟:
- 右擊選擇'檢查',就能開啟控制檯,在控制檯處,通過點選(2) 處的圖示,可以選擇頁面上任意節點,選擇後(3)處會顯示這個節點所對應的CSS樣式。同樣在style處可以通過新增和註釋css來對頁面樣式進行除錯。
樣式這裡涉及的東西太多,我不一一講解,只講一些我認為值得講一講的知識點。如果想學習更多的css樣式知識,可以在文章開頭處提供的文件檢視學習。
-
文章的展示對字型,間距,背景,顏色等等都要求很高,如果設計的不好,文章看久了就容易累,而且容易給別人一種不想去看的感覺。如果間距很窄,一大段落全是文字,就給人一種很不舒服的感覺。如果你對這些資訊瞭解不多,不知道把這些值設定成多少比較好,也不要擔心,找一個你覺得文字展示效果看起來很舒服的網站,開啟他的控制檯,看一下這個網站上這些資訊設定的值是多少,跟著一樣設定就行了。具體的細節可以再另做調整。
- 部落格的頁面底部用的fa字型,在
gemfile
裡新增font-awesome-sass
後,就能展示出這些字型圖示。但是目前的字型中沒有支付寶的字型圖示,你先不要看程式碼,想一想,如果是你,你要怎麼實現一個跟fa字型相同效果的圖示,這個圖示帶有hover效果,當滑鼠放上去的時候背景變成了藍色。
我的實現方法:
一開始我想的是用一個黑白圖片代替,弄完之後我發現hover效果無法實現。於是我就用一個背景透明只有一個支字的圖片代替,設定border-radius,background-color和字型達成一致效果,當滑鼠放上去的時候就改變background-color: #0085A1;
程式碼:
footer .fa-alipay {
border-radius: 50%;
margin-bottom: 4px;
background-color: #222529;
width: 41px;
}
footer .fa-alipay:hover {
background-color: #0085A1;
}
除錯頁面上關於hover
,visited
, focus
, active
效果,可以像圖片中勾選來檢視相應的樣式效果。
時間線
時間線是用的一個js庫,https://github.com/RyanFitzgerald/vertical-timeline, 具體可以檢視文件。值得說一下的是,一開始看到這個時間線的效果是在一個網站看到的。然後我通過頁面控制檯,看到裡面class名稱命名很規範,所以感覺是個js庫,直接在google搜尋 cd-timeline-block
第一個結果就是這個庫的資訊。除了這種方式,還可以通過控制檯的Sources
檢視assets
檔案資訊,一般都是經常壓縮的,但是有些外部庫是有註釋的,會寫上這個是來自哪個庫之類的資訊。不過最簡單快速的辦法還是用google搜尋來的快一點。如果你搜的class名字沒有找到相應的資訊,可以換個class名字試試。
另外一個要說的是,這個JS庫裡的一個js檔案main.js
, 與turbolink一起載入,沒生效,載入的時候就沒被執行,然後我就把它用$(document).on 'turbolinks:load'
, 載入就好了。
相簿
部落格裡我最喜歡的就是這個相簿功能了,當初也是看了這個翻書的效果,我才有重寫部落格的衝動。看到這個js庫是在github Trending
上, 這上面會推薦github上比較火的專案。這個庫的地址: http://www.turnjs.com, 這裡面提供了幾個demo. 這個turnjs用的 yepnope
載入js,這麼載入是因為,有些內容需要在其他檔案載入之後去執行。但是有個問題是在生產環境這些js檔案都是被轉譯了的。所以直接在yepnope
裡面寫上檔名,在生產環境上就會找不到對應的檔案。對於這個我沒有想到特別好的處理辦法,就用
$('head').append('<%= javascript_include_tag 'turn.min.js' %>')
來載入檔案,然後再執行yepnope({complete: loadApp})
。如果你有更好的辦法可以交流一下。
其他知識點
-
效果支援手機端頁面需要加上:
meta width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no
-
前端和後端的JS, CSS儘量分開,這樣載入速度會快一些
- 使用的外部庫最好重新命名成可讀名稱, 不然時間長了你就不知道這個庫是幹什麼的了. 比如我用了 timeline 的JS庫, 裡面有個main.js的檔案, 我就把它重新命名為 timeline-main.js, 這樣不需要再加註釋來說明這個檔案是做什麼的了.
釋出
釋出需要在伺服器上安裝好rails後,配置nginx.conf
,一般放在/etc/nginx/conf.d/xxx.conf
檔案.
puma.rb
,deploy.rb
配置檔案是mina部署的相關配置資訊,具體操作了什麼可以通過bundle exec mina deploy -v
來檢視:
$ bundle exec mina deploy -v
-----> Creating a temporary build path
-----> Server: liuzhen.me
-----> Path: /home/ruby/RBlog
$ echo "-----> Branch: master"
-----> Branch: master
-----> Using RVM environment "2.3.1"
-----> Quiet sidekiq (stop accepting new work)
-----> Fetching new git commits
$ (cd "/home/ruby/RBlog/scm" && git fetch "https://github.com/liuzhenangel/RBlog.git" "master:master" --force)
-----> Using git branch 'master'
$ git clone "/home/ruby/RBlog/scm" . --recursive --branch "master"
Cloning into '.'...
done.
-----> Using this git commit
$ git rev-parse HEAD > .mina_git_revision
$ git --no-pager log --format="%aN (%h):%n> %s" -n 1
liuzhenangel (eb06b54):
> update timeline
$ rm -rf .git
-----> Symlinking shared paths
-----> Installing gem dependencies using Bundler
$ bundle install --without development test --path "vendor/bundle" --deployment
-----> DB migrations unchanged; skipping DB migration
-----> Skipping asset precompilation
-----> Cleaning up old releases (keeping 5)
-----> Deploy finished
-----> Building
-----> Moving build to /home/ruby/RBlog/releases/41
-----> Build finished
-----> Launching
-----> Updating the /home/ruby/RBlog/current symlink
-----> Restart Puma -- hard...
-----> Stopping Puma...
-----> Starting Puma...
從這些日誌資訊可以看出, 首先會根據你配置的伺服器的域名和使用者名稱ssh到伺服器上,載入ruby環境,從github拉取最新程式碼,安裝gem包,如果css, js, 圖片有更新就重新編譯壓縮js, css, 圖片, 執行 db:migrate
資料遷移, 首次釋出還會執行rails db:create
來建立資料庫。然後重啟puma.
為什麼要nginx,puma
nginx相當於一個代理,當你在瀏覽器輸入:http://liuzhen.me
的時候,先通過DNS找到這個域名對應的IP,然後通過路由到達IP所在的伺服器上,伺服器發現使用者請求的是 liuzhen.me,然後nginx就根據配置檔案裡配置的 liuzhen.me 找到對應的專案,這個Rails專案是由puma啟動的,然後nginx就把這個事交給puma, puma收到後就根據路由去到對應的controller,然後返回對應的頁面給到瀏覽器。
monit 是什麼
沒有monit也能釋出成功,但是有時候你的puma可能異常關掉了,如果有monit的話,就能時刻監聽這個程式是不是啟動狀態,一旦關閉了,就重新啟動。
部落格地址: http://liuzhen.me
相關文章
- React構建個人部落格React
- Spring Boot 2.1.3+Bootstrap 4.0 構建個人部落格系統Spring Boot
- 從零開始的個人技術部落格
- 個人部落格如何搭建 用什麼系統好?學網站建設從開發一個部落格開始網站
- 如何從零構建直播系統(後端篇)後端
- 晴楓個人部落格系統
- 用 Hugo 和 Github Pages 構建個人部落格GoGithub
- 【轉載】Hexo+GitHub構建個人部落格HexoGithub
- 從零搭建基於golang的個人部落格網站Golang網站
- 程式小生的個人部落格系統
- 記一次 React + Koa + Mysql 構建個人部落格ReactMySql
- Qing部落格系統,基於Vue2套件,axios, ElementUI, KOA構建的部落格系統!Vue套件iOSUI
- 基於TP3.1個人部落格系統
- ModStartBlog 現代化個人部落格系統
- 3種個人部落格系統吐血推薦
- 免費 ,免費開源 ,ThinkPHP 部落格後臺管理系統5.0開發的個人部落格 程式開源共享.個人部落格系統,老張部落格-Boot.ZPHPboot
- Flutter 零成本搭建個人小部落格Flutter
- 基於ThinkPHP搭建的仿Wordpres個人部落格系統PHP
- Koa+Vue 實現仿GitHub風格的個人部落格系統VueGithub
- 如何搭建個人獨立部落格網站?網站
- 從零開始在GitHub上部署個人部落格——寫給大家看的教程Github
- IYCMS部落格系統
- 個人部落格程式
- 個人部落格分享
- 個人部落格地址
- 個人技術部落格
- 個人技術部落格(α)
- 搭建個人部落格
- 從零開始搭建一個 hexo 部落格。Hexo
- VuePress從零開始搭建自己的部落格Vue
- 從0到1搭建和部署個人部落格
- 教你如何搭建一個自動化構建的部落格
- 基於 Laravel5.5 的簡單個人部落格系統Laravel
- 部署在GitHub的個人部落格如何繫結個人域名Github
- JavaWeb——從零開始構建一個客戶管理系統(一)JavaWeb
- ThinkLog部落格系統
- GXBlog部落格系統
- Go Markdown 部落格系統Go