Drupal8: 20/30/40分钟搭建百家号/公众号/简书

作为一个十多年的Drupal用户,在接触百家号/公众号/简书后,琢磨各家之长,改造了一下自己的网站,使其具有图文混排、所见即所得、封面图、水印、Markdown及语法高亮等功能。

本文讲述搭建过程:先用脚本全自动安装/设置一个基本的Drupal8站点;再手动地稍加配置,使其具有百家号的效果;进一步地配置,达到公众号和简书的效果。

广告:本文高度浓缩。全自动安装LAMP/LEMP及Drupal,未见有人做到这么完整。再加上百家号/公众号/简书效果,以及响应式网页,其实可以作为几篇文章。考虑到看官时间宝贵,我就长话短说多合一了。

image.png

准备工作

本文在Debian系的Linux(Debian9/8,Ubuntu17)上测试通过。对Redhat系的(比如CentOS),要对apt包(用yum)稍加改造。

先准备一个干净的系统:只需要基本系统、SSH Server。GUI不是必须的。

安装sudo,并把自己加入sudo组。(Ubuntu上不需要这一步,安装时创建的账号默认就可以sudo)

su
apt-get install sudo
adduser your-login sudo

可以在虚拟机上做这个实验,进行简单的个人设置后,建一个快照(便于回滚),开始运行脚本。

image.png

顺便说一句,如果用虚拟机,最好用桥接(Bridge)模式,这样和主机(Host)在同一个网段。

10分钟:基本系统,全自动脚本

你可以一边阅读本章,一边运行本文最后的脚本。用自己的账号运行,脚本在需要sudo的时候,会问你密码。因为sudo会话默认超时是15分钟,所以最多要输入两次密码(注1)。

默认安装basic版,我花了大约7分钟。如果你用国内镜像,应该会更快。advanced版(主要是支持Markdown)多装了几个模块,那几个模块比较花时间,总共大约15分钟。

image.png

下面对脚本做一简单的说明。

先安装MySQL, Nginx, PHP。我用轻量级的nginx搭配php-fpm(没用apache搭配php)。为了适应各系统,尽量不指定版本号。Debian9上的MySQL已经默认使用MariaDB了,而且安装时不需要设置root密码了。这对自动安装是极好的,sudo mysql 就可以以root登录MySQL了。Debian8/Ubuntu17上则需要设置一个环境变量,才能达到同样的效果。

接下来,安装composer,PHP的包管理工具;drush,Drupal的命令行工具,让安装配置自动化的神器。

软件装好后,建一个空的数据库,给Drupal用。顺便把相应的账号密码写入自己的~/.my.cnf,便于无密码使用mysql命令行。

为了全自动,我们直接从nginx网站下载Drupal的配置。怎么从网页中抓取特定的内容,严谨的做法还是有点小麻烦的,我就简单粗暴,直接用perl -pe去除所有html tag,得到文本,然后grep -A定位和抓取配置文件内容,最后用perl和sed做一点修改。

最后用drush安装站点,composer安装需要的PHP模块,再用drush创建用户,安装/配置模块、主题。Drupal8还要求把域名加入到信任站点的列表里,否则会有警告。脚本同时也修改了这方面的配置:加入了一个域名,一个服务器的IP地址。

关于权限,养成好习惯,不要全程root:安装系统软件,修改系统配置用sudo;安装Drupal, PHP模块,用自己的账号;Drupal的modules, themes, sites/default 目录最后改为由Web server账号(www-data)所有,这样以后可以通过浏览器/网页安装/缷载Drupal模块/主题。sites/default如果不改为www-data所有,网页安装时会要使用FTP方式,那就麻烦点。

注1:每次运行composer命令(install或require)后,再运行sudo,会要求输入密码。这样,不管sudo会话的超时有多长,这个脚本至少会要两次sudo的密码。这是遗憾的地方。

网站管理员和普通用户的账号/密码都在脚本里;安装脚本成功结束后会提示网站入口地址。

先用管理员登录。下图是管理界面之一:系统状态。

image.png

下图是用户权限管理。顺便设置权限让注册用户可以创建/修改“文章”(Article)这一类型。顺便说一句:如果enable revision,网站立马就可以变成WiKi类型的站点。

