作為一個(gè)十多年的Drupal用戶箍铭,在接觸百家號/公眾號/簡書后斯辰,琢磨各家之長,改造了一下自己的網(wǎng)站坡疼,使其具有圖文混排、所見即所得衣陶、封面圖柄瑰、水印、Markdown及語法高亮等功能剪况。
本文講述搭建過程:先用腳本全自動安裝/設(shè)置一個(gè)基本的Drupal8站點(diǎn)教沾;再手動地稍加配置,使其具有百家號的效果译断;進(jìn)一步地配置授翻,達(dá)到公眾號和簡書的效果。
廣告:本文高度濃縮孙咪。全自動安裝LAMP/LEMP及Drupal堪唐,未見有人做到這么完整。再加上百家號/公眾號/簡書效果翎蹈,以及響應(yīng)式網(wǎng)頁淮菠,其實(shí)可以作為幾篇文章』缈埃考慮到看官時(shí)間寶貴合陵,我就長話短說多合一了。
準(zhǔn)備工作
本文在Debian系的Linux(Debian9/8澄阳,Ubuntu17)上測試通過拥知。對Redhat系的(比如CentOS),要對apt包(用yum)稍加改造碎赢。
先準(zhǔn)備一個(gè)干凈的系統(tǒng):只需要基本系統(tǒng)低剔、SSH Server。GUI不是必須的揩抡。
安裝sudo户侥,并把自己加入sudo組镀琉。(Ubuntu上不需要這一步,安裝時(shí)創(chuàng)建的賬號默認(rèn)就可以sudo)
su
apt-get install sudo
adduser your-login sudo
可以在虛擬機(jī)上做這個(gè)實(shí)驗(yàn)蕊唐,進(jìn)行簡單的個(gè)人設(shè)置后屋摔,建一個(gè)快照(便于回滾),開始運(yùn)行腳本替梨。
順便說一句钓试,如果用虛擬機(jī),最好用橋接(Bridge)模式副瀑,這樣和主機(jī)(Host)在同一個(gè)網(wǎng)段弓熏。
10分鐘:基本系統(tǒng),全自動腳本
你可以一邊閱讀本章糠睡,一邊運(yùn)行本文最后的腳本挽鞠。用自己的賬號運(yùn)行,腳本在需要sudo的時(shí)候狈孔,會問你密碼信认。因?yàn)閟udo會話默認(rèn)超時(shí)是15分鐘,所以最多要輸入兩次密碼(注1)均抽。
默認(rèn)安裝basic版嫁赏,我花了大約7分鐘。如果你用國內(nèi)鏡像油挥,應(yīng)該會更快潦蝇。advanced版(主要是支持Markdown)多裝了幾個(gè)模塊,那幾個(gè)模塊比較花時(shí)間深寥,總共大約15分鐘攘乒。
下面對腳本做一簡單的說明。
先安裝MySQL, Nginx, PHP惋鹅。我用輕量級的nginx搭配php-fpm(沒用apache搭配php)持灰。為了適應(yīng)各系統(tǒng),盡量不指定版本號负饲。Debian9上的MySQL已經(jīng)默認(rèn)使用MariaDB了堤魁,而且安裝時(shí)不需要設(shè)置root密碼了。這對自動安裝是極好的返十,sudo mysql 就可以以root登錄MySQL了妥泉。Debian8/Ubuntu17上則需要設(shè)置一個(gè)環(huán)境變量,才能達(dá)到同樣的效果洞坑。
接下來盲链,安裝composer,PHP的包管理工具;drush刽沾,Drupal的命令行工具本慕,讓安裝配置自動化的神器。
軟件裝好后侧漓,建一個(gè)空的數(shù)據(jù)庫锅尘,給Drupal用。順便把相應(yīng)的賬號密碼寫入自己的~/.my.cnf布蔗,便于無密碼使用mysql命令行藤违。
為了全自動,我們直接從nginx網(wǎng)站下載Drupal的配置纵揍。怎么從網(wǎng)頁中抓取特定的內(nèi)容顿乒,嚴(yán)謹(jǐn)?shù)淖龇ㄟ€是有點(diǎn)小麻煩的,我就簡單粗暴泽谨,直接用perl -pe去除所有html tag璧榄,得到文本,然后grep -A定位和抓取配置文件內(nèi)容吧雹,最后用perl和sed做一點(diǎn)修改犹菱。
最后用drush安裝站點(diǎn),composer安裝需要的PHP模塊吮炕,再用drush創(chuàng)建用戶,安裝/配置模塊访得、主題龙亲。Drupal8還要求把域名加入到信任站點(diǎn)的列表里,否則會有警告悍抑。腳本同時(shí)也修改了這方面的配置:加入了一個(gè)域名鳄炉,一個(gè)服務(wù)器的IP地址。
關(guān)于權(quán)限搜骡,養(yǎng)成好習(xí)慣拂盯,不要全程root:安裝系統(tǒng)軟件,修改系統(tǒng)配置用sudo记靡;安裝Drupal, PHP模塊谈竿,用自己的賬號;Drupal的modules, themes, sites/default 目錄最后改為由Web server賬號(www-data)所有摸吠,這樣以后可以通過瀏覽器/網(wǎng)頁安裝/缷載Drupal模塊/主題空凸。sites/default如果不改為www-data所有,網(wǎng)頁安裝時(shí)會要使用FTP方式寸痢,那就麻煩點(diǎn)呀洲。
注1:每次運(yùn)行composer命令(install或require)后,再運(yùn)行sudo,會要求輸入密碼道逗。這樣兵罢,不管sudo會話的超時(shí)有多長,這個(gè)腳本至少會要兩次sudo的密碼滓窍。這是遺憾的地方卖词。
網(wǎng)站管理員和普通用戶的賬號/密碼都在腳本里;安裝腳本成功結(jié)束后會提示網(wǎng)站入口地址贰您。
先用管理員登錄坏平。下圖是管理界面之一:系統(tǒng)狀態(tài)。
下圖是用戶權(quán)限管理锦亦。順便設(shè)置權(quán)限讓注冊用戶可以創(chuàng)建/修改“文章”(Article)這一類型舶替。順便說一句:如果enable revision,網(wǎng)站立馬就可以變成WiKi類型的站點(diǎn)杠园。
20分鐘:百家號顾瞪,封面圖
安裝完成后就有了一個(gè)所見即所得的編輯器CKEditor,可以實(shí)現(xiàn)圖文混排的編輯抛蚁,和百家號的編輯界面相當(dāng)陈醒。
百家號可以指定3張圖作為封面,而公眾號/簡書是默認(rèn)使用文中的第一張圖瞧甩。
為實(shí)現(xiàn)百家號的效果钉跷,增加一個(gè)字段,叫作"Cover”肚逸。這個(gè)字段可以設(shè)置為允許3個(gè)值爷辙,就是3張圖,和百家號類似朦促。
然后設(shè)置這個(gè)字段只在摘要頁面(Teaser)顯示膝晾,在默認(rèn)頁面中隱藏(Disabled),這樣务冕,這個(gè)封面圖就會只顯示在首頁中血当,不會顯示在正文中。這樣就實(shí)現(xiàn)了百家號的效果禀忆。
30分鐘:公眾號臊旭,水印
公眾號/訂閱號可以自動給圖片加水印,而百家號和簡書沒這個(gè)功能箩退。
在Drupal8中巍扛,可以通過模塊 Image effects 來實(shí)現(xiàn)水印的效果。
Drupal8用“樣式”(Style)來處理/生成圖片緩存乏德。一種樣式其實(shí)就是對原圖的一種/一組處理撤奸,最常見的是縮放吠昭。Drupal8自帶3種樣式:大、中胧瓜、惺概铩(縮略圖)。
我們直接在自帶的 Large 樣式里加入水印這種處理府喳。
水印可以設(shè)置:位置蒲肋,大小,透明度等等钝满。
這樣兜粘,對上傳的圖片,顯示的是自動縮型溲痢(至800x800以內(nèi))并帶水印的圖孔轴。另外,“水印”本身修改后碎捺,也不用重新處理/上傳每一張圖路鹰,因?yàn)樵瓐D在服務(wù)器上,可以重新合成收厨。
40分鐘:簡書晋柱,Markdown
簡書支持兩種編輯格式,通常的所見即所得和Markdown诵叁。
Drupal里的“格式”也可以做到同樣的事雁竞,一種格式(Text format)就是對文本的一組處理/轉(zhuǎn)換。
新建一種格式拧额,名字叫“Markdown”碑诉,其中包括 markdown,語法高亮势腮、自動生成目錄。
使用Markdown漫仆,就意味使用純文本編輯器捎拯,所以不能用CKEditor上傳圖片了。于是我們回歸原始的Image字段:
- 這個(gè)字段是多值的盲厌,所以可以上傳任意多張圖片署照;
- 這個(gè)字段不直接顯示在文章中,要在顯示中要設(shè)置為”Disabled”(圖在“百家號”那一節(jié))吗浩;
- 這樣建芙,圖片可以插入在文章的任何位置,和上載的順序無關(guān)懂扼。
為了幫助在文章里插入圖片的鏈接禁荸,使用了Insert模塊右蒲。界面如下圖所示:
不足和長處
不足:
- 不支持圖片的剪貼板操作。百家號/公眾號/簡書支持直接粘貼剪貼板內(nèi)的圖片赶熟,自動上載瑰妄。
- 不支持拖放。簡書是可以支持拖放上載的(百家號看上去也有映砖,但在Chrome里測試未成功)间坐。
- 目前的選圖/插入略感麻煩。簡書的Markdown的同屏編輯/預(yù)覽是極好的邑退,在Drupal里用簡單的模塊組合做不出來竹宋。
總之,簡書的編輯界面是我見過的最好的地技。
長處:
- 支持自動生成文章目錄蜈七。在文章中插入 “[ toc ]” 就會變成目錄。
- 支持響應(yīng)式(Responsive )頁面乓土。隨著窗口大小不同宪潮,設(shè)備不同,界面呈現(xiàn)為不同的布局趣苏。這個(gè)功能得益于Drupal的主題狡相。Drupal8自帶的主題 Bartik 與時(shí)俱進(jìn),其實(shí)已經(jīng)不錯(cuò)了食磕。當(dāng)然尽棕,還有不少第三方主題都是響應(yīng)式的。
- 有大量的第三方模塊/主題彬伦。做一個(gè)快樂的伸手黨滔悉,就能很容易地實(shí)現(xiàn)一些功能和效果。
響應(yīng)式效果簡介:
- 下圖是在手機(jī)上顯示的網(wǎng)站首頁——自動變成了單列模式单绑,并隱藏了菜單回官;
- 在PC上,則顯示為如本文第1圖的雙列模式搂橙;如果窗口變窄歉提,也會變?yōu)閱瘟心J剑?/li>
- 在iPad上,旋轉(zhuǎn)屏幕区转,也可以看到這種效果的變化苔巨。
歡迎訪問我的網(wǎng)站,直接體驗(yàn)废离。
下圖是PC上和手機(jī)上的文章目錄效果侄泽。對于長文章,有目錄還是方便一些蜻韭。
附:自動安裝腳本
請用具有sudo權(quán)限的普通用戶直接運(yùn)行此腳本悼尾,不要以sudo方式運(yùn)行柿扣,也不要用root賬號運(yùn)行。
腳本在以下系統(tǒng)測試通過:
- Debian 9.0(無GUI)诀豁;
- Debian 8.8(有GUI)窄刘;
- Ubuntu 17.04(有GUI)。
腳本可以多次運(yùn)行舷胜。比如安裝好后娩践,再運(yùn)行腳本,會清除掉數(shù)據(jù)庫重裝烹骨;但系統(tǒng)軟件(如果沒有升級版)不會再重裝翻伺。
#!/bin/bash
#Setup a Drupal8 site from scratch, including MySQL, Nginx, PHP, Drupal
#Tested on clean Debian9/8, Ubuntu17
#Updated: 6/27/2017, LobLab
set -e
PROFILE=$1
if [ -z "$PROFILE" ]; then
PROFILE=basic
#PROFILE=advanced
fi
DB_NAME=drupal8
DB_USER=drupal8
DB_PASS=JlTpr9wGryiN
SITE_NAME=LobLab
SITE_FQDN=loblab.myvnc.com
SITE_URL=http://$SITE_FQDN
ADMIN_NAME=admin
ADMIN_PASS=P2fOA9b6ctG
ADMIN_MAIL=admin@loblab.com
USER_NAME=demo
USER_PASS=dH9BbntT1Mq
USER_MAIL=demo@loblab.com
DRUPAL_DIR=/var/www/drupal8
DRUSH="drush -r $DRUPAL_DIR -l $SITE_URL -y"
function log_msg() {
echo $(date +'%m/%d %H:%M:%S') - $*
}
function install_system_packages() {
log_msg "Install system packages..."
codename=$(lsb_release -cs)
export DEBIAN_FRONTEND=noninteractive
sudo -E apt-get -y install mysql-server
sudo apt-get -y install mysql-client
sudo apt-get -y install nginx
if [ "$codename" == "jessie" ]; then
sudo apt-get -y install php5-fpm php5-mysql php5-gd
else
sudo apt-get -y install php-fpm php-mysql php-gd php-xml php-mbstring
fi
log_msg "Install system packages... done."
}
function install_php_composer() {
log_msg "Install PHP composer..."
# See https://getcomposer.org/download/
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '669656bab3166a7aff8a7506b8cb2d1c292f042046c5a994c43155c0be6190fa0355160742ab2e1c88d40d5be660b410') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
# See https://getcomposer.org/doc/00-intro.md#globally
sudo mv composer.phar /usr/local/bin/composer
log_msg "Install PHP composer... done."
}
function setup_database() {
log_msg "Setup database..."
sudo mysql -e "CREATE DATABASE IF NOT EXISTS $DB_NAME;"
sudo mysql -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASS' WITH GRANT OPTION;"
sudo mysql -e "FLUSH PRIVILEGES;"
echo "[client]" > ~/.my.cnf
echo "user=$DB_USER" >> ~/.my.cnf
echo "password=$DB_PASS" >> ~/.my.cnf
echo "socket=/var/run/mysqld/mysqld.sock" >> ~/.my.cnf
chmod 600 ~/.my.cnf
log_msg "Setup database... done."
}
function setup_nginx_drupal_config() {
log_msg "Donwload nginx config for drupal..."
cfgfile=/etc/nginx/sites-available/drupal8
wget -q -O - https://www.nginx.com/resources/wiki/start/topics/recipes/drupal/ |
perl -pe 's/<.+?>//g' |
grep "server {" -A 102 |
perl -mHTML::Entities -ne 'print HTML::Entities::decode_entities($_);' |
perl -pe "s/server_name .+?;/server_name _;/" |
sed '/location ~ \\..*\/.*\\.php$ {/i \ \ \ \ rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;' |
sudo tee $cfgfile
ps -A | grep php5 && php5=1 || php5=0
if [ $php5 -eq 1 ]; then
sudo perl -pe 's/#(fastcgi_pass.+php5.+fpm.sock;)/$1/' -i $cfgfile
sudo perl -pe 's/(fastcgi_pass.+php7.+fpm.sock;)/#$1/' -i $cfgfile
fi
cd /etc/nginx/sites-enabled
sudo ln -sf $cfgfile drupal8
sudo rm -f default
sudo service nginx restart
log_msg "Donwload nginx config for drupal... done."
}
function install_drush() {
log_msg "Install drush..."
php -r "readfile('http://files.drush.org/drush.phar');" > drush
chmod +x drush
sudo mv drush /usr/local/bin
drush -y init
log_msg "Install drush... done."
}
function install_drupal() {
log_msg "Install drupal..."
#https://www.drupal.org/documentation/install/developers
cd $(dirname $DRUPAL_DIR)
sudo chown -R $MY_ACCOUNT .
drush -y dl drupal --drupal-project-rename=$(basename $DRUPAL_DIR)
cd $DRUPAL_DIR
composer install
if [ "$PROFILE" == "advanced" ]; then
echo "Install PHP module: geshi/geshi..."
composer require geshi/geshi
echo "Install PHP module: michelf/php-markdown..."
composer require michelf/php-markdown
fi
drush -y site-install standard --db-url="mysql://$DB_USER:$DB_PASS@localhost/$DB_NAME" --site-name=$SITE_NAME --account-name="$ADMIN_NAME" --account-pass="$ADMIN_PASS" --account-mail="$ADMIN_MAIL"
host1=$(hostname -I | perl -pe 's/\./\\./g' | perl -pe 's/ //g')
host2=$(echo $SITE_FQDN | perl -pe 's/\./\\./g')
config="\$settings['trusted_host_patterns'] = array(
'^$host1$',
'^$host2$',
);
"
cfgfile=sites/default/settings.php
sudo chmod 644 $cfgfile
echo "$config" >> $cfgfile
sudo chmod 444 $cfgfile
sudo chown -R $WEB_ACCOUNT modules themes sites/default
log_msg "Install drupal... done."
}
function setup_drupal_users() {
log_msg "Create drupal users..."
drush user-create $USER_NAME --password="$USER_PASS" --mail="$USER_MAIL"
log_msg "Create drupal users... done."
}
function setup_drupal_modules() {
log_msg "Download & enable/disable drupal modules..."
sudo chown -R $MY_ACCOUNT modules
$DRUSH en smtp
$DRUSH en image_effects
$DRUSH en insert
$DRUSH en toc_api
$DRUSH en toc_filter
$DRUSH en captcha
$DRUSH en image_captcha
if [ "$PROFILE" == "advanced" ]; then
$DRUSH en geshifilter
$DRUSH en markdown
fi
sudo chown -R $WEB_ACCOUNT modules
log_msg "Download & enable/disable drupal modules... done."
}
function setup_drupal_themes() {
log_msg "Download & enable/disable drupal themes..."
sudo chown -R $MY_ACCOUNT themes
$DRUSH en adminimal_theme
sudo chown -R $WEB_ACCOUNT themes
$DRUSH config-set system.theme default bartik
$DRUSH config-set system.theme admin adminimal_theme
log_msg "Download & enable/disable drupal themes... done."
}
function main() {
install_system_packages
MY_ACCOUNT=$(id -un):$(id -gn)
WEB_ACCOUNT=$(ps -Ao user,group,cmd | grep nginx | grep worker | head -n 1 | awk '{printf "%s:%s\n", $1, $2}')
install_php_composer
install_drush
setup_database
setup_nginx_drupal_config
install_drupal
setup_drupal_users
setup_drupal_modules
setup_drupal_themes
$DRUSH cron
addr=$(hostname -I | sed 's/ //g')
log_msg "Succeeded. Please access http://$addr/"
}
main