image.png

20分钟:百家号,封面图

安装完成后就有了一个所见即所得的编辑器CKEditor,可以实现图文混排的编辑,和百家号的编辑界面相当。

image.png

百家号可以指定3张图作为封面,而公众号/简书是默认使用文中的第一张图。

为实现百家号的效果,增加一个字段,叫作"Cover”。这个字段可以设置为允许3个值,就是3张图,和百家号类似。

image.png

然后设置这个字段只在摘要页面(Teaser)显示,在默认页面中隐藏(Disabled),这样,这个封面图就会只显示在首页中,不会显示在正文中。这样就实现了百家号的效果。

image.png

30分钟:公众号,水印

公众号/订阅号可以自动给图片加水印,而百家号和简书没这个功能。

在Drupal8中,可以通过模块 Image effects 来实现水印的效果。

Drupal8用“样式”(Style)来处理/生成图片缓存。一种样式其实就是对原图的一种/一组处理,最常见的是缩放。Drupal8自带3种样式:大、中、小(缩略图)。

我们直接在自带的 Large 样式里加入水印这种处理。

image.png

水印可以设置:位置,大小,透明度等等。

image.png

这样,对上传的图片,显示的是自动缩小(至800x800以内)并带水印的图。另外,“水印”本身修改后,也不用重新处理/上传每一张图,因为原图在服务器上,可以重新合成。

40分钟:简书,Markdown

简书支持两种编辑格式,通常的所见即所得和Markdown。

Drupal里的“格式”也可以做到同样的事,一种格式(Text format)就是对文本的一组处理/转换。

新建一种格式,名字叫“Markdown”,其中包括 markdown,语法高亮、自动生成目录。

image.png

使用Markdown,就意味使用纯文本编辑器,所以不能用CKEditor上传图片了。于是我们回归原始的Image字段:

  1. 这个字段是多值的,所以可以上传任意多张图片;
  2. 这个字段不直接显示在文章中,要在显示中要设置为”Disabled”(图在“百家号”那一节);
  3. 这样,图片可以插入在文章的任何位置,和上载的顺序无关。

为了帮助在文章里插入图片的链接,使用了Insert模块。界面如下图所示:

image.png

不足和长处

不足:

  1. 不支持图片的剪贴板操作。百家号/公众号/简书支持直接粘贴剪贴板内的图片,自动上载。
  2. 不支持拖放。简书是可以支持拖放上载的(百家号看上去也有,但在Chrome里测试未成功)。
  3. 目前的选图/插入略感麻烦。简书的Markdown的同屏编辑/预览是极好的,在Drupal里用简单的模块组合做不出来。

总之,简书的编辑界面是我见过的最好的。

长处:

  1. 支持自动生成文章目录。在文章中插入 “[ toc ]” 就会变成目录。
  2. 支持响应式(Responsive )页面。随着窗口大小不同,设备不同,界面呈现为不同的布局。这个功能得益于Drupal的主题。Drupal8自带的主题 Bartik 与时俱进,其实已经不错了。当然,还有不少第三方主题都是响应式的。
  3. 有大量的第三方模块/主题。做一个快乐的伸手党,就能很容易地实现一些功能和效果。

响应式效果简介:

  • 下图是在手机上显示的网站首页——自动变成了单列模式,并隐藏了菜单;
  • 在PC上,则显示为如本文第1图的双列模式;如果窗口变窄,也会变为单列模式;
  • 在iPad上,旋转屏幕,也可以看到这种效果的变化。

欢迎访问我的网站,直接体验。

image.png

下图是PC上和手机上的文章目录效果。对于长文章,有目录还是方便一些。

image.png

附:自动安装脚本

请用具有sudo权限的普通用户直接运行此脚本,不要以sudo方式运行,也不要用root账号运行。

脚本在以下系统测试通过:

  • Debian 9.0(无GUI);
  • Debian 8.8(有GUI);
  • Ubuntu 17.04(有GUI)。

脚本可以多次运行。比如安装好后,再运行脚本,会清除掉数据库重装;但系统软件(如果没有升级版)不会再重装。

#!/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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容